logger.exception
不显示堆栈跟踪,并且错误消息以arg形式传递。
设定:
import logging
from concurrent.futures import ThreadPoolExecutor
logger = logging.getLogger('custom')
ch = logging.StreamHandler()
logger.addHandler(ch)
logger.setLevel(logging.INFO)
executor = ThreadPoolExecutor(3)
不显示stacktrace:
try:
1/0
except Exception as e:
executor.submit(logger.exception, e)
显示stackTrace:
try:
1/0
except Exception as e:
executor.submit(logger.exception(e))
答案 0 :(得分:3)
此代码有效,因为在提交给线程池之前记录了该问题:
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,* args,** 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
将转换为字符串并用作记录回溯的消息。