设为首页 收藏本站
查看: 1173|回复: 0

[经验分享] Python标准模块logging

[复制链接]

尚未签到

发表于 2015-4-20 12:39:53 | 显示全部楼层 |阅读模式
  开发Python, 一直以来都是使用自己编写的logging模块. 比较土......
  今天发现python的标准模块的这个功能做的挺好, 记录一下, 以后使用模块来进行logging.
  对于这个模块的介绍网上也很多, 我也不用自己写了, 比较好的如下,
  http://crazier9527.iteye.com/blog/290018    Python的标准logging模块
  http://blog.endlesscode.com/2010/06/03/python-logging-module/   Python的logging模块
  http://docs.python.org/library/logging.html  官方文档
  下面就对于在项目中比较需要用到的部分摘录一些,
  简单的例子
  



1 import logging
2  import sys
3 logger = logging.getLogger("endlesscode")
4 formatter = logging.Formatter('%(name)-12s %(asctime)s %(levelname)-8s %(message)s', '%a, %d %b %Y %H:%M:%S',)
5 file_handler = logging.FileHandler("test.log")
6 file_handler.setFormatter(formatter)
7 stream_handler = logging.StreamHandler(sys.stderr)
8 logger.addHandler(file_handler)
9 logger.addHandler(stream_handler)
10  #logger.setLevel(logging.ERROR)
11  logger.error("fuckgfw")
12 logger.removeHandler(stream_handler)
13 logger.error("fuckgov")

  上面这段代码基本包含logging模块的基本feature
  GetLogger
  GetLogger() returns a reference to a logger instance with the  specified name if it is provided, or root if not. The names are  period-separated hierarchical structures. Multiple calls to getLogger()  with the same name will return a reference to the same logger object.
后面会看到这种以'.'分隔的hierarchical structures有什么用.
  Formatter
  Formatter对象定义了最终log信息的顺序,结构和内容, 后面会详细解释.
  Handler
  这儿用到了StreamHandler和FileHandler, 用于向不同的输出端打log.
  SetLevel
  Logging有如下级别: DEBUG,INFO,WARNING,ERROR,CRITICAL
  默认级别是WARNING, logging模块只会输出指定level以上的log
  这样的好处, 就是在项目开发时debug用的log, 在产品release阶段不用一一注释, 只需要调整logger的级别就可以了, 很方便的.
  Formatter  
  Formatter对象定义了最终log信息的顺序,结构和内容.于基本的logging.Handler类不同,应用可以直接实例化 formatter类,当然,如果需要你也可以子例化formatter以便定制它的一些行为.构造函数接受两个可选参数:一个信息格式字符串和一个日期 格式字符串.如果没有信息格式字符串,直接输出log信息.如果没有日期格式字符串,默认的格式是:%Y-%m-%d %H:%M:%S
  上面的代码给出了Formatter的例子, 下面表格给出所有可以使用的format,

  Handler  
  Logging包含很多handler, 可能用到的有下面几种


  • StreamHandler instances send error messages to streams (file-like objects).
  • FileHandler instances send error messages to disk files.
  • RotatingFileHandler instances send error messages to disk files, with support for maximum log file sizes and log file rotation.
  • TimedRotatingFileHandler instances send error messages to disk files, rotating the log file at certain timed intervals.
  • SocketHandler instances send error messages to TCP/IP sockets.
  • DatagramHandler instances send error messages to UDP sockets.
  • SMTPHandler instances send error messages to a designated email address.
  最常用的也就是StreamHandler和FileHandler
  Configuration  


  • Creating loggers, handlers, and formatters explicitly using Python code that calls the configuration methods listed above.
  • Creating a logging config file and reading it using the fileConfig() function.
  • Creating a dictionary of configuration information and passing it to the dictConfig() function.
  第一种配置方法前面的code里面已经有了
  第二种配置方法, 我觉得在项目里面是比较实用的, 通过编写配置文件, 在code里面只需要用fileConfig配置一下logging, 显得比较简洁.
  这个可以参照http://crazier9527.iteye.com/blog/290026 或 官方文档.
  Multiple handlers and formatters  
  Loggers是一个简单的Python对象.addHandler()方法没有最多或者最少配额,当你的应用需要在把所有的log信息打到一个 txt文件中去,同时又需要把errors级别一上的错误信息打到console时,你就会体会到这个特性的好处.只要简单的配置一下合适的 handlers就可以实现这个功能.应用对logging的调用用不着修改.以下是对前一个基于module的配置例子的改进:
  



