子类化logging.Logger时,如何解决%(filename)插值显示错误文件的问题?
问题
自定义logging.Logger子类后,使用包含%(filename)s的日志格式时,输出的是子类所在文件(如custom_logger.py),而非调用日志函数的代码文件(如test.py)。需要无需大量重写Logger代码的简便解决方法。
原因
日志模块通过栈帧回溯获取filename、lineno等调用信息,默认会跳过logging模块内部的栈帧。但自定义的debug方法新增了一层栈帧,导致回溯时停在了自定义Logger的代码文件,而非实际调用位置。
解决方案
在调用父类的debug方法时,指定stacklevel=2,让日志模块跳过当前自定义方法的栈帧,找到真正的调用位置。
修改后的代码
custom_logger.py
import logging import io class CustomLogger(logging.Logger): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setLevel(logging.DEBUG) # 创建日志格式 formatter = logging.Formatter(fmt = "%(filename)s - %(message)s") # 创建处理器 self.stream = io.StringIO() handler = logging.StreamHandler(self.stream) handler.setFormatter(formatter) self.addHandler(handler) def debug(self, msg, *args, **kwargs): # 指定stacklevel=2,跳过当前方法的栈帧 super().debug(msg, *args, stacklevel=2, **kwargs) # 其他自定义逻辑 ...
test.py
from custom_logger import CustomLogger import logging logging.setLoggerClass(CustomLogger) myLog = logging.getLogger("myLog") myLog.debug("hello world") print(myLog.stream.getvalue())
验证
修改后运行test.py,输出将变为:
test.py - hello world
内容的提问来源于stack exchange,提问作者OmniZ
相关产品推荐
相关产品推荐

