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

[经验分享] Python的logging模块

[复制链接]

尚未签到

发表于 2015-4-27 09:57:01 | 显示全部楼层 |阅读模式
  转载自:http://gashero.yeax.com/?p=16
  


翻译:
gashero
  
  目录


  • 1   简介-Python文档
  • 2   各种Handler的子类

    • 2.1   TimedRotatingFileHandler


  

1   简介-Python文档
  从Python2.3版本中开始引入的logging模块为应用提供了灵活的日志系统。
  logging的行为依靠调用 Logger 类的方法来实现,实例一般叫做logger。每个实例都拥有自己的名字,并且可以通过点来分割具备层次的名字。例如,一个logger叫做”scan”是一个叫做”scan.text”的logger的顶层,当然也包括”scan.html”和”scan.pdf”。logger的名字指示了他属于应用程序的哪个位置。
  日志信息也拥有级别指定其重要程度。缺省提供的级别包括DEBUG,INFO,WARNING,ERROR,CRITICAL(严重)。为了方便,你可以调用特定的方法来指定日志的重要性,对应的方法为 debug() , info() , warning() , error() , critical() 。你也不必拘泥于这些级别,你可以使用更为通用的方法 log() 并且手动指定其级别。
  日志级别对应值如下表所示。了解这些有助于你定义自己的日志级别的相对关系。如果你定义的级别与已有的数值相同,则原有的级别会被覆盖。

级别数值
CRITICAL50
ERROR40
WARNING30
INFO20
DEBUG10
NOTSET0
  日志级别也可以在指定logger时定义,可以在开发时装入和存储配置。当调用logger的日志方法时,logger对比日志级别和自己的被指定的级别。如果本身的级别高于调用方法的级别,则不会记录这个日志信息。这是一个方便的方法用于忽略过多细节的日志。
  日志信息会被编码为 LogRecord 类,当logger决定记录一个事件时,就会为日志信息创建一个LogRecord实例。
  日志信息会被发布(dispatch)机制通过handler来发布出去,这些handler继承自 Handler 类。Handler负责把日志信息(LogRecord的实例)发布到对应的位置供处理这些信息。Handler传递LogRecord实例并指定特定目标。每个logger都可以拥有0个或多个handler,通过 addHandler() 方法添加。除了handler与logger的组合之外,所有的handler还会被所组合的祖先logger所调用来发布信息。
  有如logger,handler也可以有自己的级别过滤器,用于过滤日志级别。如果一个handler决定发布一个事件,可以调用 emit() 来发送信息到目的。大多数用户继承的Handler的子类需要重载这个emit()方法。
  除了基本的Handler类,比较有用的子类如:


  • StreamHandler实例发送错误到流(类似文件的对象)。
  • FileHandler实例发送错误到磁盘文件。
  • BaseRotatingHandler是所有轮徇日志的基类,不能直接使用。但是可以使用RotatingFileHandler和TimeRotatingFileHandler。
  • RotatingFileHandler实例发送信息到磁盘文件,并且限制最大的日志文件大小,并适时轮徇。
  • TimeRotatingFileHandler实例发送错误信息到磁盘,并在适当的事件间隔进行轮徇。
  • SocketHandler实例发送日志到TCP/IP socket。
  • DatagramHandler实例发送错误信息通过UDP协议。
  • SMTPHandler实例发送错误信息到特定的email地址。
  • SysLogHandler实例发送日志到UNIX syslog服务,并支持远程syslog服务。
  • NTEventLogHandler实例发送日志到WindowsNT/2000/XP事件日志。
  • MemoryHandler实例发送日志到内存中的缓冲区,并在达到特定条件时清空。
  • HTTPHandler实例发送错误信息到HTTP服务器,通过GET或POST方法。
  StreamHandler和FileHandler类都是在核心logging模块中定义的。其他handler定义在各个子模块中,叫做logging.handlers。当然还有一个logging.config模块提供了配置功能。
  日志信息在输出之前会经过 Formatter 类的格式化。他们在最开始使用%操作符来设置。
  批量格式化信息,需要 BufferingFormatter 类。除了格式化字符串之外,它还会在输出信息之前加上其他信息。
  当基于logger和handler的级别过滤器仍然不够时,可以使用 Filter 类的实例来添加到logger和handler实例中,通过他们的 addFilter() 方法。当决定输出日志之前,logger和handler会询问过滤器,如果过滤器返回False,则不会显示这条日志。
  最简单的过滤器功能用于指定日志的名字。如果使用了这个过滤器,则发送到命名logger和其子logger的日志将会通过,其他的会被丢弃。
  除了上面所描述的,还有很多模块级别的函数。如下:
  getLogger([name])

  返回一个logger,可以指定名字,如果没有指定名字则返回根logger。指定的名字典型的为以点分隔的分层次的名字。选择一个恰当的名字,让别人知道,谁在输出日志。所有使用相同名字调用这个函数都会返回相同的logger实例。这意味着logger实例不需要在应用中到处传递。

  getLoggerClass()

  返回一个标准的Logger类,或者上次传递到 setLoggerClass() 的类。这个函数用于定义一个新的日志类,但是之前的代码不会受到影响。例如:

