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

如何让日志记录调用函数名与文件名?自定义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模块机制:

  1. 重复调用logging.basicConfig的问题
    每次调用debug方法都执行basicConfig,这会反复覆盖根logger的配置,而且logging.debug()是调用根logger的方法,它记录的是调用logging.debug的位置(也就是Logger类的debug方法),而不是你实际调用self.logger.debug的位置。

  2. 正确的实现方式
    应该创建自定义的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:35:31