[关闭]
@spiritnotes 2016-03-07T15:54:06.000000Z 字数 2480 阅读 1446

Python标准库学习 -- logging

Python


Python标准库中含有一个logging,其支持常见的一些日志操作。

入门

logging最简单的应用就是直接在屏幕上打印信息。

  1. def test():
  2. import logging
  3. logging.debug('debug message')
  4. logging.info('info message')
  5. logging.warning('warning message')
  6. logging.error('error message')
  7. logging.critical('critical message')
  8. test()

输出结果如下:

  1. WARNING:root:warning message
  2. ERROR:root:error message
  3. CRITICAL:root:critical message

由输出可以看到只有WARNING以及以上的等级才被打印出来,这个时候可以更改logging模块配置来改变该行为,这个时候就可以打印出所有日志了。

  1. logging.basicConfig(level=logging.DUBUG)

Formatter

Formatter用以定义日志的显示形式,其中可以包含logger名字,级别,线程ID,进程ID等各种信息。其可以在logging.basicConfig,也可以添加在handler中。

  1. formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  2. logging.basicConfig(formatter=formatter)

logger

在上面例子中我们发现输出中有root,这是怎么回事呢?这就要牵扯到logger的概念了。logger是logging中日志记录对象,我们通过调用logger的各种方法(info、warn等)来记录日志。而root就是logging模块默认产生的一个logger。我们要创建一个logger很简单,直接采用getLogger方法调用即可。然后就可以单独针对该logger进行自己的配置。

  1. def test_2():
  2. import logging
  3. logger = logging.getLogger('test')
  4. logger.setLevel(logging.CRITICAL)
  5. logger.debug('debug message')
  6. logger.info('info message')
  7. logger.warning('warning message')
  8. logger.error('error message')
  9. logger.critical('critical message')

其输出如下

  1. CRITICAL:test:critical message

而调用logging默认就是使用其中名为root的logger,同样logging.getLogger()也会返回root Logger,并应用默认的日志级别、Handler和Formatter设置。

handler

handler就是如何对日志进行处理,是写入文件,还是显示在屏幕上,还是发送给网络。logging预定义了很多种handler,如logging.StreamHandler、logging.FileHandler,而我们实际上使用的时候没有定义handler,是因为其使用了默认的handler。

  1. ch = logging.StreamHandler()
  2. formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  3. ch.setFormatter(formatter)
  4. logger1.addHandler(ch)

handler常用方法包含setLevel、setFormatter、addFilter等。

logger之间关系

  1. def test_3():
  2. import logging
  3. ch = logging.StreamHandler()
  4. formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  5. ch.setFormatter(formatter)
  6. logger1 = logging.getLogger('root.test')
  7. logger1.addHandler(ch)
  8. logger2 = logging.getLogger('root.test.xxx')
  9. logger2.addHandler(ch)
  10. logger2.setLevel(logging.CRITICAL)
  11. logger2.critical('critical message')

其结果如下,一条消息出现了两次,为什么呢?这是因为logger的名字按照‘.’形成了树的关系,在子代发生的消息同样要传递给父代,而前提起作用的是用户自定义的hanlder,对于系统默认的handler是不起作用的。

  1. 2016-03-07 23:34:24,085 - root.test.xxx - CRITICAL - critical message
  2. 2016-03-07 23:34:24,085 - root.test.xxx - CRITICAL - critical message

filter

所谓filter就是对日志的输出进行控制的。可以添加在handler中,也可以添加在logger中,两者起作用的范围不一样。常见的是对名字进行过滤。

  1. filter = logging.Filter('root.test.xxx')
  2. ch.addFilter(filter)

配置文件

此外,还可以通过配置文件对logging进行配置,通过如下代码进行调用。

  1. logging.config.fileConfig("logging.conf")

使用惯例

在于实际项目中,往往在主执行文件中进行配置,而在其他子文件中,通过__name__获取对应的logger,以便于使用和定位。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注