Python logging模块在basicConfig调用前输出日志导致配置不生效疑问
Python logging模块先输出日志再调用basicConfig不生效的原因
核心原因是logging.basicConfig的设计特性:该函数仅在根日志器(root logger)没有任何已绑定的处理器(Handler)时才会生效,一旦根日志器已经存在处理器,后续调用basicConfig不会产生任何效果。
logging模块在你第一次调用任何日志输出方法(比如logging.info、logging.error等)时,会自动检查根日志器是否已经配置了处理器,如果没有,就会自动绑定默认的StreamHandler,同时使用默认的日志配置:
- 日志级别默认为
WARNING - 输出格式默认为
日志级别:日志器名称:日志内容 - 默认输出到控制台
第一段代码执行逻辑
- 导入logging模块后,首先执行
logging.info("toto"),触发自动初始化逻辑,给根日志器绑定了默认处理器,使用默认配置 - 后续调用
logging.basicConfig时,检测到根日志器已经存在处理器,直接跳过配置,你写的自定义级别、格式都没有生效 - 后续输出日志时还是使用默认配置:只有级别>=WARNING的日志(error、warning)会输出,格式也是默认的简洁格式,和给出的输出结果一致。
第二段代码执行逻辑
- 导入模块后先调用
logging.basicConfig,此时根日志器还没有任何处理器,配置成功:日志级别设为INFO,输出格式替换成你自定义的带时间、线程、代码位置的格式 - 后续输出日志时使用自定义配置:级别>=INFO的日志(info、error、warning)都会输出,debug级别低于INFO所以不会输出,格式符合你的自定义规则,和给出的输出结果一致。
特殊场景兼容方案
如果确实需要先输出日志再修改配置,可以在调用basicConfig前先清空根日志器的已有处理器:
import logging logging.info("toto") # 清空根日志器已有处理器 for handler in logging.root.handlers[:]: logging.root.removeHandler(handler) # 此时再调用basicConfig就会正常生效 logging.basicConfig(level="INFO", format="%(asctime)s - %(threadName)s -" " %(levelname)s" " - [%(funcName)s():%(filename)s:%(lineno)s]" " - %(message)s")
内容的提问来源于stack exchange,提问作者Itération 122442
相关产品推荐
相关产品推荐