class MyLogger(logging.getLoggerClass()):
#重载一些行为
  debug(msg[,*args[,**kwargs]])

  记录一个DEBUG级别的日志信息到根logger。 msg 参数就是用于输出的日志, args 参数是用于填入msg字符串的参数,当然kwargs也是差不多的角色。这说明msg可以是一个包含%d、%s等等的待格式化字符串。
  在kwargs中有2个参数是必须的: exc_info 如果不为False,则异常产生的信息也会被记录;如果提供了一个异常tuple(以 sys.exc_info() 格式),则会使用它;否则会调用 sys.exc_info() 来获取异常信息。
  另外一个参数为 extra 用于传递一个字典表示 LogRecord 中的 __dict__ 信息,可以加入用户自定义属性。这些传递的参数可以随你喜欢的。例如可能需要传递的:

FORMAT="%(asctime)-15s %(clientip)s %(user)-8s %(message)s"
logging.basicConfig(format=FORMAT)
dict={'clientip':'192.168.1.1','user':'fbloggs'}
logging.warning("Protocol problem: %s","connection reset",extra=d)
  将会有如下的显示:

2006-02-08 22:20:02,165 192.168.1.1 fbloggs Protocol problem: connection reset
  extra字典中的键不会与已有的键相冲突,具体可以参考Formatter的文档中关于使用字典的部分。
  在选择字典中的键名时,必须小心一些情况。上面的例子中,已经在待格式化字符串中有’clientip’和’user’了,这时如果没有传递这两个键,则不会输出日志,因为出现了异常了。这种情况时,你必须要传递这2个键。
  出于这种复杂性,这种功能往往用在很特殊的地方,比如多线程服务器,或关心多种信息的上下文环境,例如远程IP和登录用户。在这些情况中,需要先指定Formatter实例。 extra 参数从2.5版本开始加入。

  info(msg[,*args[,**kwargs]])

  记录INFO级别的日志信息,其他参数同debug()。

  warning(msg[,*args[,**kwargs]])

  记录WARNING级别的日志信息,其他参数同debug()。

  error(msg[,*args[,**kwargs]])

  记录ERROR级别的日志信息,其他参数同debug()。

  critical(msg[,*args[,**kwargs]])

  记录CRITICAL级别的日志信息,其他参数同debug()。

  exception(msg[,*args])

  记录ERROR级别的日志信息,其他参数同debug()。一般用在异常处理中。

  log(level,msg[,*args[,**kwargs]])

  记录level级别的日志信息,其他参数同debug()。

  disable(lvl)

  提供一个在logger中禁用某个级别日志的方法,用于应用临时切换可显示的日志。

  addLevelName(lvl,levelName)

  给级别lvl指定一个名字levelName到内部字典。以后用于映射数字的级别到特定的名字,供给Formatter用来格式化字符串。也可以用于定义自己的级别。这里也是唯一可以注册级别用的地方,级别必须是数字,并且在按照一定的排序要求。

  getLevelName(lvl)

  返回lvl级别的文字说明。如果级别是CRITICAL、ERROR、WARNING、INFO、DEBUG中的某一个,也会返回对应的名字。如果你自己通过addLevelName()自定义过级别,那么也会返回对应的名字。如果对应级别不存在,则返回 “Level %s”%lvl 这个字符串。

  makeLogRecord(attrdict)

  创建并返回一个LogRecord实例,并使用attrdict赋值过。这个函数用于把一个LogRecord给pickle过后通过socket发送,并方便接收方重组这个信息。

  basicConfig([**kwargs])

  对日志系统进行基本配置,使用缺省的StreamHandler和Formatter并添加根logger。一些函数如debug()、info()、warning()、error()、critical()会自动使用basicConfig()配置好的根logger进行日志输出。在2.4版之前,basicConfig()不接受字典参数。
  如下是支持的字典参数:


格式描述
filename指定FileHandler的文件名,而不是StreamHandler
filemode打开文件的模式,同open函数中的同名参数,默认为’a’
format输出格式字符串
datefmt日期格式
level设置根logger的日志级别
stream指定StreamHandler。这个参数与filename冲突,忽略stream
  shutdown()

  告知日志系统准备关闭日志并将所有信息写入磁盘。

  setLoggerClass(klass)

  告知日志系统使用类klass作为示例的Logger类。这个类应该定义 __init__() 方法并接受一个参数表示名字,而且 __init__() 方法应该在内部调用 Logger.__init__() 方法。这个函数一般在应用自定义Logger的行为时使用。

  PEP 282, A Logging System
  Original Python logging package
  

2   各种Handler的子类
  

2.1   TimedRotatingFileHandler
  TimedRotatingFileHandler 类是在logging.handler包中,支持对写入到磁盘的日志按照时间间隔来轮询。
  class TimedRotatingFileHandler(filename[,when[,interval[,backupCount]]])

  返回一个新的TimedRotatingFileHandler类实例,在指定文件名时会自动使用词缀。轮询发生的时间取决于参数 when 和 interval 。
  你可以使用 when 来指定 interval 的类型。可选值如下,注意区分大小写:


interval的类型
S
M分钟
H小时
D
W
midnight在午夜
  如果 backupCount 为非零,则系统会在旧日志文件名的末尾添加词缀。词缀格式为日期和时间,使用 strftime 格式如 %Y-%m-%d %H:%M:%S 或者依赖于之前的规则。最多会保留 backupCount 个日志文件,如果继续增加,会持续删除最旧的的日志。
  doRollover()

  进行一次回转,有如上面描述的。

  emit(record)

  把日志输出到文件,按照如上的回转规则。


运维网声明 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-61084-1-1.html 上篇帖子: 理解Python命名机制 下篇帖子: python cx_Oracle模块的安装和使用
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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