未来的简单Python日志异常

cla*_*lay 5 python logging exception-handling exception

这应该是一个非常简单的问题,但在谷歌搜索,阅读文档和其他几个SO线程后,我没有看到答案:如何使用Python标准日志记录异常?一个小皱纹是我从未来获得例外.我except自己不是在编写异常处理程序.理想情况下,我会得到异常消息,堆栈跟踪,发送的额外消息,以及可能的异常类型.这是一个显示我的问题的简单程序:

import logging
from concurrent.futures import ThreadPoolExecutor

logger = logging.getLogger(__name__)


def test_f(a, b=-99, c=50):
    logger.info("test_f a={} b={} c={}".format(a, b, c))


def future_callback_error_logger(future):
    e = future.exception()
    if e is not None:
        # This log statement does not seem to do what I want.
        # It logs "Executor Exception" with no information about the exception.
        # I would like to see the exception type, message, and stack trace.
        logger.error("Executor Exception", exc_info=e)


def submit_with_log_on_error(executor, func, *args, **kwargs):
    future = executor.submit(func, *args, **kwargs)
    future.add_done_callback(future_callback_error_logger)


if __name__ == "__main__":
    logging.basicConfig(level="DEBUG")

    logger.info("start")
    executor = ThreadPoolExecutor(max_workers=5)

    # This will work.
    submit_with_log_on_error(executor, test_f, 10, c=20)
    # This will intentionally trigger an error due to too many arguments.
    # I would like that error to be properly logged.
    submit_with_log_on_error(executor, test_f, 10, 20, 30, 40)
    # This will work.
    submit_with_log_on_error(executor, test_f, 50, c=60)

    executor.shutdown(True)
    logger.info("shutdown")
Run Code Online (Sandbox Code Playgroud)

wim*_*wim 8

要使用logger.exception并获取回溯等,您需要在except块内.取而代之的检查future.exception(),它返回的异常(如果有的话),使用future.result()引发的异常(如果有的话).

所以,try相反(没有双关语):

def future_callback_error_logger(future):
    try:
        future.result()
    except Exception:
        logger.exception("Executor Exception")
Run Code Online (Sandbox Code Playgroud)

  • 文档的这一部分讨论的是*由回调本身*引起的任何异常(假设您编写了一个有错误的回调)。它不是谈论发送到线程池的工作代码引发的异常。所以,是的,还是有必要的! (2认同)