Python 日志管理

1 基本定义

不同日志级别:

  • INFO:记录关键代码点的信息,以确定代码是否按预期执行,生产环境常用
  • DEBUG:记录详细的信息,方便定位问题进行调试,在生产环境一般不开启
  • WARNING:记录某些不预期发生的情况,如磁盘不足,可接受的数据异常
  • ERROR:当程序某些功不能正常运行时,进行相关错误的记录(尽量详细)
  • CRITICAL:当发生严重错误,导致应用程序不能继续运行时记录的信息

基本概念:

  • 记录器(logger),用于记录具体日志的实例,记录器会根据实际代码调用和文件目录自动生成子记录器,也可以在对应的文件内设置单独的子记录器
  • 处理器(handler),负责日志的处理和发送,可以根据消息的类型发送到不同位置
  • 格式器(formatter),指定日志的输出格式,不同处理器可以设置不同类型的格式

常见的 4 种处理器包括:(1)StreamHandler,将日志消息发送到标准输出流、错误流(2)FileHandler ,将日志消息发送到文件 (3)RotatingFileHandler ,文件达到指定大小后,启用新文件存储日志(4)TimedRotatingFileHandler,日志文件以特定的时间间隔轮换

2 Logging 配置

Logging 常用的日志配置

import logging
from logging import StreamHandler

logging.basicConfig(level=logging.DEBUG) # 设置日志输出的最低级别
logging.basicConfig(filename="test.log", level=logging.INFO) # 设置日记文件
logger = logging.getLogger(__name__) # 创建记录器(使用当前文件名称)

### 指定日志格式:创建时间,日志级别,记录器名称,具体的日志消息  
logging.basicConfig(format='%(asctime)s %(levelname)s %(name)s %(message)s')

### 添加处理器,直接输出错误日志
handler = StreamHandler(sys.stderr)
logger.addHandler(handler)

### 针对特定处理器可以设置日志格式
formatter = Formatter(" %(levelname)s:%(name)s:%(message)s")
handler.setFormatter(formatter)

### logging 还支持单独的配置文件
import logging.config
logging.config.fileConfig('logging.conf')

logging.conf 配置文件示例:

[loggers]
keys=root [handlers]
keys=consoleHandler [formatters]
keys=simpleFormatter [logger_root]
level=DEBUG
handlers=consoleHandler [handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,) [formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s

3 常见问题

Q:为什么子记录器不需要设置日志等级也可以输出? A:除非特意设定,自动生成的子记录器会默认继承父记录器的配置

Q:为什么有时候日志会输出两次? A:可能是因为设置了两个日志格式不同的处理器

Q:怎么生成以日期时间命名的日志? A:给 logger 添加一个 TimedRotatingFileHandler 处理器就行

Q:为什么有时日志配置后不生效? A:可能和程序的加载顺序有关,日志配置应尽早初始化

参考:万字详解 python logging 日志模块

往年同期文章