如何用哨兵捕捉Python警告?

azm*_*euk 5 python warnings sentry

sentry_sdk哨兵文档解释了如何自动捕获异常或记录消息。但是,我怎样才能捕捉到 python 警告,比如DeprecationWarning会引发的警告

warnings.warn(DeprecationWarning, "warning message")
Run Code Online (Sandbox Code Playgroud)

Aar*_*ron 7

首先,我们告诉 python 将警告重定向到日志系统(如 Ahmed Hany 的回答中提到的)。来自: https: //docs.python.org/3/library/logging.html#logging.captureWarnings

logging.captureWarnings(capture)

如果 capture 为 True,警告模块发出的警告将被重定向到日志系统。

其次,Sentry 默认情况下会捕获错误级别的日志记录,但我们可以调整此行为以捕获警告。请参阅: https: //docs.sentry.io/platforms/python/guides/logging/

这是一个完整的示例(对于 django):

设置.py

import logging
import os
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration
from sentry_sdk.integrations.logging import LoggingIntegration

# Ensure that warnings are enabled
os.environ["PYTHONWARNINGS"] = "default"

# Ensure that logging captures warnings issued by warnings.warn()
logging.captureWarnings(True)

sentry_sdk.init(
    dsn="...",
    integrations=[
        LoggingIntegration(
            level = logging.INFO,           # Capture info and above as breadcrumbs (this is the default)
            event_level = logging.WARNING,  # Send warnings as events (default is logging.ERROR)
        ),
        DjangoIntegration(),
    ],
    ...
)
Run Code Online (Sandbox Code Playgroud)


Ahm*_*any 2

Sentry 中没有特定的 API 用于发送警告,但是,您需要确保使用您正在使用的通用日志记录基础设施来记录这些警告。

例如,如果您使用 Django,则必须在 settings.py 文件中将日志记录级别更改为警告,如下所示

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '%(asctime)s %(levelname)s [%(name)s:%(lineno)s] %(module)s %(process)d %(thread)d %(message)s'
        }
    },
    'handlers': {
        'console': {
            'level': 'WARNING',
            'class': 'logging.StreamHandler'
        },
    },
    'loggers': {
        "": {
            "level": "WARNING",
            'handlers': ['console'],
            "propagate": True
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

哨兵配置没有变化

import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration

sentry_config = {
    'dsn': os.getenv("SENTRY_DSN", "YOUR CDN"),
    'integrations': [DjangoIntegration()],
    # Set traces_sample_rate to 1.0 to capture 100%
    # of transactions for performance monitoring.
    # We recommend adjusting this value in production.
    'traces_sample_rate': 1.0,
    # If you wish to associate users to errors (assuming you are using
    # django.contrib.auth) you may enable sending PII data.
    'send_default_pii': True
}
sentry_sdk.init(**sentry_config)
Run Code Online (Sandbox Code Playgroud)

如果您没有日志记录基础设施,您可以实现自己的,请检查这个问题,它有很多关于如何创建自定义记录器的示例。

这就是将你的级别更改为 WARNING 并创建一个控制台处理程序(StreamHandler),然后 Sentry 将处理其余的事情

编辑:我的意思是捕获logging.warning(),但是为了你必须记录它们,Python 提供了模块与模块warnings.warn()之间的内置集成来让你做到这一点;只需在脚本或自定义记录器开始时调用,警告模块发出的所有警告将自动记录在“警告”级别。loggingwarningslogging.captureWarnings(True)