如何让日志记录调用函数名与文件名?自定义Logger类日志问题
问题:自定义Logger类日志无法记录调用处的模块、函数名和行号?
我封装了一个Logger类用于记录日志,但发现日志里显示的模块、函数名和行号都是Logger类自身的信息,而不是实际调用日志方法的位置。
我的代码
Logger类实现:
import logging class Logger: def __init__(self, logfile): self.log_file = logfile def debug(self, message): logging.basicConfig(level=logging.DEBUG, format='%(asctime)-15s %(levelname)s %(module)s %(funcName)s %(lineno)d %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename=self.log_file, filemode='w') logging.debug(message)
在main函数中创建Logger实例,然后在另一个模块file1的类中使用:
# file1.py class SomeClass: def __init__(self, logger): self.logger = logger def is_path_valid(self, dc_path): self.logger.debug('Entering with parameter dc_path: %s' %(dc_path))
问题现象
实际日志输出:
Tue, 19 Mar 2019 05:41:15 DEBUG logger debug 14 Entering with parameter dc_path: /disks
期望的日志输出:
Tue, 19 Mar 2019 05:41:15 DEBUG file1 is_path_valid #line_number Entering with parameter dc_path: /disks
解决方案
这个问题的核心是你误用了Python的logging模块机制:
重复调用
logging.basicConfig的问题
每次调用debug方法都执行basicConfig,这会反复覆盖根logger的配置,而且logging.debug()是调用根logger的方法,它记录的是调用logging.debug的位置(也就是Logger类的debug方法),而不是你实际调用self.logger.debug的位置。正确的实现方式
应该创建自定义的logger实例,配置一次handler和formatter,然后通过这个实例来记录日志,这样才能捕获到实际调用处的上下文信息。
修改后的Logger类:
import logging class Logger: def __init__(self, logfile): # 创建自定义logger实例 self.logger = logging.getLogger("custom_logger") self.logger.setLevel(logging.DEBUG) # 避免重复添加handler(多次实例化Logger时不会重复创建) if not self.logger.handlers: # 定义日志格式 formatter = logging.Formatter( '%(asctime)-15s %(levelname)s %(module)s %(funcName)s %(lineno)d %(message)s', datefmt='%a, %d %b %Y %H:%M:%S' ) # 创建文件handler file_handler = logging.FileHandler(logfile, mode='w') file_handler.setFormatter(formatter) # 给logger添加handler self.logger.addHandler(file_handler) def debug(self, message): # 使用自定义logger实例的debug方法 self.logger.debug(message)
为什么这样能解决问题?
- 我们不再使用根logger的
logging.debug(),而是使用自定义logger实例的debug()方法。 - 当调用
self.logger.debug()时,logging模块会自动捕获调用这个方法的位置(也就是file1.py里的is_path_valid函数),从而正确记录模块名、函数名和行号。 - 把配置逻辑放在
__init__里且判断if not self.logger.handlers,避免了重复添加handler导致日志重复输出的问题。
这样修改后,你的日志就能按照预期显示实际调用处的上下文信息了。
内容的提问来源于stack exchange,提问作者xksyvone
相关产品推荐
相关产品推荐

