sentry_sdk.init()必须在应用启动最前头调用,以捕获早期异常;django需置于wsgi.py或manage.py开头,flask需在app创建后立即调用;异步任务需显式集成celeryintegration或rq包装;上下文丢失主因是未启用对应框架集成或未正确注入用户信息。

为什么 sentry_sdk.init() 必须在应用启动最前头调用?
Sentry 的 SDK 需要在任何可能抛出异常的代码执行前完成初始化,否则早期启动错误(比如配置加载失败、数据库连接异常)会被直接忽略。Django 或 Flask 启动时若在 sentry_sdk.init() 之前就触发了日志、中间件注册或模型导入,那些异常就进不了 Sentry。
- Django:必须放在
settings.py顶部,或更稳妥地放在manage.py或wsgi.py最开头(早于django.setup()) - Flask:在创建
Flask实例后、注册路由/扩展前立即调用 - 不要把它塞进某个视图函数或 lazy-init 的工具类里——那等于没接
import sentry_sdk from sentry_sdk.integrations.django import DjangoIntegration <p>sentry_sdk.init( dsn="<a href="https://www.php.cn/link/35856571321788e2cfb267bccef93f07">https://www.php.cn/link/35856571321788e2cfb267bccef93f07</a>", integrations=[DjangoIntegration()], traces_sample_rate=0.1, environment="production", )</p>
Django 中如何避免 DEBUG=True 时误发错误到 Sentry?
Sentry 默认不区分 DEBUG 状态,只要初始化了,DEBUG=True 下的本地报错也会上传。这不是你想要的——既污染数据,又可能泄露敏感路径或变量。
- 显式传入
environment并配合条件判断是最可靠方式 - 不要依赖
settings.DEBUG做开关(因为sentry_sdk.init()可能早于 settings 加载),而应从环境变量读取
推荐写法:
import os
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration
<p>if os.environ.get("SENTRY_DSN"):
sentry_sdk.init(
dsn=os.environ["SENTRY_DSN"],
integrations=[DjangoIntegration()],
environment=os.environ.get("ENVIRONMENT", "development"),</p><h1>development 环境默认不采样,production 才开</h1><pre class="brush:python;toolbar:false;"> traces_sample_rate=1.0 if os.environ.get("ENVIRONMENT") == "production" else 0.0,
)
如何让 Sentry 捕获异步任务(Celery / RQ)里的异常?
Celery worker 是独立进程,不会自动继承 Web 进程的 Sentry 配置。不额外集成的话,所有 task.apply_async() 抛出的异常都只会打日志,不会上报。
- Celery:必须显式添加
sentry_sdk.integrations.celery.CeleryIntegration - RQ:需手动 wrap
job.perform(),或使用rq-sentry这类轻量包装器
Celery 集成要点:
- 在 Celery app 创建后、task 导入前调用
sentry_sdk.init()(和 Web 进程一样) -
CeleryIntegration必须加入integrations=列表,否则 task 内部异常无法关联 trace - 确保
task acks_late=True,否则异常发生前任务已被标记为成功
为什么线上看到的错误堆栈总是缺 request 信息或用户 ID?
Sentry 默认只捕获异常本身,Web 请求上下文(如 URL、method、user、headers)需要靠框架集成自动注入。但常见疏漏会导致上下文丢失:
- Django:未启用
DjangoIntegration,或启用了但没加send_default_pii=True(注意:开启后可能上传邮箱、IP,需合规评估) - Flask:未用
FlaskIntegration,或用了但没在app实例上正确绑定(比如用工厂模式时 init_app 顺序错了) - 用户标识:需手动调用
sentry_sdk.set_user({"id": user.id, "email": user.email}),且必须在 request 生命周期内(例如 middleware 里),不能只在 login 视图里设一次
关键细节:
– send_default_pii=True 在生产环境慎用,建议改用 before_send 回调过滤敏感字段
– 如果用了 Nginx + Gunicorn,确保 X-Forwarded-For 和 X-Real-IP 被正确透传,否则 request.ip 会是内网地址
Sentry 的集成深度取决于你是否愿意花十分钟检查初始化时机、环境分支和上下文注入点——这些地方不难,但错一个,报错就静默消失。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











