是否应该在except块内调用logger.exception?为什么?

时间:2014-07-17 11:48:46

标签: python python-2.7 exception logging

logger.exception的文档提及:

  

只应从异常处理程序调用此方法。

所以用法应该是这样的:

try:
    errorerrorerror
except NameError as e:
    logger.exception('debug message %s', e)

但是当我尝试以“错误”的方式行事时,行为似乎是一样的:

try:
    errorerrorerror
except NameError as e:
    pass

logger.exception('debug message %s', e)

文档中提到的这个警告的原因是什么?是吗实际上是真的,我们只能在一个except块中使用它,因为一些微妙的原因在这里不明显?

2 个答案:

答案 0 :(得分:5)

该方法是设计的,用于异常处理程序。因此,文档告诉您这一点,通过使用应该这个词,而不是必须

在标准文本中,必须严格定义;一个意思是我们建议你这样做,如果你做的话要好得多,另一个意味着如果你不这样做,它就是一个彻头彻尾的错误。这样做。有关IETF工作组的措辞,请参阅RFC 2119

在调用logging.exception()之前,所有exc_info都会设置logging.error()关键字参数。然后,exc_info参数将被充实,以包含从sys.exc_info()获取的最近处理的异常。然后由格式化程序包含异常消息(通过Formatter.format_exception() method)来格式化异常。

由于sys.exc_info()适用于except套件和套件,因此两种变体都有效。从代码文档的角度来看,如果您在except处理程序中使用它,就会更清楚。

您确实不需要包含错误消息,因为您的日志格式化程序应该已经为您执行此操作:

logger.exception('debug message 2')  # exception should be included automatically

您可以使用以下命令将异常显式附加到任何日志消息:

logger.error('debug message 2', exc_info=sys.exc_info())

或具有异常类型,异常值和回溯的任何其他3元组值。或者,设置exc_info=1以让记录器从sys.exc_info()本身检索信息。

请参阅Logger.debug()的文档:

  

exc_info ,如果它没有评估为false,则会将异常信息添加到日志消息中。如果提供了异常元组(以sys.exc_info()返回的格式),则使用它;否则,调用sys.exc_info()来获取异常信息。

答案 1 :(得分:-1)

行为并不完全相同。该函数记录上次引发的异常,但仅在except块内,您可以确定此异常实际上是属于try块的except块中发生的异常。您的示例有始终发生的异常。在那个非常无用的角落情况下,如果在log.exception()区块内或之后进行except调用,那么这无关紧要。


两个例子来说明差异:

import logging
import random

try:
    if random.randint(0, 1) == 1:
        1 / 0
except:
    logging.exception()

import logging
import random

try:
    if random.randint(0, 1) == 1:
        1 / 0
except:
    pass

logging.exception()

在第一个代码中,ZeroDivisionError发生了50%的可能性,即记录的。在第二个代码中,异常发生的可能性相同,如果发生则记录。现在想想其他50%的运行会发生什么。