我可以通过日志记录在一行中输出 Python 异常吗?
Can I make Python output exceptions in one line / via logging?
我正在使用 AWS 并使用 AWS cloudwatch 查看日志。虽然事情不应该在 AWS 上崩溃,但它们可能会崩溃。我刚好有这样一个案例。然后我搜索 Traceback
并得到行
Traceback (most recent call last):
没有实际的回溯。我有一个有效的结构化日志记录设置(参见 ),我想以类似的方式获得回溯。
所以代替:
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 块。宠物小精灵风格。有更好的解决方案吗?
您可以使用 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
现在,无论何时发生异常,都会使用您的记录器处理程序进行记录。
注意:不要忘记在 运行 这个
之前设置记录器
如果有人希望以默认格式记录异常,但基于接受的答案(出于任何原因)在一行中:
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" 行。
另请注意,它似乎只适用于未捕获的异常。
要记录捕获的异常,请访问 并查看我的回答。
一个细微的变化:如果你运行一个 Flask 应用程序,你可以这样做:
@app.errorhandler(Exception)
def exception_logger(error):
"""Log the exception."""
logger.exception(str(error))
return str(error)
我正在使用 AWS 并使用 AWS cloudwatch 查看日志。虽然事情不应该在 AWS 上崩溃,但它们可能会崩溃。我刚好有这样一个案例。然后我搜索 Traceback
并得到行
Traceback (most recent call last):
没有实际的回溯。我有一个有效的结构化日志记录设置(参见
所以代替:
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 块。宠物小精灵风格。有更好的解决方案吗?
您可以使用 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
现在,无论何时发生异常,都会使用您的记录器处理程序进行记录。
注意:不要忘记在 运行 这个
之前设置记录器如果有人希望以默认格式记录异常,但基于接受的答案(出于任何原因)在一行中:
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" 行。
另请注意,它似乎只适用于未捕获的异常。
要记录捕获的异常,请访问
一个细微的变化:如果你运行一个 Flask 应用程序,你可以这样做:
@app.errorhandler(Exception)
def exception_logger(error):
"""Log the exception."""
logger.exception(str(error))
return str(error)