运行结果如下:
# 控制台输出: === Warning 级别的信息 === === Error 级别的信息 === === Critical 级别的信息 === # test.log文件: === Info 级别的信息 === === Warning 级别的信息 === === Error 级别的信息 === === Critical 级别的信息 ===
③ 定制日志输出格式
纠结完输出到那里,接着就输出日志的格式了,日志一般都是比较规范的,比如日志打印的时间,类型等,而不会像我们这样随意拼接一段字符串,对于日志格式的定制可以通过
logging模块
的Formatter组件
来定制。basicConfig()
中的handler 自带一个formatter,通过logging.basicConfig(**kwargs)函数
进行定制,该函数可接收的关键字参数如下表所示。
参数 | 描述 |
filename | 指定日志输出目标文件的文件名,设置后信息就不会打印到控制台 |
filemode | 指定日志文件的打开模式,默认为'a',设置了filename这个才会生效 |
format | 指定日志格式字符串,即指定日志输出时所包含的字段信息以及它们的顺序 |
datefmt | 指定日期/时间格式,该选项要在format中包含时间字段%(asctime)s时才有效 |
level | 指定日志器的日志级别 |
stream | 指定日志输出目标stream,不能和filename同时使用否则会引起ValueError异常 |
style | Python 3.2新增,默认'%'指定format格式字符串的风格,可取值为'%'、'{'和'$' |
format格式字符串的字段列表如下表所示:
参数 | 描述 |
%(asctime)s | 日志发生的时间--人类可读时间,如:2003-07-08 16:49:45,896 |
%(created)f | 日志发生的时间--时间戳,就是当时调用time.time()函数返回的值 |
%(relativeCreated)d | 日志发生的时间相对于logging模块加载时间的相对毫秒数 |
%(msecs)d | 日志发生时间的毫秒部分 |
%(levelname)s | 该日志记录的文字形式的日志级别('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL') |
%(levelno)s | 该日志记录的数字形式的日志级别(10, 20, 30, 40, 50) |
%(name)s | 所使用的日志器名称,默认是'root',因为默认使用的是 rootLogger |
%(message)s | 日志记录的文本内容,通过 msg % args计算得到的 |
%(pathname)s | 调用日志记录函数的源码文件的全路径 |
%(filename)s | pathname的文件名部分,包含文件后缀 |
%(module)s | filename的名称部分,不包含后缀 |
%(lineno)d | 调用日志记录函数的源代码所在的行号 |
%(funcName)s | 调用日志记录函数的函数名 |
%(process)d | 进程ID |
%(processName)s | 进程名称,Python 3.1新增 |
%(thread)d | 线程ID |
%(thread)s | 线程名称 |
简单的使用代码示例如下:
import logging if __name__ == '__main__': logger = logging.getLogger("Test") logging.basicConfig(level=logging.INFO, format="%(asctime)s %(process)d:%(processName)s- %(levelname)s === %(message)s", datefmt="%Y-%m-%d %H:%M:%S %p") logger.debug("Debug 级别的信息") logger.info("Info 级别的信息") logger.warning("Warning 级别的信息") logger.error("Error 级别的信息") logger.critical("Critical 级别的信息")
运行结果如下:
2019-03-14 16:39:02 PM 8628:MainProcess- INFO === Info 级别的信息 2019-03-14 16:39:02 PM 8628:MainProcess- WARNING === Warning 级别的信息 2019-03-14 16:39:02 PM 8628:MainProcess- ERROR === Error 级别的信息 2019-03-14 16:39:02 PM 8628:MainProcess- CRITICAL === Critical 级别的信息
另外要注意一点basicConfig没有设置编码的属性,如果想把日志写入到文件里,而日志里又有中文的话,只能通过一开始那种设置FileHandler对象的方式!除了通过basicConfig()设置日志格式,还可以自定义一个Formatter对象,然后调用
setFormatter
函数进行设置。使用代码示例如下:
import logging if __name__ == '__main__': logger = logging.getLogger("Test") logger.setLevel(logging.INFO) # 自定义Formatter对象 fmt = logging.Formatter("%(asctime)s %(process)d:%(processName)s- %(levelname)s === %(message)s", datefmt="%Y-%m-%d %H:%M:%S %p") # 输出到控制台 s_handler = logging.StreamHandler() s_handler.setLevel(logging.WARNING) s_handler.setFormatter(fmt) logger.addHandler(s_handler) # 输出到文件 f_handler = logging.FileHandler('test.log', encoding='UTF-8') f_handler.setLevel(logging.DEBUG) f_handler.setFormatter(fmt) logger.addHandler(f_handler) logger.debug("Debug 级别的信息") logger.info("Info 级别的信息") logger.warning("Warning 级别的信息") logger.error("Error 级别的信息") logger.critical("Critical 级别的信息")
运行结果如下:
# 控制台输出: 2019-03-14 16:41:09 PM 11312:MainProcess- WARNING === Warning 级别的信息 2019-03-14 16:41:09 PM 11312:MainProcess- ERROR === Error 级别的信息 2019-03-14 16:41:09 PM 11312:MainProcess- CRITICAL === Critical 级别的信息 # test.log文件: 2019-03-14 16:41:09 PM 11312:MainProcess- INFO === Info 级别的信息 2019-03-14 16:41:09 PM 11312:MainProcess- WARNING === Warning 级别的信息 2019-03-14 16:41:09 PM 11312:MainProcess- ERROR === Error 级别的信息 2019-03-14 16:41:09 PM 11312:MainProcess- CRITICAL === Critical 级别的信息
logging除了Handler
和Formatter
两个组件外还有,Filter
和LoggerAdapter
组件,不过用得不多,有兴趣的同学可以自行到官方文档进行查阅: