logging.raiseExceptions = True不会重新引发异常

时间:2016-11-08 09:32:35

标签: python python-3.x logging

我想在我的代码中使用以下功能:

  • 记录信息和错误消息以及控制台和/或文件的例外情况,而不会中断程序流程(即吞咽异常,某种运行模式
  • 通过设置develop = True标记
  • 进入开发模式,引发异常

目前,我正在使用Python3 logging模块,该模块(根据this)应该具有内置的功能。然后该标志为logging.raiseExceptions = True

但是,我没有让它在MWE中工作:无论我的设置是什么,我抛出的异常都不会被重新提升。

# mwe.py
import logging
import logging.config

if __name__ == '__main__':
    # Configure logging and set flag to raise exceptions
    logging.config.fileConfig('log.conf')
    logging.raiseExceptions = True

    logger = logging.getLogger('root')

    logger.info('Started')

    # Test whether exceptions get raised
    try:
        raise RuntimeError("Ooops.")
    except RuntimeError:
        try:
            logger.exception('There was an oops.')
            # which is the same as logger.error('...', exc_info=True)
        except:
            print("GOTCHA! Exception was re-raised.")

    logger.info('Finished')

相应的配置文件

# log.conf
[loggers]
keys=root

[handlers]
keys=consoleHandler

[formatters]
keys=consoleFormatter

[logger_root]
handlers=consoleHandler
level=DEBUG

[handler_consoleHandler]
class=logging.StreamHandler
formatter=consoleFormatter
args=(sys.stdout,)

[formatter_consoleFormatter]
format=%(filename)s (%(lineno)d) %(levelname)-8s - %(message)s

这会产生以下输出

mwe.py (12) INFO     - Started
mwe.py (19) ERROR    - There was an oops.
Traceback (most recent call last):
  File "mwe.py", line 16, in <module>
    raise RuntimeError("Ooops.")
RuntimeError: Ooops.
mwe.py (24) INFO     - Finished

为什么我没有进入GOTCHA部分,虽然raiseExceptions的默认值为True,另外我也将其设为True?我的配置有什么问题?
或者我是否对logging用于此目的有一些很大的误解?

(小额奖励问题:有没有办法在raiseException文件中配置log.conf标志?)

1 个答案:

答案 0 :(得分:2)

你弄错了。这不会重新引发任何自定义异常。这是为了更改日志记录模块的默认行为,该模块吞噬内部日志记录异常,即错误配置的记录器尝试写入无权写入的文件。默认情况下,这将无提示失败,设置logging.raiseException = True将导致记录器配置错误或日志记录模块中的任何其他问题引发您必须处理的异常。

现在到了你想要实现的目标。记录异常回溯而不抑制异常(让它传播)是默认行为。如果未配置日志记录,则回溯将转至stderr。如果配置了日志记录,则由日志记录处理程序将其写入所需位置 所以基本上为了实现你的目标,你根本不应该处理异常。但是,如果您知道如何处理异常(意味着您知道导致异常的原因),那么通常您不需要记录回溯。
如果您坚持认为仍然可以在logger.exception(...)子句中使用except RuntimeError并使用纯raise重新引发例外:

try:
    raise RuntimeError("Ooops.")
except RuntimeError:
    logger.exception('There was an oops.')
    raise