1 import logging
2 logger = logging.getLogger("simple_example")
3 logger.setLevel(logging.DEBUG)
4 # create file handler which logs even debug messages
5 fh = logging.FileHandler("spam.log")
6 fh.setLevel(logging.DEBUG)
7 # create console handler with a higher log level
8 ch = logging.StreamHandler()
9 ch.setLevel(logging.ERROR)
10 # create formatter and add it to the handlers
11 formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
12 ch.setFormatter(formatter)
13 fh.setFormatter(formatter)
14 # add the handlers to logger
15 logger.addHandler(ch)
16 logger.addHandler(fh)
17 # "application" code
18 logger.debug("debug message")
19 logger.info("info message")
20 logger.warn("warn message")
21 logger.error("error message")
22 logger.critical("critical message")

  多module使用Logging(只要在同一个Python interpreter process)  
  上面我曾提到过,所有的对logging.getLogger(‘someLogger’)的调用都会返回同一个对象.这个规则不仅仅在同一个 module有效,而且对在同一个Python的解释器进程里面的多个module也有效.而且,应用代码可以在一个module里面定义一个父 logger,而在另一个module里面继承这个logger,所有对这个子logger的调用都会转到父logger里面去,如下所示:
  下面这个是主模块的代码,
  



1 import logging
2 import auxiliary_module
3 # create logger with "spam_application"
4 logger = logging.getLogger("spam_application")
5 logger.setLevel(logging.DEBUG)
6 # create file handler which logs even debug messages
7 fh = logging.FileHandler("spam.log")
8 fh.setLevel(logging.DEBUG)
9 # create console handler with a higher log level
10 ch = logging.StreamHandler()
11 ch.setLevel(logging.ERROR)
12 # create formatter and add it to the handlers
13 formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
14 fh.setFormatter(formatter)
15 ch.setFormatter(formatter)
16 # add the handlers to the logger
17 logger.addHandler(fh)
18 logger.addHandler(ch)
19 logger.info("creating an instance of auxiliary_module.Auxiliary")
20 a = auxiliary_module.Auxiliary()
21 logger.info("created an instance of auxiliary_module.Auxiliary")
22 logger.info("calling auxiliary_module.Auxiliary.do_something")
23 a.do_something()
24 logger.info("finished auxiliary_module.Auxiliary.do_something")
25 logger.info("calling auxiliary_module.some_function()")
26 auxiliary_module.some_function()
27 logger.info("done with auxiliary_module.some_function()")

  这个是子模块的代码,
  



1 import logging
2 # create logger
3 module_logger = logging.getLogger("spam_application.auxiliary")
4 class Auxiliary:
5     def __init__(self):
6         self.logger = logging.getLogger("spam_application.auxiliary.Auxiliary")
7         self.logger.info("creating an instance of Auxiliary")
8     def do_something(self):
9         self.logger.info("doing something")
10         a = 1 + 1
11         self.logger.info("done doing something")
12 def some_function():
13     module_logger.info("received a call to /"some_function/"")

  可以看到, 我们在主模块里面定义了一个logger 'spam_application', 并对他进行了配置.
  那么在这个解释器进程里面的任何地方去通过getLogger('spam_application')得到的对象都是一样的, 不需要从新定义配置, 可以直接使用.
  更方便的是, 你定义任意该logger的子logger, 都可以共享父logger的定义和配置
  所谓的父子logger只是简单的通过命名来识别, 任意以'spam_application.'开头的logger都是他的子logger, 例如'spam_application.auxiliary'
  这个在实际的开发中, 还是很方便的, 对于一个application,
  首先通过logging配置文件编写好这个application所对应的log策略, 可以只生成一个根logger, 比如叫'Project'
  然后在Main函数里面, 通过fileConfig加载logging的配置
  接着在appliction的任意地方, 不同的模块中, 可以使用Project的子logger, 如Project.UI, Project.Core, 来进行log, 并且不需要反复的定义和配置各个logger.



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-58872-1-1.html 上篇帖子: python网络编程学习笔记(9):数据库客户端 下篇帖子: 黄聪:Python网站采集功能(多线程的采集、WDPYSPIDER类、pycurl)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表