go服务应根据告警类型选择通道:业务错误(如json解析失败)用sentry,基础设施事件(如cpu持续95%)用pagerduty v2 api;禁用已归档的pagerduty-go sdk,改用http.client直调https://events.pagerduty.com/v2/enqueue,需设content-type、authorization: token及routing_key,并通过event_action和payload.severity区分操作与级别。

Go服务该用 Sentry 还是 PagerDuty?先看告警类型
不是所有“异常”都适合走同一套通道。Sentry 专精于 error 和 panic 的上下文捕获与归因,PagerDuty 则面向运维事件(trigger/resolve/acknowledge),两者定位不同。如果你要上报的是 HTTP handler 里的 err != nil、数据库超时、JSON 解析失败这类业务错误,Sentry 是更直接的选择;如果目标是「服务不可达」「CPU 持续 95%」这类基础设施级事件,且已有 PagerDuty 运维流程,那就走 https://events.pagerduty.com/v2/enqueue。
sentry-go.Init() 必须放在 main() 最开头
这是 90% 部署后静默失败的根源。Sentry 的 panic 捕获依赖 recover() 和全局 handler 注册,一旦 goroutine 或 HTTP server 先于 Init 启动,那些崩溃就彻底丢失。
-
Init()要早于日志库初始化(比如 zap.New(...))、DB 连接、HTTP server.ListenAndServe() - 不要在
init()函数里调用它——包初始化阶段的 panic 不会被捕获 - 若用 gin/echo,中间件注册前必须确保
sentry.Init()已完成,否则中间件内 panic 不上报
HTTP 请求上下文不补全,Sentry 就只剩 GET /
默认的 sentry.HTTPIntegration 只带 method、url、status_code,没有 header、用户 ID、trace_id —— 所有错误看起来都一样,根本没法定位。
- 在 HTTP 中间件里调用
sentry.ConfigureScope(),手动塞关键字段:scope.SetTag("user_id", r.Header.Get("X-User-ID")) - 用
scope.SetExtra()补充trace_id、request_id等调试信息 - 绝对避免把 token、密码等敏感字段写进 scope —— Sentry 控制台默认可公开访问
PagerDuty v2 API 不认 github.com/PagerDuty/go-pagerduty
那个库名义上是官方维护,实则长期未更新,仍指向已下线的 v1 REST API,强行调用会返回 404 Not Found 或 401 Unauthorized(鉴权方式错)。
- 直接用
http.ClientPOST 到https://events.pagerduty.com/v2/enqueue - Header 必须含
Content-Type: application/json和Authorization: Token token=xxx(注意不是 Bearer) -
routing_key是 Integration Key,不是 API Key,需在 PagerDuty UI 创建「Events API v2」集成获取 -
event_action控制操作类型:"trigger"、"resolve"、"acknowledge",同一 endpoint 复用 - 级别靠
payload.severity控制:"critical"、"error"、"warning"、"info",不填默认"critical"
最易被忽略的其实是告警通道的「语义对齐」:Sentry 上报的是「这个 error 发生在哪次请求」,PagerDuty 接收的是「某个服务状态变更」,混用会导致告警泛滥或漏报。选一个主通道,另一个只做备份或特定场景补充。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











