此代码的工作,因为被提交到线程池之前被记录的问题:
try:
1/0
except Exception as e:
executor.submit(logger.exception(e))
在现实中,你发送到线程池是什么None
。
这不起作用,因为有一点神奇的logger.exception调用发生,这不,当它的异常处理上下文之外(这当它在另一个线程的运行它会)工作:
try:
1/0
except Exception as e:
executor.submit(logger.exception, e)
它通常有助于检查文档。对于.exception()
method文档说:
在此记录器上记录级别为ERROR的消息。参数解释为debug()。异常信息被添加到日志消息中。该方法只能从异常处理程序调用。
为.debug()
文档的相关部分是:
logging.debug(MSG,*指定参数时,** kwargs)
日志与根记录器级别DEBUG的消息。 msg是消息格式字符串,args是使用字符串格式化运算符合并到msg中的参数。 (请注意,这意味着您可以使用格式字符串中的关键字以及单个字典参数。)
在被检查的kwargs中有三个关键字参数:exc_info,如果它不计算为false,则会导致将异常信息添加到日志消息中。如果提供了一个异常元组(以sys.exc_info()返回的格式),则使用它;否则,调用sys.exc_info()来获取异常信息。
所以,这条线:
executor.submit(logger.exception, e)
将调用原因sys.exc_info()
在线程处理的记录,其中有没有异常信息被称为 - 所以没有回溯记录。相反,你想:
executor.submit(logger.exception, "error occurred", exc_info=sys.exc_info())
所以在它的最终形式,它会是什么样子:
try:
1/0
except Exception as e:
executor.submit(logger.exception, "error occurred", exc_info=sys.exc_info())
更妙的是避免logger.exception()
电话而只使用logger.error()
代替:
try:
1/0
except Exception as e:
executor.submit(logger.error, "error occurred", exc_info=sys.exc_info())
如果您希望将异常消息作为日志消息,则可以执行此操作(类似于您在原始代码中执行的操作):
try:
1/0
except Exception as e:
executor.submit(logger.error, e, exc_info=sys.exc_info())
e
将被转换为字符串并用作记录回溯的消息。
新的线程意味着新的堆栈。 –
但是,如果像'logger.exception(e)' – garg10may
这样提交,它会起作用,因为你在调用'submit'前做了日志记录。它实际上会被记录调用的结果调用,AFAIR应该是'None'。 –