模块logging是Python的标准日志记录工具。它实现了日志记录器的层次结构,并支持日志级别(严重性级别):DEBUG, INFO, WARNING, ERROR, CRITICAL。正确使用可以集中管理输出,保存日志到文件,通过电子邮件发送,按级别过滤等。
主要思想是在每个模块中创建带有名称的日志记录器(logging.getLogger(__name__)),而不是在每个地方都从头开始创建全局root日志记录器。配置(格式、处理器、级别)在应用程序启动时集中进行。
配置示例:
import logging logging.basicConfig(format='%(levelname)s:%(name)s:%(message)s', level=logging.INFO) logger = logging.getLogger(__name__) def foo(): logger.info('信息消息') logger.error('错误!') foo()
为什么不能在每个模块中调用logging.basicConfig()? 如果这样做,会发生什么?
答复: logging.basicConfig()只会在Python会话中设置root日志记录器一次。如果root日志记录器已经初始化,则重复调用将被忽略。因此,如果不同的模块尝试使用自己的格式/级别调用basicConfig(),只有第一个会生效!
故事
在一个大型项目中,每位开发人员通过basicConfig和本地处理器按照自己的喜好配置了日志记录。因此,一些日志根本没有输出,而其他日志则重复输出10倍,而且来自不同模块的消息无法放入一个文件中。
故事
在将Web服务迁移到多级日志记录时,忘记通过getLogger(__name__)指定日志记录器的名称,所有地方都写入了root日志记录器。最终无法确定特定日志来自何处。
故事
使用logger.error()函数记录所有消息,即使不是错误的消息。结果,自动监控系统不断“发出警报”,因为它们看到高错误级别,尽管这些只是调试/信息消息。