题 如何记录python异常? [重复]


这个问题在这里已有答案:

如何在Python中记录异常?

我查看了一些选项,发现我可以使用以下代码访问实际的异常详细信息:

import sys
import traceback

try:
    1/0
except:
    exc_type, exc_value, exc_traceback = sys.exc_info()
    traceback.print_exception(exc_type, exc_value, exc_traceback)

我想以某种方式得到字符串 print_exception() 扔到标准输出,以便我可以记录它。


49
2017-12-22 11:46


起源


至少 raise (没有参数,因此stracktrace被保留)在记录之后,否则你会以静默方式吞下异常。
您应该始终明确说明您要捕获的异常: except NameError as e,说。这会阻止你捕捉像 KeyboardInterrupt  和 为您提供异常对象的引用,您可以学习更多详细信息。 - Katriel


答案:


要回答您的问题,您可以获得字符串版本 print_exception() 使用 traceback.format_exception() 功能。它将traceback消息作为字符串列表返回,而不是将其打印到stdout,因此您可以使用它执行所需的操作。例如:

import sys
import traceback

try:
    asdf
except NameError:
    exc_type, exc_value, exc_traceback = sys.exc_info()
    lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
    print ''.join('!! ' + line for line in lines)  # Log it or whatever here

这显示:

!! Traceback (most recent call last):
!!   File "<stdin>", line 2, in <module>
!! NameError: name 'asdf' is not defined

但是,我肯定建议使用标准的Python日志记录模块,如rlotun所建议的那样。这不是最简单的设置,但它可以自定义。


49
2017-12-22 14:32



“不是最简单的设置”,这意味着它是 硬 设置,但这不是真的, logging.basicConfig() 在主要功能中适用于大多数简单应用。 - SingleNegationElimination
当您无法使用日志包时,您的代码很有用。例如。实现日志记录处理程序时:-) - Doomsday
@Doomsday,我会想实现一个 logging.Handler 可能是这段代码的唯一好处。对于OP的原始问题,OP肯定会使用 记录 同 logging.exception 或登录较低级别 exc_info=True。 - KyleWpppd


看一眼 logging.exception (Python日志记录模块

import logging 
def foo():
    try:
        some_code()
    except:
        logging.exception('')

这应该自动处理获取当前异常的回溯并正确记录它。


95
2017-12-22 11:49



except 全能可能是一个坏主意: stackoverflow.com/a/4990739/1091116 - d33tah


记录异常就像将exc_info = True关键字参数添加到任何日志消息一样简单,请参阅Logger.debug中的条目 http://docs.python.org/2/library/logging.html

例:

try: 
    raise Exception('lala')
except Exception:
    logging.info('blah', exc_info=True)

输出(当然,取决于您的日志处理程序配置):

2012-11-29 10:18:12,778 - root - INFO - <ipython-input-27-5af852892344> : 3 - blah
Traceback (most recent call last):
  File "<ipython-input-27-5af852892344>", line 1, in <module>
    try: raise Exception('lala')
Exception: lala

43
2017-11-29 08:22



你需要付出很多努力。为什么不呢 logging.exception(exc)? - Chris Johnson
logging.exception是logging.error(...,exc_info = True)的缩写,因此如果您打算将异常记录为错误,最好使用logging.exception。如果要在除错误之外的日志级别记录格式化异常,则必须使用exc_info = True。 - NeilenMarais


在Python 3.5中,您可以在exc_info参数中传递异常实例:

import logging
try:
    1/0
except Exception as e:
   logging.error('Error at %s', 'division', exc_info=e)

7
2018-06-23 13:24





首先,考虑在except子句中使用适当的Exception类型。 然后,命名异常,您可以打印它:

try:
    1/0
except Exception as e:
    print e

根据您的Python版本,您必须使用

except Exception, e

5
2017-12-22 12:42



打印不记录。使用 logging.exception(exc)。 - Chris Johnson
@ChrisJohnson你推荐过 logging.exception(exc) 在本页的一些评论中,但这是一个坏主意。第一个参数 logging.exception 不是用于记录的异常(Python只是抓取当前的那个 except: 通过魔法阻止,它是为了 信息 在追溯之前记录。将异常指定为消息会导致将其转换为字符串,从而导致异常消息被复制。如果您没有有意义的消息来记录您的异常,请使用 logging.exception('')但是 logging.exception(exc) 没什么意义。 - Mark Amery