logging.raiseExceptions = True不会重新引发异常 [英] logging.raiseExceptions = True does not re-raise an exception

查看:35
本文介绍了logging.raiseExceptions = True不会重新引发异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在代码中具有以下功能:

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

当前,我正在使用Python3 logging 模块,该模块(根据

相应的配置文件:

 #log.conf[记录员]键=根[处理人员]keys = consoleHandler[格式器]keys = consoleFormatter[logger_root]handlers = consoleHandler级别=调试[handler_consoleHandler]class = logging.StreamHandlerformatter = consoleFormatterargs = {sys.stdout,)[formatter_consoleFormatter]格式=%(文件名)s(%(lineno)d)%(级别名)-8s-%(消息)s 

这将产生以下输出:

  mwe.py(12)信息-已开始mwe.py(19)错误-糟糕.追溯(最近一次通话):文件mwe.py",第 16 行,在 <module> 中引发RuntimeError("Ooops.")RuntimeError:糟糕.mwe.py(24)信息-已完成 


为什么我不进入 GOTCHA 部分,尽管 raiseExceptions 的默认值是 True ,此外,我还将其设置为是真的?我的配置有什么问题?
还是我为此目的使用 logging 有一些误会?

(小问题:是否可以在 log.conf 文件中配置 raiseException 标志?)

您弄错了.这不会重新引发任何自定义异常.这是为了更改日志记录模块的默认行为,该行为会吞噬内部日志记录异常,即配置错误的记录器试图写入没有写入权限的文件.默认情况下,此操作将以静默方式失败,并且设置 logging.raiseException = True 将导致记录器配置错误或记录器模块内的任何其他问题,从而引发您必须处理的异常./p>

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

  try:引发RuntimeError("Ooops.")除了RuntimeError:logger.exception('哎呀.')增加 

I am trying to have the following functionality in my code:

  • Log info and error messages and also exceptions to console and/or a file, without interrupting the program flow (i.e., swallowing exceptions, some kind of Run Mode)
  • Get into Development Mode, where exceptions are raised, by setting a develop = True flag

Currently, I am using the Python3 logging module, which (according to this) should have exactly that functionality built-in. The flag is then logging.raiseExceptions = True.

However, I am not getting this to work in a MWE: the exception I am throwing does not get re-raised, whatever my setting of the flag is.

# 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')

The corresponding config file:

# 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

This produces the following output:

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


Why am I not getting to the GOTCHA part, although the default value of raiseExceptions is True and additionally I am also setting it to True? What is wrong with my configuration?
Or do I have some big misunderstanding about the use of logging for this purpose?

(Little bonus question: is there a way to configure the raiseException flag in the log.conf file?)

解决方案

You got it wrong. This will not re-raise any custom exception. This is meant to change the default behaviour of logging module which is swallowing internal logging exceptions i.e. misconfigured logger trying to write to a file where it has no permissions to write. This will fail silently by default and setting logging.raiseException = True will cause logger misconfiguration or any other problem within logging module to raise an exception which you would have to handle.

Now to the point of what you are trying to achieve. Having an exception traceback logged without suppressing the exception (letting it propagate) is the default behaviour. If logging is not configured the traceback goes to stderr. If logging is configured, it's written by logging handler to the desired location.
So basically in order to achieve your goal, you should not handle the exception at all. However if you know how to handle the exception (meaning you know what causes the exception) then normally you don't need a traceback to be logged.
If you insist you can still use logger.exception(...) inside your except RuntimeError clause and re-raise the exception with pure raise:

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

这篇关于logging.raiseExceptions = True不会重新引发异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