Python日志输出方法名异常:始终显示logging:callHandlers:1706而非真实方法名
Python logging 显示内部方法名
logging:callHandlers:1706的解决办法 问题根源
你遇到的情况是因为日志格式中使用%(funcName)s时,默认的logging模块只会捕获当前栈帧的函数名。当日志请求经过logging内部的callHandlers方法(对应行号1706)时,栈帧指向了这个内部方法,导致业务代码的真实方法名被覆盖。
解决方案
方案一:自定义过滤器修正栈帧
通过自定义日志过滤器,跳过logging内部的调用栈,获取业务代码的真实方法名:
import logging import inspect class RealFuncFilter(logging.Filter): def filter(self, record): frame = inspect.currentframe() try: # 跳过logging内部调用栈,次数需根据你的代码结构调整 for _ in range(6): frame = frame.f_back if not frame: break if frame: record.funcName = frame.f_code.co_name record.lineno = frame.f_lineno finally: del frame # 避免内存泄漏 return True # 配置日志 logger = logging.getLogger(__name__) logger.addFilter(RealFuncFilter()) # 设置日志格式 formatter = logging.Formatter('[%(levelname)s] [%(asctime)s] [%(funcName)s] %(message)s') handler = logging.StreamHandler() handler.setFormatter(formatter) logger.addHandler(handler) logger.setLevel(logging.INFO) # 测试业务方法 def process_job(): logger.error("Deleting job task for: test_id") process_job()
注意:
range(6)的次数可能需要调整,你可以在循环中打印frame.f_code.co_name,找到业务方法名出现的位置,对应调整跳过的层数。
方案二:手动传入真实方法名
如果不想自定义过滤器,可以在日志调用时通过extra参数显式传入方法名:
import logging import inspect logger = logging.getLogger(__name__) formatter = logging.Formatter('[%(levelname)s] [%(asctime)s] [%(funcName)s] %(message)s') handler = logging.StreamHandler() handler.setFormatter(formatter) logger.addHandler(handler) logger.setLevel(logging.INFO) def process_job(): logger.error("Deleting job task for: test_id", extra={'funcName': inspect.currentframe().f_code.co_name}) process_job()
这种方式需要每个日志调用都手动添加,适合小范围场景使用。
额外注意事项
- 确保
logger = logging.getLogger(__name__)在模块级别定义,不要在函数内部重复创建,避免日志配置混乱。 - 如果使用异步代码(如asyncio),栈帧获取逻辑需要调整,可使用
inspect的异步栈帧API或专门的异步日志工具。
内容的提问来源于stack exchange,提问作者magnum87
相关产品推荐
相关产品推荐

