
Go 项目里怎么加 Sentry 初始化代码
直接在 main() 函数最开始调用 sentry.Init(),别等路由注册完、中间件加载完才初始化 —— 否则启动阶段 panic 就捕获不到。传参必须带 dsn,否则静默失败,连日志都不打。
-
dsn必须从环境变量读(比如os.Getenv("SENTRY_DSN")),硬编码进代码容易泄露或误提交 - 建议加
AttachStacktrace: true,Go 的 panic 默认不带完整栈,这个开关能补全 - 如果用的是
gin或echo,别只靠全局Init(),还得配对应中间件,否则 HTTP 请求异常不会自动上报 - 本地开发时设
Environment: "development",避免测试错误刷爆生产项目的 quota
HTTP handler 里 panic 为什么没进 Sentry
因为 Go 的 http.ServeMux 和大多数 Web 框架默认会 recover 并吞掉 panic,Sentry 来不及介入。你得主动把 panic 转成 Sentry event,或者用框架适配器。
- 对原生
net/http:用sentryhttp.New(sentryhttp.Options{Repanic: true})包一层 handler - 对
gin:必须用gin.Sentry()中间件(来自github.com/getsentry/sentry-go/gin),且要放在所有其他中间件之前 - 对
echo:用echo.WrapHandler(sentryecho.New(sentryecho.Options{})),不是直接Use()那个函数 - 手动上报时别用
sentry.CaptureException(err)传 nil,会 panic;先判空
自定义错误上下文怎么传给 Sentry
Sentry 默认只抓 panic 和 HTTP 状态,业务逻辑里的关键信息(如用户 ID、订单号、请求参数)得手动塞进去,不然查问题时全是黑盒。
- 用
sentry.ConfigureScope()+scope.SetTag()或scope.SetExtra(),注意它只影响后续上报,不是全局持久化 - 在 handler 开头就做:比如从 context 解出
userID,立刻sentry.ConfigureScope(func(scope *sentry.Scope) { scope.SetTag("user_id", userID) }) - 避免在 goroutine 里调
ConfigureScope()—— Scope 是绑定当前 goroutine 的,子协程改了也白改 - 敏感字段(密码、token)绝不能进
SetExtra(),Sentry 控制台可公开访问,tag 也尽量用脱敏后的哈希值
报错延迟高或根本收不到,可能卡在哪
Sentry SDK 默认异步发送事件,但底层用的是带缓冲的 channel,如果并发量大、网络卡、或 DSN 错了,event 会堆积然后丢弃,且不报错。
立即学习“go语言免费学习笔记(深入)”;
- 检查
sentry.Init()返回值:err != nil说明 DSN 格式非法或网络不通,但很多项目忽略这个 err - 加
BeforeSend: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event,在里面打日志,确认 event 是否生成成功 - 线上服务别用
Debug: true,它会强制同步发请求,压测时直接拖垮 QPS - 容器环境注意 DNS 解析超时,默认 30s,可设
Transport: &sentry.HTTPTransport{Timeout: 5 * time.Second}
最常被跳过的一步:没验证上报是否真生效。上线后故意触发一个带唯一 tag 的 panic(比如 if os.Getenv("TEST_SENTRY") == "1" { panic("test-sentry-2024") }),再盯 2 分钟控制台 —— 不亲眼看到 event 出现,就等于没接通。










