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块中使用它,因为一些微妙的原因在这里不明显?
答案 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%的运行会发生什么。