首页 > 解决方案 > 如果 python 日志处理程序引发异常会发生什么?

问题描述

如果日志处理程序失败会发生什么?

假设我们的日志配置是用一些日志处理程序定义的。有一种方法可以自定义这样的处理程序,因此我可以在任何处理程序的发出函数上定义任何操作。此外,假设其中一个处理程序引发了异常。问题是,不管怎样,剩下的那个的emit函数还是被触发了,或者有些会默默的失败。

一个可能的用例是使用预定义的SMTPHandler,但互联网被关闭。如果在范围内定义了 RotatingFileHandler,它会在这种情况下失败,或者处理程序的发射是独立发生的吗?

我看到该示例的三种可能情况:

  1. RotatingFileHandler 总是被触发,因为处理程序是独立处理的
  2. RotatingFileHandler 的失败按照处理程序的顺序随机发生
  3. 如果其中任何一个失败,则没有处理程序成功

标签: pythonlogginghandler

解决方案


Python 标准库处理程序的构建考虑了稳健性。如果在要求处理程序发出记录时引发异常,所有标准库实现都会捕获异常并调用Handler.handleError().

默认情况下,如果sys.stderr未设置为None,则调用Handler.handleError() 会重新引发异常。在您想要设置的生产系统logging.raiseExceptions = False中,此时异常会被静默忽略,并且日志记录会继续进行,就好像什么都没发生一样。

从文档中:

当调用过程中遇到异常时,应从处理程序调用此方法emit()。如果模块级属性raiseExceptionsFalse,异常会被静默忽略。这是日志系统最需要的——大多数用户不会关心日志系统中的错误,他们对应用程序错误更感兴趣。但是,如果您愿意,可以将其替换为自定义处理程序。指定的记录是发生异常时正在处理的记录。(默认值为,因为这在开发过程raiseExceptionsTrue更有用)。

因此,如果logging.raiseExceptions保留为默认值True,则取决于处理程序注册顺序首先调用哪个处理程序。在引发异常之前调用的任何处理程序都将成功。

如果logging.raiseExceptions已设置为False,则将调用所有处理程序,即使其中一个因异常而失败。


推荐阅读