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
相关产品推荐
相关产品推荐

