如何让工具函数的日志显示为来自其调用方而非自身?
解决方案
要让工具函数里的日志显示调用方的module/funcName/lineno,核心是让日志模块跳过工具函数本身的栈帧,直接抓取上层调用者的信息。以下是几种实用方法:
方法一:用装饰器批量处理(符合你想要的@logAsCaller需求)
这个装饰器会临时修改日志的调用栈检测逻辑,让所有被装饰的工具函数输出日志时自动指向调用方:
import logging import functools def log_as_caller(func): @functools.wraps(func) def wrapper(*args, **kwargs): # 保存原始的findCaller方法 original_find_caller = logging.Logger.findCaller def modified_find_caller(self, stack_info=False, stacklevel=1): # 多跳一层栈帧,跳过当前工具函数 return original_find_caller(self, stack_info, stacklevel + 1) # 替换方法并执行原函数 logging.Logger.findCaller = modified_find_caller try: return func(*args, **kwargs) finally: # 恢复原方法,避免影响其他日志 logging.Logger.findCaller = original_find_caller return wrapper
使用示例
# 给工具函数加上装饰器 @log_as_caller def my_helper_fn(): logging.warning("这条日志会显示调用方的信息") def main(): my_helper_fn() # 日志里的funcName会是main,而非my_helper_fn if __name__ == "__main__": logformat = '%(asctime)s %(levelname)s %(module)s:%(funcName)s:%(lineno)d - %(message)s' logging.basicConfig(format=logformat, level=logging.WARNING) main()
方法二:自定义Logger全局生效
如果所有工具函数都需要这个特性,可以自定义Logger类,重写findCaller方法让它默认跳过一层栈帧:
import logging class CallerLogger(logging.Logger): def findCaller(self, stack_info=False, stacklevel=1): # 强制多跳一层,直接抓取调用方信息 return super().findCaller(stack_info, stacklevel + 1) # 替换默认的Logger类 logging.setLoggerClass(CallerLogger) # 初始化日志 logformat = '%(asctime)s %(levelname)s %(module)s:%(funcName)s:%(lineno)d - %(message)s' logging.basicConfig(format=logformat, level=logging.WARNING) # 工具函数直接用logging即可 def my_helper_fn(): logging.warning("这条日志会显示调用方的信息") def main(): my_helper_fn() if __name__ == "__main__": main()
方法三:手动指定stacklevel(最简单)
Python 3.8+的日志方法支持stacklevel参数,直接给日志调用加stacklevel=2,就能跳过当前工具函数的栈帧:
def my_helper_fn(): # stacklevel=2表示跳过当前函数,抓取调用方的栈信息 logging.warning("这条日志会显示调用方的信息", stacklevel=2) def main(): my_helper_fn() if __name__ == "__main__": logformat = '%(asctime)s %(levelname)s %(module)s:%(funcName)s:%(lineno)d - %(message)s' logging.basicConfig(format=logformat, level=logging.WARNING) main()
内容的提问来源于stack exchange,提问作者user2722968
相关产品推荐
相关产品推荐

