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

Python logging如何跨多文件访问同一个自定义Logger实例

实现全局唯一自定义Logger实例的方法

核心逻辑是利用Python logging模块自带的同名logger单例机制,在所有跨模块导入、所有logger实例化操作之前注册自定义Logger类,保证第一次生成目标logger时就用你定义的CustomLogger类,后续所有文件调用logging.getLogger('the_only_logger')拿到的都是同一个实例。


正确代码示例

main.py 写法

必须严格遵守顺序:先定义自定义类 → 注册自定义类到logging体系 → 实例化logger并完成配置 → 最后导入其他依赖logger的项目文件

# main.py
import logging

# 自定义Logger类,修正原代码的语法错误、补全父类初始化逻辑
class CustomLogger(logging.Logger):
    def __init__(self, name, level=logging.NOTSET):
        # 必须调用父类构造方法,否则会缺失原生Logger的核心属性
        super().__init__(name, level)
        self.foo = None

    def log(self, level, msg, *args, **kwargs):
        # 自定义日志逻辑
        apply_external_method(self.foo, msg)
        print(msg)
        # 如果需要保留原生logging的log功能,放开下面这行
        # super().log(level, msg, *args, **kwargs)

# 关键:在导入其他模块、第一次调用getLogger之前,注册自定义Logger类
logging.setLoggerClass(CustomLogger)

# 第一次实例化目标logger,此时生成的就是CustomLogger类型实例
logger = logging.getLogger('the_only_logger')
logger.foo = "foo"

# 等logger完全配置完成后,再导入其他项目文件
from additional import bar

if __name__ == "__main__":
    print("main里的logger类型:", type(logger))
    bar()

additional.py 写法

不需要额外修改,正常通过logging.getLogger获取即可,拿到的就是已经配置好foo属性的同一个CustomLogger实例:

# additional.py
import logging

logger = logging.getLogger('the_only_logger')

def bar():
    print("additional里的logger类型:", type(logger))
    print("logger.foo属性值:", logger.foo)
    logger.log(logging.INFO, "这是一条测试日志")

踩坑说明

  • 绝对不能在注册CustomLogger之前导入additional这类依赖目标logger的模块:导入模块时会立刻执行模块内的logging.getLogger('the_only_logger'),此时logging还没拿到自定义类,会默认生成原生Logger实例缓存起来,后续再调用getLogger拿到的都是这个原生实例,不会替换成CustomLogger。
  • 自定义Logger的__init__方法必须接收name、level两个位置参数,否则实例化时会直接抛参数不匹配的错误。
  • 重写log方法时尽量保持和父类方法签名一致,避免其他模块调用info、error等内置日志方法时出现参数报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 15:39:15