简体   繁体   English

如果 python 日志处理程序引发异常会发生什么?

[英]What happens if a python logging handler raises an exception?

What happens if a logging handler fails?如果日志处理程序失败会发生什么?

Assume our logging configuration is defined with some logging handlers.假设我们的日志配置是用一些日志处理程序定义的。 There is a way to customize such a handler, so I can define any operation on the emit function of any handler.有一种方法可以自定义这样的处理程序,因此我可以在任何处理程序的发出 function 上定义任何操作。 Assume furthermore, that one of the handler raises an exception.此外,假设其中一个处理程序引发了异常。 The question is that, no matter what, the remaining ones' emit function is still triggered, or some will silently fail.问题是,不管怎样,其余的 emit function 仍然被触发,或者一些会默默地失败。

A possible use case would be to use the predefined SMTPHandler , but with the internet being shut down.一个可能的用例是使用预定义的SMTPHandler ,但互联网被关闭。 If a RotatingFileHandler is defined in the scope, can it fail in that case, or the emitting of the handlers happen independently?如果在 scope 中定义了 RotatingFileHandler,它会在这种情况下失败,或者处理程序的发射是独立发生的吗?

I see three possible cases for the example:我看到该示例的三种可能情况:

  1. The RotatingFileHandler always trigerred, as the handlers are treated independently RotatingFileHandler 总是被触发,因为处理程序是独立处理的
  2. The failure of the RotatingFileHandler happens randomly, by the order of the handlers RotatingFileHandler 的失败按照处理程序的顺序随机发生
  3. No handler suceeds if any of them fails如果其中任何一个失败,则没有处理程序成功

The Python standard-library handlers have been built with robustness in mind. Python 标准库处理程序在构建时考虑了稳健性。 If an exception is raised while a handler is asked to emit a record, all standard library implementations catch the exception and instead call Handler.handleError() .如果在要求处理程序发出记录时引发异常,所有标准库实现都会捕获异常并调用Handler.handleError()

By default, and if sys.stderr is not set to None , calling Handler.handleError() re-raises the exception .默认情况下,如果sys.stderr未设置为None ,则调用Handler.handleError()会重新引发异常 In production systems you want to set logging.raiseExceptions = False , at which point the exceptions are silently ignored, and logging continues as if nothing happened.在生产系统中,您要设置logging.raiseExceptions = False ,此时异常会被静默忽略,并且日志记录会继续进行,就好像什么都没发生一样。

From the documentation:从文档中:

This method should be called from handlers when an exception is encountered during an emit() call.当在emit()调用期间遇到异常时,应该从处理程序调用此方法。 If the module-level attribute raiseExceptions is False , exceptions get silently ignored.如果模块级属性raiseExceptionsFalse ,异常会被忽略。 This is what is mostly wanted for a logging system - most users will not care about errors in the logging system, they are more interested in application errors.这是日志系统最需要的——大多数用户不会关心日志系统中的错误,他们对应用程序错误更感兴趣。 You could, however, replace this with a custom handler if you wish.但是,如果您愿意,可以将其替换为自定义处理程序。 The specified record is the one which was being processed when the exception occurred.指定的记录是发生异常时正在处理的记录。 (The default value of raiseExceptions is True , as that is more useful during development). raiseExceptions的默认值为True ,因为这在开发过程中更有用)。

So if logging.raiseExceptions is left to the default True , then it depends on the handler registration order which handler is called first.因此,如果将logging.raiseExceptions保留为默认值True ,则取决于处理程序注册顺序首先调用哪个处理程序。 Any handlers called before an exception is raised will have succeeded.在引发异常之前调用的任何处理程序都将成功。

If logging.raiseExceptions has been set to False , all handlers will be called, even if one of them fails with an exception.如果logging.raiseExceptions已设置为False ,则将调用所有处理程序,即使其中一个因异常而失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM