作者:尹超
日期:2019-9-19
python的logging模块有多种配置方式,可以通过api进行直接配置,也可以通过配置文件的形式进行配置,各有利弊。
通过api进行配置好处是比较简单随意,缺点是配置不方便修改和共用
通过配置文件的形式进行配置的好处在于多模块可以复用相同配置,工程中常使用这种模式
而配置文件常见有两种形式
fileConfig()
这种形式已经被淘汰不用了
[loggers]
keys=root,log02,log03,log04,log05,log06,log07
[handlers]
keys=hand01,hand02,hand03,hand04,hand05,hand06,hand07,hand08,hand09
[formatters]
keys=form01,form02,form03,form04,form05,form06,form07,form08,form09
dictConfig()
其一是以json格式的配置
其二是以yaml格式的配置(更简洁)
综上,本文统一采用yaml的配置模式
key名称 | 描述 |
---|---|
version | 必选项,其值是一个整数值,表示配置格式的版本,当前唯一可用的值就是1 |
formatters | 可选项,其值是一个字典对象,该字典对象每个元素的key为要定义的格式器名称,value为格式器的配置信息组成的dict,如format和datefmt |
filters | 可选项,其值是一个字典对象,该字典对象每个元素的key为要定义的过滤器名称,value为过滤器的配置信息组成的dict,如name |
handlers | 可选项,其值是一个字典对象,该字典对象每个元素的key为要定义的处理器名称,value为处理器的配置信息组成的dcit,如class、level、formatter和filters,其中class为必选项,其它为可选项;其他配置信息将会传递给class所指定的处理器类的构造函数,如下面的handlers定义示例中的stream、filename、maxBytes和backupCount等 |
loggers | 可选项,其值是一个字典对象,该字典对象每个元素的key为要定义的日志器名称,value为日志器的配置信息组成的dcit,如level、handlers、filters 和 propagate(yes |
root | 可选项,这是root logger的配置信息,其值也是一个字典对象。除非在定义其它logger时明确指定propagate值为no,否则root logger定义的handlers都会被作用到其它logger上 |
incremental | 可选项,默认值为False。该选项的意义在于,如果这里定义的对象已经存在,那么这里对这些对象的定义是否应用到已存在的对象上。值为False表示,已存在的对象将会被重新定义。 |
disable_existing_loggers | 可选项,默认值为True。该选项用于指定是否禁用已存在的日志器loggers,如果incremental的值为True则该选项 |
官方规定只有version字段是强制配置的,其余全部可以选配
实际使用中,为了便于改动和自定义调整,常常还需配置如下三个字段
下文重点讲述以上三个字段的配置方法
可以将格式统一成几类并实例化,方便不同格式的输出
format配置:
默认情况下: “%(message)s”,最简单的输出形式,常见定义如下:
%(message)s 打印实际log内容(必选)
%(asctime)s 打印时间
%(name)s 打印logger的实例名
%(filename)s: 打印log的文件名
%(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
%(funcName)s: 打印函数名
%(levelname)s 打印log等级
%(thread)d: 打印线程ID
%(threadName)s: 打印线程名称
%(process)d: 打印进程ID
datefmt配置:
%F 显示日期
%T 显示时间
实际可用的配置示例:
formatters:
simple:
format: "%(levelname)s | %(message)s"
full:
format: "%(asctime)s | %(name)s | %(levelname)s | %(message)s"
datefmt: #精确控制日期(%F),时间(%T)的显示
"%F %T"
logging自带3个hanlder
还有logging.handlers下的handler类型:
SocketHandler、DatagramHandler、SysLogHandler、NtEventHandler、SMTPHandler、MemoryHandler、HTTPHandler不常用,需要请参考官方文档
主要的配置属性有如下4个:
handler类型定义,上述
日志级别:CRITICAL、ERROR、WARNING、INFO、DEBUG
选择上述自定义好的formatter格式
可以不用配置
其他配置属性:请参见不同handler定义具体查看,传送门
给出一个示例
handlers:
console: #可实例化的handler1
class: logging.StreamHandler
level: DEBUG
formatter: full
info_file_handler: #可实例化的hander2
class: logging.handlers.RotatingFileHandler
level: INFO
formatter: simple
filename: test.log
maxBytes: 1024
backupCount: 1
encoding: "utf8"
logger为日志器设置具体名称,用户在此指定读取的log来源
root
loggers
需要为日志器指定level, handlers, propagate三个参数
指定输出的等级,只会输出等于或高于该等级的log
默认有如下5个等级,由高到低。用户亦可以自定义(完全够用了嘛)
CRITICAL
ERROR
WARNING
INFO
DEBUG
决定该log生成器采用前文中哪一个handler配置
看不懂的话该参数默认配置为0就好了
propagate
entry is set to 1 to indicate that messages must propagate to handlers higher up the logger hierarchy from this logger, or 0 to indicate that messages are not propagated to handlers up the hierarchy.
意思是propagate有继承的意思,如果使能该参数,则低级别的logger日志会复制到上层logger,有可能会有重复输出,一般意义上需要显示将该参数设置为0
给出一个可用的示例
loggers: #默认生成器【不可以自定义】
my_log: #生成器1,可随意取名字
level: ERROR
handlers: [info_file_handler]
propagate: no
root: #默认生成器【不可以自定义】
level: DEBUG
handlers: [console]
propagate: no
version: 1
disable_existing_loggers: False
formatters:
simple:
format: "%(levelname)s | %(message)s"
full:
format: "%(asctime)s | %(name)s | %(levelname)s | %(message)s"
datefmt:
"%F %T"
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: full
info_file_handler:
class: logging.handlers.RotatingFileHandler
level: INFO
formatter: simple
filename: test.log
maxBytes: 1024
backupCount: 1
encoding: "utf8"
loggers:
fileLogger:
level: ERROR
handlers: [info_file_handler]
propagate: no
root:
level: DEBUG
handlers: [console]
propagate: no
很简单,以级别高的为准
YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated,
经查是YAML5.1标准以后禁止直接load(),需要显示指定load的来源:
yaml.load(f) #旧的报错
yaml.load(f, Loader=yaml.FullLoader) #新的没问题
官网配置说明
详解python之配置日志的几种方式
logging模块yaml配置