之前写过一篇文章日志的艺术(The art of logging),提到了输出日志的时候记录上下文信息的重要性,我认为上下文信息包括:
when:log事件发生的时间
where:log事件发生在哪个模块(文件、函数)
how important:log 事件的紧急程度
who:事件产生者的唯一标识
what:具体的事件内容,以及其他所必须的上下文信息
其中,when、where、how important都很容易通过logging框架自动包含,但是who(事件生产者的唯一标识)就不能框架自动填充了。比如在服务器端,同时有大量的用户,如果日志缺乏用户唯一标识,如(User can not login),那么可以说这样的日志是毫无意义的。特别是当线上出问题的时候,而且是偶发的问题的时候,日志往往是查找问题的唯一途径,如果这个时候日志信息不充分,那就很让人抓狂了。
虽然在团队中强调过很多次,但是很多同事还是会输出毫无意义的log,也曾试过静态代码检查或者运行时分析,不过都不太优雅,于是希望能够自动添加一些重要的上下文信息,比如用户唯一标识。
虽然每天都在打log,但事实上我以前也没有深度了解过python logging模块,于是借着这个机会,仔细看了一下logging文档与源码。
这里补充一句,虽然网上有很多文章介绍python logging模块,但还是建议直接看官方资料,顺序如下:、、、源码
本文地址:https://www.cnblogs.com/xybaby/p/9176140.html
初识python logginglogging模块是python官方提供的、标准的日志模块。看代码的话是借鉴了许多log4j中的概念和思想。
logging模块包括以下几大组件:
Loggers expose the interface that application code directly uses.
Handlers send the log records (created by loggers) to the appropriate destination.
Filters provide a finer grained facility for determining which log records to output.
Formatters specify the layout of log records in the final output.
下面结合一个更完整的例子来逐个介绍。example1.py
1 import logging 2 class ContextFilter(logging.Filter): 3 def filter(self, record): 4 record.userid = '123' 5 return True 6 7 8 if __name__ == '__main__': 9 # create logger 10 logger = logging.getLogger('simple_example') 11 logger.setLevel(logging.DEBUG) 12 13 # create console handler and set level to debug 14 ch = logging.StreamHandler() 15 ch.setLevel(logging.DEBUG) 16 # create formatter for console handler 17 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 18 # add formatter to console handler 19 ch.setFormatter(formatter) 20 21 # create file handler and set level to warn 22 fh = logging.FileHandler('spam.log') 23 fh.setLevel(logging.WARN) 24 # create formatter for file handler 25 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(userid)s - %(message)s') 26 # add formatter to file handler 27 fh.setFormatter(formatter) 28 # add context filter to file handler 29 fh.addFilter(ContextFilter()) 30 31 # add ch、fh to logger 32 logger.addHandler(ch) 33 logger.addHandler(fh) 34 35 # 'application' code 36 logger.debug('debug message') 37 logger.info('info message') 38 logger.warn('warn message %s', 'args') 39 logger.error('error message') 40 logger.critical('critical message')