Python日志记录 - 仅用于文件处理程序的exc_info

时间:2011-05-30 14:28:15

标签: python logging

我为它定义了根记录器和处理程序:

_root = logging.getLogger()
_sh = logging.StreamHandler()
_fh = logging.FileHandler('./error.log', delay = True)
_root.addHandler(_sh)
_root.addHandler(_fh)

模块记录器实例:

_log = logging.getLogger("Main")
# In other file
_log = logging.getLogger("Configuration")

现在我在try..except块中调用_log.exception

_log.exception("Test")

现在我在控制台和文件中得到回溯。我尝试使用控制台处理程序禁止打印exc_info,但不使用文件处理程序:

class _TraceBackFilter(logging.Filter):
    def filter(self, rec):
        rec.exc_info = None
        return True
_sh = logging.StreamHandler()
_sh.addFilter(_TraceBackFilter())
_root.addHandler(_sh)

这适用于文件和控制台处理程序,所有处理程序都完全删除了回溯,但我只需要控制台。有没有办法只为控制台处理程序压缩exc_info,而不是文件处理程序?

修改

我修改了_TraceBackFilter类。

class _TraceBackFilter(logging.Filter):
    def filter(self, rec):
        if rec.exc_info:
            logging.getLogger(rec.name).log(rec.levelno, rec.getMessage())
            return False
        else:
            return True

现在它适用于控制台处理程序,但在文件中我有两个消息,一个有一个没有回溯。

2 个答案:

答案 0 :(得分:4)

为您的控制台处理程序创建一个logging.Formatter子类,该子类从其formatException方法返回一个空字符串。

异常文本缓存在记录中(在属性exc_text中):如果这是一个假值(例如空字符串),那么将调用formatException()来重新填充它,否则它会赢得'是的。因此,在格式化程序类中,您可能需要覆盖format()方法并在调用超类“record.exc_text方法之前将format()设置为false值,以确保覆盖的formatException()获取调用。例如(未测试):

class NoExceptionFormatter(logging.Formatter):
    def format(self, record):
        record.exc_text = '' # ensure formatException gets called
        return super(NoExceptionFormatter, self).format(record)

    def formatException(self, record):
        return ''

答案 1 :(得分:0)

如果首先使用该过滤器处理_sh处理程序,则看起来它可能正在修改实际的回溯对象。因为同一个traceback对象传递给_sh和_fh,所以_fh接收已经修改过的回溯。

您可以在该过滤器中创建一个新的traceback对象,也可以只删除exc_info,或者只是交换顺序,以便首先在_fh上调用addHandler。