必须用sentry-sdk替代已弃用的raven,因其支持Python 3.11+及异步框架,安装命令为pip install sentry-sdk,需按框架添加可选依赖(如[django]),并在应用启动最开始调用sentry_sdk.init()初始化。

如何用 sentry-sdk 替代已弃用的 raven
直接装 raven 会出问题——它早在 2020 年就停止维护,且不兼容 Python 3.11+ 和现代异步框架。必须用官方推荐的 sentry-sdk,它支持 WSGI、ASGI、Celery、FastAPI、Django 等主流运行时。
安装命令是:pip install sentry-sdk。别漏掉可选依赖,比如用 FastAPI 就加 [fastapi],用 Django 就加 [django],否则某些上下文(如 request body、user info)可能抓不到。
- 初始化必须放在应用启动最开始的位置,比如
main.py或settings.py顶部,晚于其他 import 可能导致部分异常漏报 - Django 用户不要在
settings.py里只配SENTRY_DSN就以为完事——得显式调用sentry_sdk.init(),否则 SDK 不激活 - 本地开发时设
environment="development",避免测试日志刷爆 Sentry 项目配额
怎样让 Flask/FastAPI 自动捕获未处理异常
默认情况下,sentry-sdk 只捕获顶层未捕获异常(比如主线程崩溃),但 Web 框架通常会吞掉异常并返回 500 页面——这需要框架集成才能上报。
Flask:导入 flask 集成后,所有 500 错误自动上报,包括视图函数里抛出的 ValueError、KeyError:
立即学习“Python免费学习笔记(深入)”;
sentry_sdk.init(
dsn="https://xxx@o123456.ingest.sentry.io/123456",
integrations=[FlaskIntegration()],
)FastAPI:必须用 asgi 集成,且确保 app 是 ASGI 实例(即用 uvicorn 启动):
sentry_sdk.init(
dsn="https://xxx@o123456.ingest.sentry.io/123456",
integrations=[AsgiMiddleware(app)],
)- 别把
AsgiMiddleware当装饰器用在路由函数上——它要包装整个 app 实例 - 如果用了
ExceptionMiddleware自定义错误处理,Sentry 可能收不到原始异常;建议删掉自定义中间件,改用add_exception_handler注册 Sentry 的capture_exception - Flask 的
before_request里出错不会触发 Sentry——因为还没进视图,需手动sentry_sdk.capture_exception(e)
为什么有些异常没上报?排查 before_send 和采样率
常见假象是“明明崩了却没看到事件”——大概率被 before_send 过滤或采样掉了。SDK 默认开启 1.0(100%)采样,但生产环境常配 sample_rate=0.1,意味着 90% 的相同异常被丢弃。
更隐蔽的是 before_send 回调:有人为过滤 404、健康检查失败等非关键错误,但写错逻辑会导致全部拦截:
def before_send(event, hint):
if "404" in str(event.get("message", "")):
return None # ← 这里返回 None 就丢弃事件
return event- 检查
sentry_sdk.get_client().options["sample_rate"]运行时值,确认不是被覆盖成 0 -
before_send抛异常也会静默丢弃事件,务必加try/except包裹 - 异步任务(如 Celery)需单独 init,且必须传
enable_tracing=True才能链路追踪,否则只报顶层异常
怎么给 Sentry 事件附加用户、请求、标签等上下文
光有 traceback 不够定位问题。关键字段要手动塞:用户 ID、请求 URL、订单号、Git commit hash。这些不是自动带的,得靠 set_tag、set_user、set_context。
例如,在 FastAPI 的依赖函数里绑定当前用户:
@app.middleware("http")
async def add_sentry_context(request: Request, call_next):
sentry_sdk.set_user({"id": request.state.user_id})
sentry_sdk.set_tag("endpoint", request.url.path)
return await call_next(request)-
set_user接受{"id": "...", "email": "...", "username": "..."},只传id最安全,避免 GDPR 风险 - 敏感字段(如密码、token)绝不能进
set_extra——Sentry 默认记录所有变量值,可用before_send清洗event["extra"] - Django 中
request.POST默认不上传,要开send_default_pii=True,但生产环境慎用
真实线上环境里,最常被忽略的是异步任务的上下文隔离——一个 Celery worker 处理多个任务,set_tag 不自动清空,上次任务的 tag 会污染下一次。必须在任务开头重置,或用 with sentry_sdk.push_scope() 包裹。


















