在 python 中,logging 有几个关键的类,分别是 LoggerHandlerFilterFormatter,理解好他们的关系,对于日志理解就不好那么杂乱了,他们之间的关系可以表示为:

Loggerlevel 的话,python 是有这么几个 level 的:按照日志级别大小关系为CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET,当然也可以自己定义日志级别。

下面就讲解几个例子来深化这些概念:

1. 默认的配置

1
2
3
>>> import logging
>>> logging.getLogger().warning("hehe")
No handlers could be found for logger "root"

跑一遍之后会发现打印出来的并不是 "hehe",什么都没有,我的 pyhton 环境是 python 2.7.11,默认情况下,logging 的默认 logger 是没有 handler 的,所以日志是打不出来的。

2. 配置打印到文件

1
2
3
4
5
6
7
8
9
import logging

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                    datefmt='%a, %d %b %Y %H:%M:%S',
                    filename='myapp.log',
                    filemode='w')

logging.debug('This is debug message')

这里用的是 logging 的 basicConfig,它默认配置的是一个叫做 'root' 的 Logger,可以看到他的参数,levelDEBUG 级别,然后配置了日志格式和时间格式,因为是输出到文件,所以还要指定文件的位置以及打开模式。我们打开文件 ./myapp.log,可以看到文件中内容为:

1
Fri, 09 Sep 2016 17:40:34 <stdin>[line:1] INFO hehe

logging.basicConfig函数各参数含义见附录一。

3. 配置日志输出到控制台

1
2
3
4
5
6
7
8
9
import logging

console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
console.setFormatter(formatter)
logging.getLogger('').addHandler(console)

logging.debug('This is debug message')

可以看到,这里显式得创建了一个 StreamHandler 和 Formatter,然后设置 Level 和 formatter,然后将它加入到 Logger 中。我们可以在屏幕上看到输出:

1
root        : WARNING  This is debug message

4. 配置日志回滚

1
2
3
4
5
6
7
8
9
import logging
from logging.handlers import RotatingFileHandler

#定义一个RotatingFileHandler,最多备份5个日志文件,每个日志文件最大10M
Rthandler = RotatingFileHandler('myapp.log', maxBytes=10*1024*1024,backupCount=5)
Rthandler.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
Rthandler.setFormatter(formatter)
logging.getLogger('').addHandler(Rthandler)

这里其实是 logging 中的一个特殊的 Handler,叫 RotatingFileHandler,然后其他各方面都和刚才的 Handler 一致,不过还多了一个,就是文件的最大 size 以及回滚文件的个数。除了 RotatingFileHandler 之外,我们还可以考虑使用 TimedRotatingFileHandler

logging的几种handle方式如下:

更多的 Handler 可以参考附录二。

5.通过文件配置日志

我们上面的例子都是在代码中对 logger 进行配置的,其实,除了在代码中配置之外,还可以在配置文件中配置好这一切,配置文件是 python 原生支持的 ini 配置文件。

由于配置文件太长,所以我以附件 的形式给出,如有需要开在新窗口打开查看。然后看下使用示例:

1
2
3
4
5
6
7
import logging
import logging.config

logging.config.fileConfig(logger.conf)
logger = logging.getLogger(example01)

logger.warning('This is warning message')

附录

附录一

logging.basicConfig 各参数含义:

附录二

logging.handlers 中的更多 Handler

由于 StreamHandlerFileHandler 是常用的日志处理方式,所以直接包含在 logging 模块中,而其他方式则包含在 logging.handlers 模块中。

Reference