调用logging.basicConfig时自定义logger出现重复日志问题咨询
重复日志问题原因
Python logging 模块默认开启日志层级向上传播规则:自定义logger生成的日志,除了触发自身绑定的处理器执行,还会向上传递给所有父级logger(最终到root logger),触发父级绑定的所有处理器执行。
你当前的场景中:
- 自行创建的
log对象确实仅绑定了1个自定义StreamHandler,所以打印len(log.handlers)返回1符合预期 - 调用
logging.basicConfig()方法时,会自动为未绑定任何处理器的root logger新增一个默认StreamHandler,同时设置root logger的日志级别 - 两次日志分别来自你自定义的logger的处理器、以及日志向上传播到root logger后触发的root默认处理器输出,两者格式一致因此看起来是完全重复的内容
解决方案
方案1:关闭自定义logger的传播(最轻便,无需调整其他逻辑)
创建自定义logger后新增一行关闭传播配置即可,日志只会在当前logger层处理,不会向上传递到root:
log.propagate = False
方案2:提前完成全局日志初始化
logging.basicConfig()仅在root logger无处理器时才会生效,你可以在导入所有内部调用basicConfig的第三方模块之前,先完成root logger的自定义配置,后续第三方模块调用basicConfig不会生效,也就不会新增多余的处理器。
方案3:清空root logger的处理器
如果不需要root logger输出任何日志,可以直接清空root绑定的所有处理器:
logging.root.handlers.clear()
修复后参考代码
import logging import sys # 创建一个logger,添加一个handler和formatter log = logging.getLogger(__name__) log.setLevel(logging.INFO) handler = logging.StreamHandler(stream=sys.stdout) handler.setFormatter(logging.Formatter("%(levelname)s:%(name)s:%(message)s")) log.addHandler(handler) # 关闭日志向上传播 log.propagate = False # 调用basicConfig logging.basicConfig(level=logging.INFO) # 生成一条日志消息 log.info("hello world") # 校验logger上的handler数量 print(f" num_handlers = {len(log.handlers)}")
运行后仅输出一行日志,符合预期。
内容的提问来源于stack exchange,提问作者Arran Duff
相关产品推荐
相关产品推荐

