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

127572 次浏览

Take a look at logging.exception (Python Logging Module)

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

This should automatically take care of getting the traceback for the current exception and logging it properly.

First of all, consider using a proper Exception type on your except clause. Then, naming the exception, you can print it:

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

Dependending on your Python version, you must use

except Exception, e

To answer your question, you can get the string version of print_exception() using the traceback.format_exception() function. It returns the traceback message as a list of strings rather than printing it to stdout, so you can do what you want with it. For example:

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

This displays:

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

However, I'd definitely recommend using the standard Python logging module, as suggested by rlotun. It's not the easiest thing to set up, but it's very customizable.

Logging exceptions is as simple as adding the exc_info=True keyword argument to any log message, see entry for Logger.debug in http://docs.python.org/2/library/logging.html.

Example:

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

output (depending, of course, on your log handler config):

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

In Python 3.5 you can pass exception instance in exc_info argument:

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