You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python logging跨模块调用时日志配置不生效如何解决

问题原因

你遇到的问题由三个细节共同导致:

  1. 你当前只给名为__main__的logger绑定了handler和格式配置,Python logging的继承规则是子logger默认向上查找父logger(最终到根logger)的配置,submodule对应的logger和__main__是平级,根本不会继承__main__上挂的配置。
  2. 你在日志配置完成前就导入了submodule,而submodule里的logger.info('Test 1')、logger.error('Test 2')是导入阶段就直接执行的,执行时日志配置还没生效。
  3. 未单独配置级别的logger默认日志级别是WARNING,所以子模块的INFO级别的Test 1会被直接过滤;Test 2是ERROR级别,会触发logging默认挂载的标准错误流handler,这个handler没有设置你自定义的格式,所以只会输出原始消息文本。
修复方法

按以下调整即可,子模块代码不需要做任何修改:

  • 统一配置根logger,而不是给__main__专属logger挂handler,所有模块通过logging.getLogger(__name__)拿到的logger都会自动继承根logger的配置。
  • 把导入子模块的逻辑挪到日志全部配置完成之后,保证导入阶段执行的日志语句能拿到正确配置。
  • 补上原代码缺失的sys模块导入,你代码里h1指定输出到sys.stdout但没导入sys,运行会直接抛错。

调整后的main.py代码如下:

# File: main.py
import logging
import sys

def main():
    logger = logging.getLogger(__name__)
    logger.debug(f'Test')

if __name__ == '__main__':
    # 初始化根logger配置
    root_logger = logging.getLogger()
    root_logger.setLevel(logging.DEBUG)
    formatter = logging.Formatter('[%(levelname)s | %(name)s] %(message)s')

    # 处理debug、info级别日志输出到stdout
    h1 = logging.StreamHandler(sys.stdout)
    h1.setLevel(logging.DEBUG)
    h1.addFilter(lambda record: record.levelno <= logging.INFO)
    h1.setFormatter(formatter)

    # 处理warning及以上级别日志输出到stderr
    h2 = logging.StreamHandler()
    h2.setLevel(logging.WARNING)
    h2.setFormatter(formatter)

    root_logger.addHandler(h1)
    root_logger.addHandler(h2)

    # 日志配置完成后再导入子模块
    import submodule

    main()

运行后就能得到符合预期的输出:

[INFO | submodule] Test 1
[DEBUG | __main__] Test
[ERROR | submodule] Test 2

注:Test 1的输出顺序在Test前面是因为submodule导入时就会执行info日志,main函数里的debug日志是调用main()时才触发,属于正常现象。如果需要调整顺序,把submodule里的日志语句放到函数里,等main调用时再执行即可。


内容的提问来源于stack exchange,提问作者user16456506

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.22 16:12:26