如何记录python异常? [复制]

Posted

技术标签:

【中文标题】如何记录python异常? [复制]【英文标题】:How to log python exception? [duplicate] 【发布时间】:2011-05-29 08:58:58 【问题描述】:

如何在 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() 抛出到标准输出,以便我可以记录它。

【问题讨论】:

在记录后至少raise(没有参数,所以stracktrace被保留),否则你会默默地吞下异常。 您应该始终明确说明您要捕获的异常:except NameError as e,比如说。这将阻止您捕获诸如KeyboardInterrupt 之类的内容 为您提供对异常对象的引用,您可以研究它以获取更多详细信息。 【参考方案1】:

看看logging.exception(Python Logging Module)

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

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

【讨论】:

except catch-all 可能是个坏主意:***.com/a/4990739/1091116【参考方案2】:

要回答您的问题,您可以使用traceback.format_exception() 函数获取print_exception() 的字符串版本。它将回溯消息作为字符串列表返回,而不是将其打印到标准输出,因此您可以使用它做您想做的事情。例如:

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 所建议的那样。这不是最容易设置的东西,但它非常可定制。

【讨论】:

"不是最容易设置的东西"有点暗示设置它hard,但事实并非如此,主函数中的logging.basicConfig() 足以满足最简单的应用程序。 当您无法使用日志记录包时,您的代码很有用。例如。实现日志处理程序时:-) @Doomsday,我认为实现logging.Handler 可能是这段代码唯一的好用处。对于OP的原始问题,OP绝对应该使用logging和logging.exception或使用exc_info=True在较低级别登录。【参考方案3】:

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

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

【讨论】:

这正是我想要的。我需要记录 exception from a task 并且没有 except 块。【参考方案4】:

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

例子:

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

【讨论】:

你会付出很多努力。为什么不只是logging.exception(exc) logging.exception 是 logging.error(..., exc_info=True) 的缩写,因此如果您打算将异常记录为错误,最好使用 logging.exception。如果要在除错误之外的日志级别记录格式化异常,则必须使用 exc_info=True。 "显式优于隐式" @ChrisJohnson - 你可以简单地在你的例子中使用 logging.exception() ......此外,有完全合理的架构理由想要记录异常信息而不是将日志的 LEVEL 设置为 @ 987654326@。 logger.exception 是一个独特的案例,因为它是唯一没有将 LEVEL 明确设置为其函数名的调用。 logger.exception() 将级别设置为 ERROR。我们有与错误峰值相关的警报,尽管有些异常并不足以引发这些警报,但我们绝对希望为它们记录 exc_info。【参考方案5】:

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

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

取决于你的 Python 版本,你必须使用

except Exception, e

【讨论】:

打印不记录。使用logging.exception(exc) @ChrisJohnson 您已在此页面的几个 cmets 中推荐了 logging.exception(exc),但这是个坏主意。 logging.exception 的第一个参数不是为了记录异常(Python 只是通过魔法从当前的 except: 块中获取一个),而是为了在回溯之前记录 message。将异常指定为消息会导致将其转换为字符串,从而导致异常消息被复制。如果您没有有意义的消息与您的异常一起记录,请使用logging.exception(''),但logging.exception(exc) 没有什么意义。 这是这里最直白的代码。默认是有意义的消息。

以上是关于如何记录python异常? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python 中实现用户定义的异常? [复制]

每当有人尝试从 Python 中的特定文件夹复制任何文件时如何记录日志

java 自己定义异常,记录日志简单说明!留着以后真接复制

如何使用 Python 在日志文件中复制/捕获标准输出

Python小练:(五:异常处理)

为啥 Python 不使用“-> 类型”函数定义抛出类型异常? [复制]