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

子类化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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 08:50:56