Python2 Django应用:Sentry未捕获logging模块自身异常,如何处理?
问题
我们有一个基于Python 2的Django应用,目前仍在使用该版本。Sentry集成在其他场景下工作正常,但无法记录logging模块自身的崩溃——比如调用logger.info()时传入的格式化参数不足的情况。
问题示例代码:
logger.info('some info about %s and %s', my_thing)
这里缺少一个格式化参数,导致异常。
该异常的回溯信息能在Heroku日志中看到,但Sentry中没有任何记录:
Apr 27 23:35:32 xxx app/web.9 Traceback (most recent call last): Apr 27 23:35:32 xxx app/web.9 File "/usr/local/lib/python2.7/logging/__init__.py", line 868, in emit Apr 27 23:35:32 xxx app/web.9 msg = self.format(record) Apr 27 23:35:32 xxx app/web.9 File "/usr/local/lib/python2.7/logging/__init__.py", line 741, in format Apr 27 23:35:32 xxx app/web.9 return fmt.format(record) Apr 27 23:35:32 xxx app/web.9 File "/usr/local/lib/python2.7/logging/__init__.py", line 465, in format Apr 27 23:35:32 xxx app/web.9 record.message = record.getMessage() Apr 27 23:35:32 xxx app/web.9 File "/usr/local/lib/python2.7/logging/__init__.py", line 329, in getMessage Apr 27 23:35:32 xxx app/web.9 msg = msg % self.args Apr 27 23:35:32 xxx app/web.9 TypeError: not enough arguments for format string Apr 27 23:35:32 xxx app/web.9 Logged from file models.py, line 18407
请问是否需要额外配置,让sentry_sdk能够捕获logging模块运行时的相关异常?
解决方案
需要额外配置。Python 2的logging模块默认会在emit()方法内部捕获并打印异常,不会将异常抛出到外部,导致Sentry的默认集成无法捕获这类异常。你可以通过以下两种方式解决:
方法一:修改Sentry的Logging集成配置
在初始化Sentry时,配置logging集成的capture_errors参数,开启捕获日志处理过程中的错误:
import sentry_sdk from sentry_sdk.integrations.django import DjangoIntegration from sentry_sdk.integrations.logging import LoggingIntegration sentry_logging = LoggingIntegration( level=None, # 保留原有日志级别配置 event_level=None, # 保留原有事件级别配置 capture_errors=True # 开启捕获日志处理阶段的异常 ) sentry_sdk.init( dsn="你的Sentry DSN", integrations=[ DjangoIntegration(), sentry_logging ], # 其他原有配置项 )
方法二:自定义Logging Handler
如果方法一不生效,可以自定义一个Logging Handler,在emit()方法中手动将异常上报到Sentry:
import logging import sentry_sdk import traceback class SentryLoggingHandler(logging.Handler): def emit(self, record): try: super(SentryLoggingHandler, self).emit(record) except Exception as e: # 将日志处理异常上报到Sentry sentry_sdk.capture_exception(e) # 保留原有异常打印逻辑 traceback.print_exc() # 将自定义Handler添加到根logger root_logger = logging.getLogger() root_logger.addHandler(SentryLoggingHandler())
注意:由于你使用的是Python 2,需确保安装的sentry-sdk版本支持该环境,建议使用sentry-sdk==0.19.5(这是最后支持Python 2的版本)。
内容的提问来源于stack exchange,提问作者Jules Olléon
相关产品推荐
相关产品推荐

