如何用哨兵捕获 python 警告?
How to catch python warnings with sentry?
使用 sentry_sdk
,哨兵文档解释了如何自动捕获异常或记录消息。但是,我怎样才能捕捉到 python 警告,比如 DeprecationWarning
会被
引发
warnings.warn(DeprecationWarning, "warning message")
如果异常:
try:
...
except Exception as exc:
sentry_sdk.capture_exception(exc)
如果消息:
sentry_sdk.capture_message("xxx")
在 Python 中,您可以通过不传递参数来捕获已捕获的异常或当前保存在 sys.exc_info() 中的异常:
from sentry_sdk import capture_exception
try:
a_potentially_failing_function()
except Exception as e:
# Alternatively the argument can be omitted
capture_exception(e)
另一个常见的操作是捕获裸消息。消息是应该发送给哨兵的文本信息。通常不会发出消息,但它们对某些团队很有用。
from sentry_sdk import capture_message
capture_message('Something went wrong')
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
}
}
}
哨兵配置没有变化
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)
如果您没有日志记录基础设施,您可以实现自己的,
检查这个 Question,它有很多关于如何创建自定义记录器的示例。
这就是将您的级别更改为 WARNING 并创建控制台处理程序(StreamHandler),然后 Sentry 将处理其余部分
编辑: 我本来打算捕获 logging.warning()
,但是对于 warnings.warn()
你必须记录它们,Python 提供了一个内置的logging
模块和 warnings
模块之间的集成让您可以做到这一点;只需在脚本或自定义记录器的开头调用 logging.captureWarnings(True)
,警告模块发出的所有警告将自动记录在警告级别。
首先,我们告诉 python 将警告重定向到日志系统(如 Ahmed Hany 的回答中所述)。来自:https://docs.python.org/3/library/logging.html#logging.captureWarnings
logging.captureWarnings(capture)
If capture is True, warnings issued by the warnings module will be redirected to the logging system.
其次,Sentry 默认会捕获 error-level 日志记录,但我们可以调整此行为以同时捕获警告。参见:https://docs.sentry.io/platforms/python/guides/logging/
这是一个完整的例子(对于 django):
settings.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(),
],
...
)
使用 sentry_sdk
,哨兵文档解释了如何自动捕获异常或记录消息。但是,我怎样才能捕捉到 python 警告,比如 DeprecationWarning
会被
warnings.warn(DeprecationWarning, "warning message")
如果异常:
try:
...
except Exception as exc:
sentry_sdk.capture_exception(exc)
如果消息:
sentry_sdk.capture_message("xxx")
在 Python 中,您可以通过不传递参数来捕获已捕获的异常或当前保存在 sys.exc_info() 中的异常:
from sentry_sdk import capture_exception
try:
a_potentially_failing_function()
except Exception as e:
# Alternatively the argument can be omitted
capture_exception(e)
另一个常见的操作是捕获裸消息。消息是应该发送给哨兵的文本信息。通常不会发出消息,但它们对某些团队很有用。
from sentry_sdk import capture_message
capture_message('Something went wrong')
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
}
}
}
哨兵配置没有变化
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)
如果您没有日志记录基础设施,您可以实现自己的, 检查这个 Question,它有很多关于如何创建自定义记录器的示例。
这就是将您的级别更改为 WARNING 并创建控制台处理程序(StreamHandler),然后 Sentry 将处理其余部分
编辑: 我本来打算捕获 logging.warning()
,但是对于 warnings.warn()
你必须记录它们,Python 提供了一个内置的logging
模块和 warnings
模块之间的集成让您可以做到这一点;只需在脚本或自定义记录器的开头调用 logging.captureWarnings(True)
,警告模块发出的所有警告将自动记录在警告级别。
首先,我们告诉 python 将警告重定向到日志系统(如 Ahmed Hany 的回答中所述)。来自:https://docs.python.org/3/library/logging.html#logging.captureWarnings
logging.captureWarnings(capture)
If capture is True, warnings issued by the warnings module will be redirected to the logging system.
其次,Sentry 默认会捕获 error-level 日志记录,但我们可以调整此行为以同时捕获警告。参见:https://docs.sentry.io/platforms/python/guides/logging/
这是一个完整的例子(对于 django):
settings.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(),
],
...
)