logging
是python自带的标准库,无需使用pip
进行安装。
import logging
日志模块作用
- 用于程序开发过程中的调试和运行记录
- 可以输出到日志文件,方便开发人员和运维人员对已经在现场部署程序的运行状态的掌握,若程序报错或运行结果不对,可根据日志文件进行错误定位。
日志级别
logging
模块预定义了5种日志级别,并根据它们所跟踪的事件的级别或严重程度来命名,具体如下:
Level | Numeric Value | When it's used |
---|---|---|
DEBUG |
10 | 报告详细的程序运行结果,用于调试 |
INFO |
20 | 报告程序正常运行期间发生的事件,或一些结果记录,确认程序在按照预期进行。 |
WARNING |
30 | 发出关于特定运行时事件的警告,说明程序本身对这种情况的处理是无能为力的,但是依然需要报告该情况。(例如输入数据小于0等不是由于算法造成的情况) |
ERROR |
40 | 报告异常,由于一个更严重的问题,程序已经不能执行一些功能。 |
CRITICAL |
50 | 表明程序本身可能无法继续运行。 |
注意:
在配置日志模块时,需要设定日志级别,低于该日志级别的日志记录将不会被打印输出。(默认级别是
WARNING
)可以自己自定义新的日志级别,当新定义的numeric value与预定义的value重复时,预定义的级别将会被覆盖
日志模块的四个重要组件
Loggers:算法与日志模块的接口
Handlers:将日志记录发送到指定的目标(控制台、文件、邮件等)
Formatters:指定最终输出中日志记录的样式。
Filters:为确定输出哪些日志记录提供了更细粒度的工具。
Loggers
Logger
对象有三个功能:
- 提供接口给算法,算法在运行时通过调用这些接口来记录日志
- 根据级别或过滤对象确定要对哪些日志消息进行操作(to
Handles
)。 - 将日志消息传递给所有与之相关的处理器。
Logger
对象的使用最广泛的方法主要是:配置和记录消息
常用配置:
-
Logger.setLever()
: 用于设置日志级别 -
Logger.addHandler()
: 添加处理器 -
Logger.addFilter()
: 添加过滤器
记录消息
当配置了Logger
对象后,就可以使用Logger.debug()
, Logger.info()
, Logger.warning
, Logger.error
, Logger.critical()
方法来创建日志消息,只需将需要记录的消息写进括号内即可
所有需要被记录的消息实际上是一个字符串,它可以包含标准字符串替换语法
%s
、%d
、%f
等来实现具体数据的输出。
Handlers
Handler
对象负责将日志消息(基于日志消息的严重性)分派给处理器的指定目标。在上一步中提到,可以使用Logger.addHandler()
来添加零个或多个处理器对象。例如,算法可以将所有日志消息都发送到控制台,将ERROR
或者更高级别的消息发送到磁盘文件。这就需要两个单独的处理器。
处理器有很多种类,常用的主要有以下几种:
StreamHandler: 将日志记录输出到数据流(例如sys.stdout, sys.stderr, 或者任何文件类对象)
FileHandler:将日志记录输出到磁盘文件中,它继承了
StreamHandler
的输出RotatingFileHandler:支持磁盘日志文件按文件大小轮换。当文件即将超出预定大小时,将关闭旧文件并打开一个新文件用于输出。
TimedRotatingFileHandler:支持磁盘日志文件按照特定时间间隔轮换。
Formatters
Formatter
对象是用来配置日志消息的最终输出形式。其格式由%(<dictionary key>)s
这样的表达形式来组合成字符串。例如:
'%(asctime)s - %(levelname)s - %(message)s'
其中,可以设置的<dictionary key>可参考LogRecord属性
配置日志模块
将日志记录输出在控制台
import logging
# 创建一个logger实例并设置日志级别
logger = logging.getLogger('alg_name')
logger.setLevel(logging.DEBUG)
# 配置handler,拟将日志记录输出在控制台
stdout_handler = logging.StreamHandler()
# 配置formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
stdout_handler.setFormatter(formatter)
# 添加handler至logger
logger.addHandler(stdout_handler)
配置完后,我们就可以在我们算法想要进行日志记录的地方调用Logger.debug()
, Logger.info()
, Logger.warning
, Logger.error
, Logger.critical()
来进行日志输出了。比如:
# 下面的内容都是写在算法文件里你需要的地方
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
当运行算法时,你会看到控制台输出以下内容
2005-03-19 15:10:26,618 - alg_name - DEBUG - debug message
2005-03-19 15:10:26,620 - alg_name - INFO - info message
2005-03-19 15:10:26,695 - alg_name - WARNING - warn message
2005-03-19 15:10:26,697 - alg_name - ERROR - error message
2005-03-19 15:10:26,773 - alg_name - CRITICAL - critical message
将日志记录输出至日志文件
import logging
# 创建一个logger实例并设置日志级别
logger = logging.getLogger('alg_name')
logger.setLevel(logging.DEBUG)
# 配置handler,拟将日志记录输出至/log/文件夹
file_name = './log/alg_name_log.log' # 注意:如果/log/文件夹不存在,则需要新建
file_handler = logging.handlers.TimedRotatingFileHandler(file_name, when='MIDNIGHT', interval=1, backupCount=30) # 每天午夜生成alg_name_log.log文件,最多保留30天
# 配置formatter
formatter = logging.Formatter('%(levelname)s - %(asctime)s [%(filename)s:%(lineno)d] %(message)s \n')
file_handler.setFormatter(formatter)
# 添加handler至logger
logger.addHandler(file_handler)