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

问题描述:

我为它定义根记录器和处理程序:Python记录 - exc_info仅用于文件处理程序

_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 

现在它的作品为控制台处理程序,但在文件中我已经加倍消息,一个和一个没有回溯。

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

将异常文本缓存在记录中(在属性exc_text中):如果这是一个错误值(例如空字符串),那么将调用formatException()来重新填充它,否则它将不会被重新填充。因此,在您的格式化程序类中,您可能需要覆盖format()方法,并在调用超类'format()方法之前将record.exc_text设置为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 '' 

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

您可以在该过滤器中创建一个新的回溯对象,使用exc_info,或者交换顺序,以便首先在_fh上调用addHandler。