Sentry 是应用错误与异常监控工具,本文讨论它通过项目 Service Hook 把告警交给自建接收服务、再由该服务写入或关联 ONES 缺陷的方案设计。这是一套需要自行开发的对接方案,端到端写入尚未验证;Sentry 侧需先确认 servicehooks 功能与项目写权限,ONES 侧需按实际部署核对 API 版本、凭据类型与建单端点。
要点总览(TL;DR)
- 核心思路是让接收服务维护一张 Sentry 事件与 ONES 缺陷的关联记录表,以稳定的去重键判定是否同一异常:命中则追加评论与计数,未命中才调用 ONES 开放平台建单并回写缺陷 ID。
- 去重键建议以 Sentry 问题标识为主,异常类型、堆栈摘要、服务名作为辅助校验;主键命中但特征冲突时转人工复核,不直接合并。
- Sentry 项目 Service Hook 注册接口是已证实的厂商能力,但要求 servicehooks 功能与项目写权限,不能默认所有账户可用,注册前需核对租户功能与所选告警机制。
- ONES 侧通过开放平台 REST API v2 写入,认证使用 Bearer Token,凭据分个人 OAuth 与组织凭据;组织凭据文档标注 ONES 6.2.18 及以上,实施前需确认版本与授权范围。
- 端到端写入尚未验证,事件字段、CN 建单端点与重复告警合并策略需在联调阶段逐项确认,验收以重复告警不新建缺陷、评论正确追加、异常可追溯为准。
先定去重键:什么算“同一异常”
重复告警是否合并,取决于两次告警能否落到同一个稳定的键上。方案设计的第一步是选定去重键,并把它作为关联记录表的唯一约束,让接收服务在写入前就能判断“这条告警是否已经有对应的 ONES 缺陷”。
可用的键有三类,稳定性与冲突风险不同:
| 候选键 | 构成方式 | 稳定性 | 主要风险 |
|---|---|---|---|
| Sentry 事件标识 | 单次事件 ID | 低,每次告警都不同 | 无法用于跨告警合并,只能做幂等去重 |
| Sentry 问题标识 | 同一问题(issue)的标识 | 较高,同一问题内多次事件共享 | 问题被合并或拆分时键会变化,需核实规则 |
| 指纹或异常特征组合 | 指纹,或异常类型+堆栈摘要+服务名 | 取决于指纹配置 | 不同服务同名异常会撞键;堆栈轻微变化会分裂 |
建议以“Sentry 问题标识”为主键,把“异常类型+堆栈摘要+服务名”作为辅助校验字段:主键命中但辅助字段明显不一致时,转入人工复核而不是直接合并。事件标识单独存一列,用于防止同一条事件被重复投递时重复追加评论。
关联记录表建议包含以下字段:
| 字段 | 用途 | 约束 |
|---|---|---|
| 去重键 | 判定是否同一异常 | 唯一索引 |
| 辅助特征(异常类型、堆栈摘要、服务名) | 冲突校验 | 与去重键一同记录 |
| ONES 缺陷 ID | 指向已建缺陷 | 建单成功后回写,非空 |
| 最近事件标识 | 幂等判断 | 每次处理更新 |
| 首次事件时间、最近事件时间 | 判断复发与告警间隔 | — |
| 事件计数 | 反映重复程度 | 每次命中加一 |
| 关联状态 | 区分已关联、待复核、已拆分 | 枚举值 |
键的稳定性需要向 Sentry 侧核实:问题标识在问题合并、拆分、重新打开时是否保持不变,指纹的默认生成规则与自定义规则如何配置,以及所选告警机制实际投递哪些字段。这些属于实施前的核验缺口,不能按假设直接上线。
接收服务处理流程:查表、合并、建单、回写
接收服务是整套方案的中枢,职责是接收 Sentry 投递的事件、查关联表、按命中与否走不同分支,并把结果写回关联表。Sentry 提供项目 Service Hook 注册接口,可订阅文档指定事件;该接口要求 servicehooks 功能与项目写权限,不能默认所有账户都能使用,注册前需核对租户可用功能与所选告警机制。
每个分支的输入、动作与输出如下:
| 分支 | 输入 | 动作 | 输出 |
|---|---|---|---|
| 查表 | 事件载荷中的去重键与辅助特征 | 按唯一索引查询关联表 | 命中记录或空结果 |
| 命中且特征一致 | 已有记录、本次事件 | 向对应 ONES 缺陷追加评论或更新计数,不新建缺陷 | 缺陷下新增一条事件记录,关联表计数与最近时间更新 |
| 命中但特征冲突 | 已有记录、冲突字段 | 标记待复核,暂停自动写入 | 复核任务,关联状态改为待复核 |
| 未命中 | 事件载荷 | 调用 ONES 开放平台创建缺陷,成功后回写缺陷 ID 与去重键 | 新缺陷与一条关联记录 |
| 写入失败 | 失败原因 | 进入重试队列,保持关联表未完成状态 | 补偿任务,避免重复建单 |
ONES 侧通过开放平台 REST API v2 完成建单与评论写入,目标租户需支持对应 API 版本。认证使用 Bearer Token,接口路径示例为 /openapi/v2/,这只是路径前缀,不是创建工作项的完整地址,具体端点须按目标部署文档核对。凭据分个人 OAuth 凭据与组织凭据两类,二者代表的身份与作用范围不同;组织凭据能力在文档中标为 ONES 6.2.18 及以上,实施前需确认实际版本、管理角色与授权范围。
凭据管理有三条容易踩空的条件:个人 Token 刷新会产生新的访问与刷新令牌、旧令牌失效,接收服务必须保存并使用新令牌;改变凭据 Scope 不会自动改变已发出的 Token,需重新授权使新范围生效;国内开放平台入口与 COM 文档体系不能仅凭名称视为同一套接口契约,HTTP 路径、参数与返回值都要按目标部署验证。服务账号建议使用组织凭据,避免个人离职或改密导致集成中断。
角色分工与人工复核规则
自动化只处理特征一致的重复告警,边界情况交给明确的人。角色划分建议如下:
| 角色 | 主要动作 | 交付物 |
|---|---|---|
| 集成负责人 | 维护接收服务、关联表结构与凭据,处理重试与补偿 | 可用的接收服务、关联表变更记录 |
| 值班研发 | 处理待复核任务,判断是否同一问题 | 复核结论:合并、拆分或新建 |
| 缺陷负责人 | 在 ONES 缺陷中跟进修复,确认关闭条件 | 缺陷状态与修复记录 |
以下情况应触发人工复核:去重键命中但辅助特征不一致;不同服务出现同名异常,指纹可能撞键;缺陷已关闭后同一异常再次出现;Sentry 侧问题被合并或拆分导致键变化。复核结论需要回写关联表:判定为同一问题则恢复关联状态并继续追加;判定为不同问题则新建缺陷,并在原记录上标注拆分关系。
合并与拆分都要留痕,至少记录操作人、时间、依据的事件标识与结论,便于事后追溯为什么某次告警没有建单。留痕写在关联表或独立的操作日志中,不依赖聊天记录。
示例:一次重复告警的完整走向
假设订单服务在 10:00 首次抛出空指针异常,Sentry 生成问题 P1 并投递事件 E1。接收服务查表未命中,调用 ONES 开放平台创建缺陷 BUG-101,回写关联记录:去重键 P1、缺陷 BUG-101、计数 1、状态已关联。值班研发在 BUG-101 中开始排查。
10:40 同一异常再次触发,事件 E2 到达。接收服务按 P1 查表命中,辅助特征与记录一致,于是向 BUG-101 追加一条评论,注明事件时间与次数,关联表计数变为 2、最近事件时间更新为 10:40,不新建缺陷。
若 BUG-101 在 11:30 被关闭,12:10 该异常复现,接收服务仍会命中 P1。此时按复核规则不直接追加,而是生成复核任务:值班研发确认是修复未生效还是新引入的同类问题,前者重新打开 BUG-101 并恢复关联,后者新建缺陷并把原记录标记为拆分。
这个示例中,Service Hook 注册与事件投递属于已证实的厂商能力,但事件字段是否包含所需的问题标识与指纹、ONES 建单与评论端点的具体参数、以及重复告警在 Sentry 侧是否已被合并,都属于待验证假设,需在联调阶段逐项确认。
上线前检查与验收标准
上线前按三侧逐项核对,每项都要有明确的通过标志:
| 检查项 | 核对内容 | 通过标准 |
|---|---|---|
| Sentry 功能 | 租户是否具备 servicehooks 功能与项目写权限 | 能成功注册 Service Hook 并收到测试事件 |
| Sentry 告警机制 | 实际可用的告警机制、投递字段、重复告警合并策略 | 测试事件包含去重键所需字段 |
| ONES API | API 版本、CN 部署端点、建单与评论接口 | 测试租户中能成功建单并追加评论 |
| ONES 凭据 | 凭据类型、Scope、版本是否满足组织凭据要求 | 授权范围覆盖建单与评论,Token 刷新后可继续调用 |
| 关联表 | 去重键唯一约束、幂等写入、失败重试与补偿 | 重复投递同一事件不产生第二条记录 |
验收以行为结果为准:同一异常连续触发三次,ONES 中只有一个缺陷且评论按序追加;模拟建单接口超时后重试,不出现重复缺陷;缺陷关闭后异常复现,能进入复核流程并留下记录;从任一缺陷可回溯到对应的 Sentry 问题与事件。全部通过后再切换正式告警,并保留一段并行观察期。
常见问题
Sentry 的问题标识在问题被合并或拆分后还能继续用作去重键吗?
这需要在实施前向 Sentry 侧核实。问题标识在同一问题内多次事件之间共享,稳定性高于单次事件 ID,但问题合并、拆分或重新打开时键是否保持不变,资料中没有给出结论。方案上建议把问题标识作为主键、把异常类型与堆栈摘要作为辅助校验字段,一旦发现主键命中而辅助特征明显不一致,就转入人工复核,避免把两个不同问题错误合并到同一 ONES 缺陷。
接收服务调用 ONES 建单超时后重试,会不会产生重复缺陷?
这取决于关联表的写入顺序与幂等设计。建议先以去重键写入一条“处理中”记录并加唯一约束,再调用 ONES 建单,成功后回写缺陷 ID;若建单超时,记录保持未完成状态进入重试队列,重试前先查该键是否已有缺陷 ID,避免重复建单。同一事件被重复投递时,用最近事件标识做幂等判断,不重复追加评论。这些属于自建方案的设计要求,端到端行为需在测试租户中验证。
个人 OAuth 凭据和组织凭据在长期运行的接收服务里怎么选?
开放平台文档区分个人 OAuth 凭据和组织凭据,二者代表的身份与作用范围不同。个人 Token 刷新会产生新的访问与刷新令牌、旧令牌失效,接收服务必须保存并使用新令牌;改变凭据 Scope 不会自动改变已发出的 Token,需重新授权使新范围生效。组织凭据能力在文档中标为 ONES 6.2.18 及以上,实施前需确认实际版本、管理角色与授权范围。长期运行的服务账号建议评估组织凭据,减少个人离职或改密带来的中断风险。
缺陷已关闭后同一异常再次出现,应该重新打开还是新建缺陷?
建议交给人工复核判断,不直接自动追加。值班研发需要确认是原修复未生效还是新引入的同类问题:前者重新打开原缺陷并恢复关联状态,后者新建缺陷并把原关联记录标记为拆分。两种结论都要回写关联表并留下操作人、时间与依据的事件标识,便于事后追溯为什么某次告警没有建单。
上线前最容易被忽略的核对项是什么?
常见缺口在两端接口契约的匹配上。Sentry 侧要确认租户是否具备 servicehooks 功能与项目写权限,以及所选告警机制实际投递哪些字段;ONES 侧要按目标部署核对 API 版本、CN 端点与凭据 Scope。国内开放平台入口与 COM 文档体系不能仅凭名称视为同一套接口契约,HTTP 路径、参数与返回值都要按目标部署文档验证,接口路径示例 /openapi/v2/ 只是前缀,不是创建工作项的完整地址。
官方参考资料
- Register a New Service Hook(Sentry)
- ONES Open API v2(ONES)
- Open API Authentication And Authorization(ONES)
