如何通过日志模块而不是stderr导致未捕获的异常输出?

我意识到最好的办法是:

try:
    raise Exception, 'Throwing a boring exception'
except Exception, e:
    logging.exception(e)

但我的情况是,如果在没有捕获异常时自动调用logging.exception(…),那就太好了。


当前回答

方法sys。如果异常未被捕获,将调用Excepthook: http://docs.python.org/library/sys.html#sys.excepthook

当异常被引发并未被捕获时,解释器调用sys. js。Excepthook包含三个参数,异常类、异常实例和一个回溯对象。在交互式会话中,这发生在控制返回到提示符之前;在Python程序中,这发生在程序退出之前。这种顶级异常的处理可以通过给sys.excepthook分配另一个三个参数的函数来定制。

其他回答

为什么不:

import sys
import logging
import traceback

def log_except_hook(*exc_info):
    text = "".join(traceback.format_exception(*exc_info()))
    logging.error("Unhandled exception: %s", text)

sys.excepthook = log_except_hook

None()

下面是使用sys的输出。如上图所示:

$ python tb.py
ERROR:root:Unhandled exception: Traceback (most recent call last):
  File "tb.py", line 11, in <module>
    None()
TypeError: 'NoneType' object is not callable

下面是使用sys. js的输出。但是thook评论道:

$ python tb.py
Traceback (most recent call last):
  File "tb.py", line 11, in <module>
    None()
TypeError: 'NoneType' object is not callable

唯一的区别是前者在第一行的开头有ERROR:root:Unhandled异常。

方法sys。如果异常未被捕获,将调用Excepthook: http://docs.python.org/library/sys.html#sys.excepthook

当异常被引发并未被捕获时,解释器调用sys. js。Excepthook包含三个参数,异常类、异常实例和一个回溯对象。在交互式会话中,这发生在控制返回到提示符之前;在Python程序中,这发生在程序退出之前。这种顶级异常的处理可以通过给sys.excepthook分配另一个三个参数的函数来定制。

在我的情况下(使用python 3),当使用@Jacinda的答案时,跟踪的内容没有打印。相反,它只打印对象本身:<traceback object at 0x7f90299b7b90>。

相反,我这样做:

import sys
import logging
import traceback

def custom_excepthook(exc_type, exc_value, exc_traceback):
    # Do not print exception when user cancels the program
    if issubclass(exc_type, KeyboardInterrupt):
        sys.__excepthook__(exc_type, exc_value, exc_traceback)
        return

    logging.error("An uncaught exception occurred:")
    logging.error("Type: %s", exc_type)
    logging.error("Value: %s", exc_value)

    if exc_traceback:
        format_exception = traceback.format_tb(exc_traceback)
        for line in format_exception:
            logging.error(repr(line))

sys.excepthook = custom_excepthook

包装你的应用程序入口调用在一个尝试…Except块,这样您就能够捕获和记录(可能还会重新引发)所有未捕获的异常。例如:

if __name__ == '__main__':
    main()

这样做:

if __name__ == '__main__':
    try:
        main()
    except Exception as e:
        logger.exception(e)
        raise

以Jacinda的回答为基础,但使用记录器对象:

def catchException(logger, typ, value, traceback):
    logger.critical("My Error Information")
    logger.critical("Type: %s" % typ)
    logger.critical("Value: %s" % value)
    logger.critical("Traceback: %s" % traceback)

# Use a partially applied function
func = lambda typ, value, traceback: catchException(logger, typ, value, traceback)
sys.excepthook = func