@spiritnotes
2016-03-07T15:54:06.000000Z
字数 2480
阅读 1585
Python
Python标准库中含有一个logging,其支持常见的一些日志操作。
logging最简单的应用就是直接在屏幕上打印信息。
def test():
import logging
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
test()
输出结果如下:
WARNING:root:warning message
ERROR:root:error message
CRITICAL:root:critical message
由输出可以看到只有WARNING以及以上的等级才被打印出来,这个时候可以更改logging模块配置来改变该行为,这个时候就可以打印出所有日志了。
logging.basicConfig(level=logging.DUBUG)
Formatter用以定义日志的显示形式,其中可以包含logger名字,级别,线程ID,进程ID等各种信息。其可以在logging.basicConfig,也可以添加在handler中。
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logging.basicConfig(formatter=formatter)
在上面例子中我们发现输出中有root,这是怎么回事呢?这就要牵扯到logger的概念了。logger是logging中日志记录对象,我们通过调用logger的各种方法(info、warn等)来记录日志。而root就是logging模块默认产生的一个logger。我们要创建一个logger很简单,直接采用getLogger方法调用即可。然后就可以单独针对该logger进行自己的配置。
def test_2():
import logging
logger = logging.getLogger('test')
logger.setLevel(logging.CRITICAL)
logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')
其输出如下
CRITICAL:test:critical message
而调用logging默认就是使用其中名为root的logger,同样logging.getLogger()也会返回root Logger,并应用默认的日志级别、Handler和Formatter设置。
handler就是如何对日志进行处理,是写入文件,还是显示在屏幕上,还是发送给网络。logging预定义了很多种handler,如logging.StreamHandler、logging.FileHandler,而我们实际上使用的时候没有定义handler,是因为其使用了默认的handler。
ch = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
logger1.addHandler(ch)
handler常用方法包含setLevel、setFormatter、addFilter等。
def test_3():
import logging
ch = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
logger1 = logging.getLogger('root.test')
logger1.addHandler(ch)
logger2 = logging.getLogger('root.test.xxx')
logger2.addHandler(ch)
logger2.setLevel(logging.CRITICAL)
logger2.critical('critical message')
其结果如下,一条消息出现了两次,为什么呢?这是因为logger的名字按照‘.’形成了树的关系,在子代发生的消息同样要传递给父代,而前提起作用的是用户自定义的hanlder,对于系统默认的handler是不起作用的。
2016-03-07 23:34:24,085 - root.test.xxx - CRITICAL - critical message
2016-03-07 23:34:24,085 - root.test.xxx - CRITICAL - critical message
所谓filter就是对日志的输出进行控制的。可以添加在handler中,也可以添加在logger中,两者起作用的范围不一样。常见的是对名字进行过滤。
filter = logging.Filter('root.test.xxx')
ch.addFilter(filter)
此外,还可以通过配置文件对logging进行配置,通过如下代码进行调用。
logging.config.fileConfig("logging.conf")
在于实际项目中,往往在主执行文件中进行配置,而在其他子文件中,通过__name__获取对应的logger,以便于使用和定位。