我正在用logging.error将Python异常消息打印到日志文件:

import logging
try:
    1/0
except ZeroDivisionError as e:
    logging.error(e)  # ERROR:root:division by zero

是否可以打印有关异常和生成异常的代码的更详细信息,而不仅仅是异常字符串?行号或堆栈跟踪之类的东西会很棒。


当前回答

如果你看一下这个代码示例(适用于Python 2和3),你会看到下面可以提取的函数定义

方法 行号 代码的上下文 文件路径

对于整个堆栈跟踪,无论是否有异常:

def sentry_friendly_trace(get_last_exception=True):
    try:
        current_call = list(map(frame_trans, traceback.extract_stack()))
        alert_frame = current_call[-4]
        before_call = current_call[:-4]

        err_type, err, tb = sys.exc_info() if get_last_exception else (None, None, None)
        after_call = [alert_frame] if err_type is None else extract_all_sentry_frames_from_exception(tb)

        return before_call + after_call, err, alert_frame
    except:
        return None, None, None

当然,这个函数依赖于上面链接的整个要点,特别是extract_all_sentry_frames_from_exception()和frame_trans(),但是异常信息提取总共不到60行。

希望有帮助!

其他回答

我的方法是创建一个上下文管理器,记录并引发异常:

import logging
from contextlib import AbstractContextManager


class LogError(AbstractContextManager):

    def __init__(self, logger=None):
        self.logger = logger.name if isinstance(logger, logging.Logger) else logger

    def __exit__(self, exc_type, exc_value, traceback):
        if exc_value is not None:
            logging.getLogger(self.logger).exception(exc_value)


with LogError():
    1/0

您可以将记录器名称或记录器实例传递给LogError()。默认情况下,它将使用基本日志记录器(通过将None传递给logging.getLogger)。 还可以简单地添加一个开关来引发错误或只记录错误。

一个干净的方法是使用format_exc(),然后解析输出以获得相关部分:

from traceback import format_exc

try:
    1/0
except Exception:
    print 'the relevant part is: '+format_exc().split('\n')[-2]

问候

引用

如果您的应用程序以其他方式记录日志-不使用日志模块?

现在,traceback可以用在这里。

import traceback

def log_traceback(ex, ex_traceback=None):
    if ex_traceback is None:
        ex_traceback = ex.__traceback__
    tb_lines = [ line.rstrip('\n') for line in
                 traceback.format_exception(ex.__class__, ex, ex_traceback)]
    exception_logger.log(tb_lines)

在Python 2中使用它: 试一试: #你的函数调用在这里 Exception as ex: _, _, ex_traceback = sys.exc_info() ex_traceback log_traceback(例) 在Python 3中使用它: 试一试: X = get_number() Exception as ex: log_traceback(特异)

日志记录有一个好处。SiggyF的答案没有显示的异常是,你可以传递一个任意的消息,日志仍然会显示所有异常细节的完整跟踪:

import logging
try:
    1/0
except ZeroDivisionError:
    logging.exception("Deliberate divide by zero traceback")

默认情况下(在最近的版本中)只是将错误打印到sys. log行为。Stderr,它看起来像这样:

>>> import logging
>>> try:
...     1/0
... except ZeroDivisionError:
...     logging.exception("Deliberate divide by zero traceback")
... 
ERROR:root:Deliberate divide by zero traceback
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: integer division or modulo by zero

如果你可以处理额外的依赖,那么使用twisted.log,你不必显式地记录错误,而且它还会返回整个回溯和时间到文件或流。