【问题标题】:Can I make Python output exceptions in one line / via logging?我可以在一行中/通过日志记录使 Python 输出异常吗?
【发布时间】:2018-07-16 11:06:14
【问题描述】:

我正在使用 AWS 并使用 AWS cloudwatch 查看日志。虽然事情不应该在 AWS 上中断,但它们可以。我刚遇到这样的情况。然后我搜索了Traceback,得到了这些台词

Traceback (most recent call last):

没有实际的回溯。我有一个有效的结构化日志记录设置(请参阅other question),我想以类似的方式获取回溯。

所以而不是:

Traceback (most recent call last):
  File "/home/math/Desktop/test.py", line 32, in <module>
    adf
NameError: name 'adf' is not defined

类似

{"message": "Traceback (most recent call last):\n      File \"/home/math/Desktop/test.py\", line 32, in <module>\n        adf\n    NameError: name 'adf' is not defined", "lineno": 35, "pathname": "/home/math/Desktop/test.py"}

或者甚至更好地使用 JSON 格式的字符串。

我能想到的唯一方法是一个巨大的 try-except 块。口袋妖怪风格。有没有更好的解决方案?

【问题讨论】:

  • 所以你不想尝试除了块,还想用格式化的方式记录错误?
  • 您应该使用自定义的logging.Formatter 并实现formatException
  • @ArpitSolanki 是的

标签: python logging traceback


【解决方案1】:

您可以使用sys.excepthook。每当您的脚本中发生异常时都会调用它。

import logging
import sys
import traceback

def exception_logging(exctype, value, tb):
    """
    Log exception by using the root logger.

    Parameters
    ----------
    exctype : type
    value : NameError
    tb : traceback
    """
    write_val = {'exception_type': str(exctype),
                 'message': str(traceback.format_tb(tb, 10))}
    logging.exception(str(write_val))

然后在您的脚本中,您必须覆盖 sys.excepthook 的值。

sys.excepthook = exception_logging

现在,无论何时发生异常,都会使用您的记录器处理程序进行记录。

注意:在运行之前不要忘记设置记录器

【讨论】:

  • 我正在用我的 django 应用程序尝试这个...知道在哪里放置它,代码方面吗?我正在尝试apps.pyAppConfig,使用ready() 覆盖sys.excepthook。如以下链接所示,日志记录设置得很早,所以,在准备好之前......但没有看,仍然有很多行......docs.djangoproject.com/en/3.0/ref/applications/…
【解决方案2】:

如果有人希望以默认格式记录异常,但在一行中(出于任何原因),基于接受的答案:

def exception_logging(exctype, value, tb):
    """
    Log exception in one line by using the root logger.

    Parameters
    ----------
    exctype : exception type
    value : seems to be the Exception object (with its message)
    tb : traceback
    """
    logging.error(''.join(traceback.format_exception(exctype, value, tb)))

还请注意,它使用 logging.error() 而不是 logging.exception(),它还会打印一些额外的“NoneType: None”行。
另请注意,它似乎只适用于未捕获的异常。
要记录捕获的异常,请访问 How do I can format exception stacktraces in Python logging? 并查看我的答案。

【讨论】:

    【解决方案3】:

    一个细微的变化:如果你运行一个 Flask 应用程序,你可以这样做:

    @app.errorhandler(Exception)
    def exception_logger(error):
        """Log the exception."""
        logger.exception(str(error))
        return str(error)
    

    【讨论】:

      猜你喜欢
      • 2011-10-23
      • 1970-01-01
      • 2020-12-31
      • 1970-01-01
      • 2017-01-31
      • 1970-01-01
      • 2014-03-31
      • 2014-12-14
      • 1970-01-01
      相关资源
      最近更新 更多