Python多模块日志无法输出正确源数据(文件名、函数名等)
解决自定义Log类中日志调用源信息错误的问题
问题根源在于自定义的Log.debug方法作为中间调用层,logging模块默认捕获的是该方法在logger.py中的调用位置,而非业务代码(module.py)里实际调用log.debug的位置。
解决方案(Python 3.8+ 推荐)
利用Python 3.8为logging模块新增的stacklevel参数,指定跳过当前中间层栈帧,直接获取业务代码的调用信息。
修改logger.py中的Log.debug方法:
def debug(self, msg): self.logger.debug(msg, stacklevel=2)
完整修改后的logger.py代码
import logging def get_module_logger(mod_name): logger = logging.getLogger(mod_name) handler = logging.StreamHandler() formatter = logging.Formatter( '%(asctime)s %(levelname)-8s %(message)s (%(filename)s:%(funcName)s:%(lineno)d)') handler.setFormatter(formatter) logger.addHandler(handler) logger.setLevel(logging.DEBUG) return logger class Log(): def __init__(self, logger): self.logger = logger def report(self, msg): print(f"some none-logger printing: {msg}") def debug(self, msg): self.logger.debug(msg, stacklevel=2)
兼容旧版本Python的解决方案
如果需要支持Python 3.8以下版本,可以手动获取正确的调用者信息,直接调用logger的底层_log方法:
修改logger.py中的Log.debug方法:
def debug(self, msg): # 获取真实调用者的文件、行号、函数名信息 fn, lno, func, _ = self.logger.findCaller(stack_info=False) # 调用底层日志方法传入正确的调用信息 self.logger._log( logging.DEBUG, msg, args=(), exc_info=None, extra=None, stack_info=False, fn=fn, lno=lno, func=func )
测试效果
运行module.py后,日志输出将符合预期:
2023-05-12 01:17:55,682 DEBUG -= MSG =- (module.py:my_func_1:5) some none-logger printing: RPT
内容的提问来源于stack exchange,提问作者ziGuy
相关产品推荐
相关产品推荐

