如何记录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异常? [复制]的主要内容,如果未能解决你的问题,请参考以下文章