Sentry在Python生产环境需正确初始化、配置采样率并注入上下文:init()须在框架实例创建后调用;sample_rate应设为1.0确保错误全量上报,traces_sample_rate按需设置;须在请求中间件等处手动注入用户ID、请求ID和SQL查询等业务上下文。

直接上结论:Sentry 在 Python 生产环境里不是“装上就完事”,关键在于 sentry_sdk.init() 的初始化时机、采样策略和上下文注入是否到位——漏掉任一环节,90% 的错误会静默丢失。
为什么 sentry_sdk.init() 不能放在模块顶层?
很多项目把初始化写在 main.py 或 settings.py 顶部,结果 Flask/FastAPI 启动前就执行了,导致后续中间件、日志处理器、异步任务(如 Celery)无法被自动捕获。Sentry 的自动集成依赖于框架的生命周期钩子,必须等框架实例创建完成后再调用 init()。
- Flask:在
create_app()函数末尾、app.run()前调用sentry_sdk.init() - FastAPI:在
app = FastAPI()之后立即初始化,不要等uvicorn.run() - Celery:需在每个 worker 进程中单独初始化,推荐在
celery.py的app.conf.on_after_configure回调里触发 - 避免在
__init__.py或导入时初始化——此时logging尚未配置,Sentry 自带的日志捕获器会失效
traces_sample_rate 和 sample_rate 到底怎么设才不丢关键错误?
这两个参数控制性能数据和错误事件的采样率,但作用对象不同:sample_rate 只影响异常上报,traces_sample_rate 控制全链路追踪(Span)是否生成。生产环境常见误配是把两者都设成 0.01,结果错误上报率极低,而追踪数据却占满配额。
- 错误必须 100% 上报:设
sample_rate=1.0(默认值),除非你明确做了before_send过滤 - 追踪按需开启:若只关心 API 错误路径,设
traces_sample_rate=0.05;若要分析慢请求,改用traces_sampler函数动态判断 - 注意
max_breadcrumbs=100是默认值,高频日志场景建议降到50,否则内存占用飙升
如何让 Sentry 显示真实的用户 ID、请求 ID 和数据库查询?
Sentry 默认只抓异常堆栈和基础环境信息,没有业务上下文就等于“知道病了,但不知道谁病、在哪病、怎么病的”。必须手动注入关键字段,且要注意线程/协程隔离。
立即学习“Python免费学习笔记(深入)”;
- 用户信息:在请求中间件里用
sentry_sdk.set_user({"id": user_id, "email": email}),别在全局 scope 设置 - 请求 ID:从
request.headers.get("X-Request-ID")提取后,用sentry_sdk.set_tag("request_id", rid) - SQL 查询:禁用
sqlalchemy自动集成(它会暴露敏感参数),改用with sentry_sdk.start_span(op="db", description="SELECT * FROM users"):手动包裹关键查询 - 异步任务(Celery):确保
task.request.id通过sentry_sdk.set_tag("celery_task_id", task.request.id)注入,否则任务失败无法关联
为什么 capture_exception() 有时不生效?
这不是 Sentry 的 bug,而是 Python 异常处理机制和 Sentry 捕获时机的错位。最典型的是:你在 try/except 里调用了 capture_exception(),但没 re-raise,导致外层框架(如 Flask)根本不知道发生了错误,自然不会触发其自带的错误处理流程。
- 正确做法:只在你想“吞掉但记录”的场景用
capture_exception(),并确保raise或返回错误响应 - 更稳妥的方式是依赖自动捕获——Sentry 的
flask或fastapi集成会在框架内部异常抛出时自动触发,无需手动调用 - 调试时加
debug=True参数,观察控制台是否打印Sentry is attempting to send...,没这条日志说明根本没触发上报 - 注意
sys.excepthook被其他库(如loguru)覆盖后,未捕获异常会绕过 Sentry——需显式调用sentry_sdk.excepthook
真正卡住人的从来不是 SDK 安装命令,而是异常发生时,那个本该出现在 Sentry Dashboard 里的 issue 却始终没出现——这时候要查的不是网络或 DSN,而是初始化位置、采样率、上下文注入时机,以及有没有人悄悄 patch 了 sys.excepthook。


















