首页
/ agent-skills 可观测性清单解析:从 On-Call 问题出发构建结构化日志、RED/USE 指标与症状驱动告警

agent-skills 可观测性清单解析:从 On-Call 问题出发构建结构化日志、RED/USE 指标与症状驱动告警

2026-09-05 11:48:29作者:史锋燃Gardner

本篇以 agent-skills 仓库中的 references/observability-checklist.md 为主体,系统拆解这份生产环境遥测(Telemetry)核查清单的完整脉络:如何从 On-Call 问题定义信号、如何用结构化日志与 RED/USE 指标避免基数爆炸、如何用 OpenTelemetry 打通分布式追踪、如何用"症状驱动"告警替代"原因驱动"告警,以及功能上线前必须通过的遥测门禁(Pre-Launch Gate)。读完本文,你将掌握一套可直接用于生产功能开发的埋点核查流程,并理解该清单在 agent-skills 技能体系中的定位与配套技能 observability-and-instrumentation 的协作方式。

一、清单定位:技能包里的"速查参考"层

agent-skills 是一个面向 AI 编码代理的工程技能包,其目录结构遵循"渐进式披露(Progressive disclosure)"设计:skills/ 下每个技能以 SKILL.md 为入口,而 references/ 目录存放 7 份补充性核查清单,供技能在需要时按需加载,以最小化 token 消耗(见 README.md 的 "How Skills Work" 一节)。

observability-checklist.md 在其中承担"速查版"角色。其开篇即声明:

Quick reference for instrumenting production code. Use alongside the observability-and-instrumentation skill.

skills/observability-and-instrumentation/SKILL.md 的结尾(Verification 一节之后),也有反向引用:"For the at-a-glance version of this list, including the pre-launch instrumentation gate, see ../../references/observability-checklist.md."。也就是说,技能文档负责完整的七步流程与反合理化论证(Rationalizations / Red Flags),而本清单浓缩为可直接逐项打勾的核查条目,并在技能基础上额外提供了"仪表盘(Dashboards)"与"上线前门禁(Pre-Launch Gate)"两个独立小节。README.md 的 Reference Checklists 表格对它的概括是:"On-call questions, structured logging, RED/USE metrics, tracing, symptom-based alerting, pre-launch gate"。

二、从 On-Call 问题出发:给遥测定义用途

清单第一个小节是 "On-Call Questions (Start Here)",核心论断是:"Telemetry without a question is noise"(没有问题的遥测就是噪声)。在动手埋点之前,需满足三个条目:

  • [ ] 写下 2–4 个 On-Call 工程师会针对该功能提出的问题;
  • [ ] 下文每一类信号都必须映射到这些问题之一;
  • [ ] 每个问题匹配到正确的信号类型:指标告诉你"有什么问题"(metrics say that something is wrong),追踪告诉你"哪里出问题"(traces say where),日志告诉你"为什么"(logs say why)。

仓库中的评测夹具 evals/fixtures/observability-and-instrumentation/operations.md 给出了这个环节的落地范例——"支付重试"功能的 On-Call 问题清单:

  • 重试是否成功恢复了网关的瞬时故障?
  • 哪个网关、哪类失败在导致重试耗尽?
  • 是否存在同一笔支付被重复扣款?
  • 哪些客户可见的支付现在需要人工介入?

该夹具同时划定了敏感数据边界:支付 ID 与尝试 ID 是安全的关联标识符,而卡号、客户邮箱、网关原始响应严禁入日志。这与清单在结构化日志一节中引用的 security-and-hardening 硬性规则相互印证(对应技能 skills/security-and-hardening/SKILL.md)。

三、结构化日志核查项

清单 "Structured Logging" 小节共 8 个核查条目,逐条解读如下:

  1. 日志必须结构化(JSON),事件名稳定——不是自由拼接的字符串。这一点在仓库夹具 evals/fixtures/observability-and-instrumentation/payment-retry.js 中有一个反面教材:

    console.log(`retry ${attempt} failed: ${error.message}`);
    

    这行模板字符串无法被过滤、聚合或告警。配套的 skills/observability-and-instrumentation/SKILL.md 给出了改造后的正例:event: 'payment_failed' 的稳定事件名加上 paymentIdprovidererrorCodeattempt 等机器可读字段,并配了 error/warn/info/debug 四级日志的语义对照表(error = 不变量被破坏、可能有人需要处理;warn = 降级但已处理;info = 重要业务事件;debug = 生产环境默认关闭)。

  2. 每行日志携带 correlation/request ID,在系统边界生成或接收;

  3. 关联 ID 必须跨所有出站调用与异步边界传播(HTTP 头、队列元数据)。技能文档中给出了 Express 中间件实现:在请求边界读取 x-request-id 头或生成 crypto.randomUUID(),用 logger.child({ requestId: req.id }) 派生子日志器并回写响应头;

  4. 日志级别语义一致(见上一条的四级定义);

  5. 任何日志行不得包含密钥、token、密码或未脱敏的 PII——清单明确标注这是 security-and-hardening 技能的硬性规则;

  6. 字段白名单制——不允许整体输出请求/响应体,不允许输出认证头;

  7. 外部服务调用只记录元数据:端点、状态、时延、尝试次数、脱敏后的标识符;

  8. 抽查真实日志输出——确认是结构化字段而不是 [object Object]

最后一条值得强调:清单把"验证实际输出"作为核查项而非建议,呼应了技能文档 "Verification" 一节中 "confirm fields are structured (not [object Object])" 的要求。

四、指标核查项:RED/USE、直方图与基数红线

"Metrics" 小节的 7 个条目可以归为三组规则:

覆盖规则(RED + USE)

  • 每个端点和每个外部依赖都埋 RED 三指标:Rate(速率)、Errors(错误率)、Duration(时延);
  • 每个资源(队列、连接池、主机)埋 USE:Utilization(利用率)、Saturation(饱和度)、Errors(错误)。

统计规则

  • 时延必须是直方图(histogram),p50/p95/p99 可查询——"never an average"(绝不用平均值)。技能文档补充了原因:"an average hides the 1% of users having a terrible experience";
  • 队列深度与处理时长要对每个 worker/队列单独跟踪。

基数规则(清单中最关键的一组)

  • 所有 label 必须来自小而固定的集合(路由模板、状态码类别、服务商名);
  • 严禁无界 label 值:不得出现 user ID、tenant ID、邮箱、原始 URL、请求 ID、错误消息文本;
  • 状态码按类别归组(用 5xx 而不是 503)。

技能文档把这条称为 "Cardinality is the failure mode":每一种唯一 label 组合都是一条独立时间序列,无界值会让指标后端撑不住;这些高基数信息应该放进日志和追踪里。仓库附带的示例代码展示了带有限定 label 集合的直方图定义(Prometheus prom-client,技能文档注明这只是一种常见后端选择,RED/USE 与基数规则与厂商无关):

const httpDuration = new Histogram({
  name: 'http_request_duration_seconds',
  help: 'HTTP request duration',
  labelNames: ['method', 'route', 'status_class'],  // '2xx', not '200'
  buckets: [0.05, 0.1, 0.25, 0.5, 1, 2.5, 5],
});

文档同时给出正误对照:route="/api/tasks/:id"status_class="5xx"provider="stripe" 是合格 label;user_idemailrequest_id、完整 URL、错误消息文本则永远不该成为 label。

五、分布式追踪核查项

"Distributed Tracing" 小节 7 个条目覆盖了追踪接入的完整生命周期:

  1. OpenTelemetry(或等价物)在服务启动时初始化,先于其他导入——技能文档的示例是独立的 tracing.ts 入口文件,NodeSDK 携带 serviceName 与自动插桩器,"must be imported before anything else";
  2. 对 HTTP、gRPC、数据库客户端启用自动插桩,代码量趋近于零;
  3. 追踪上下文在每次出站调用中传播、在每次入站请求中提取,协议为 W3C traceparent/tracestate
  4. 上下文必须跨越异步边界存活——队列消息需携带 trace 元数据,否则"trace dies at the gap"(追踪在间隙处断掉);
  5. 手工 span 只包裹有意义的内部工作单元(如 applyDiscountschargeProvider),并附带 On-Call 会用来过滤的属性;
  6. span 属性中不出现密钥或 PII
  7. 采样策略:默认低比率的 head-based 采样;若后端支持 tail sampling,错误请求 100% 保留。

六、告警核查项:症状驱动 + 两级严重度

"Alerting" 小节 7 个条目浓缩了 SRE 领域的两条硬规则:

症状驱动,而非原因驱动

Every alert is symptom-based (error rate, p99 latency, queue age) — causes (CPU, disk, restarts) go to dashboards, not pagers.

技能文档给出了对照表:错误率 >1% 持续 5 分钟、p99 时延 >2s、队列积压 >10 分钟属于值得 page 的症状;CPU 85%、某个 pod 重启、磁盘 70% 属于原因,应上仪表盘而不是打给值班人员。原因驱动告警会在"一切正常时误报,在你没预测到的故障时漏报";症状驱动告警则在"用户受损时精确触发,与具体原因无关"。

其余核查条目

  • 每条告警必须可行动——"忽略它、会自愈"的告警直接删除;
  • 每条告警链接到 runbook,最少三行:它意味着什么、第一条要跑的查询、升级路径;
  • 阈值与持续时间必须由 SLO 或历史数据论证,而非拍脑袋;
  • 只保留两级严重度page(用户可见,立即处理)与 ticket(降级,本周内处理)——清单原话:第三级会"变成训练人们忽略一切的噪声";
  • 每条新告警试触发一次:确认它到达了正确的渠道、runbook 链接可点;
  • 不存在"每天触发并被例行确认、无人处理"的告警。

七、仪表盘核查项

"Dashboards" 小节仅 4 条,但针对性很强:

  • [ ] 存在服务健康仪表盘:错误率、p99 时延、流量、饱和度;
  • [ ] 依赖健康面板展示每个下游服务的错误率与时延;
  • [ ] 仪表盘回答的是清单开头的 On-Call 问题——而不是"everything except the answer"(什么都显示、就是不显示答案);
  • [ ] 默认时间范围合理(1h–6h,而不是 30d)。

第四条隐含的操作含义:值班工程师打开仪表盘的默认视图应直接对准"事故当下"的时间窗口。

八、验证遥测本身:把埋点当代码对待

"Verify the Telemetry" 小节开宗明义:"Instrumentation is code; it can be wrong"(埋点也是代码,同样会写错)。四个验证条目构成闭环:

  1. 在 staging 人为制造一个错误 → 通过 correlation ID 在日志中找到它;
  2. 发送测试流量 → 指标序列带着预期的 label 和合理数值出现;
  3. 在追踪 UI 中端到端跟踪一个请求 → 没有断掉的 span;
  4. 一个人为诱导的故障仅凭遥测数据即可诊断,无需读源码。

第 4 条是最强的验收标准:如果诊断过程需要翻代码,说明遥测本身存在盲区。这一节与技能文档 "7. Verify the telemetry itself" 完全对应,是该技能"验证不可妥协(Verification is non-negotiable)"设计原则的体现。

九、Pre-Launch Gate:上线前遥测门禁

清单最后的 "Pre-Launch Gate" 是相对技能文档独有的强化——在功能进入生产环境之前,以下条目必须全部为真:

  • [ ] 结构化日志正在流入日志聚合系统;
  • [ ] 每个新端点和每个新依赖的 RED 指标已在仪表盘可见;
  • [ ] 至少一条症状驱动告警已配置,附 runbook,且已试触发;
  • [ ] 一个请求可以被追踪它经过的每一个服务;
  • [ ] On-Call 知道 runbook 放在哪里。

清单末尾将"上线当天的监控时序与回滚触发条件"交给 shipping-and-launch 技能(skills/shipping-and-launch/SKILL.md)——该技能定义了灰度发布阶梯(canary → 5% → 25% → 100% 的监控窗口)与回滚计划,本清单则确保喂给那些监控的遥测管道是完整的。两者形成"埋点就绪 → 发布可观测"的衔接。

十、在仓库中如何使用与验证这份清单

从源码结构看,这份清单的可用性在仓库层面有三重保障:

  1. 评测用例锚定行为evals/cases/observability-and-instrumentation.json 定义了针对该技能的评测:prompt 为 "Instrument a new payment-retry feature so on-call can operate it.",期望输出为 "On-call questions defined first, then structured logs, RED metrics, and symptom-based alerts that answer them",并列出四项可核查预期——先写 On-Call 问题、结构化事件日志带 correlation id、指标避免无界基数、告警为症状驱动且可行动。这四个预期与清单的四个核心小节一一对应,说明清单条目本身就是评测断言的素材。
  2. 正反夹具成对出现payment-retry.js 提供"未插桩"的基线代码(含 console.log 反模式),operations.md 提供"On-Call 问题 + 敏感数据边界"的输入上下文,代理的任务就是按清单把它改造成可运营代码。
  3. README 的引用表README.md 在 Reference Checklists 表格中把本清单概括为 "On-call questions, structured logging, RED/USE metrics, tracing, symptom-based alerting, pre-launch gate",可作为检索本清单内容的官方目录。

使用方式上,若你在自己的仓库中为 AI 编码代理安装该技能包(各工具的安装方式见 docs/getting-started.md),当代理执行"为某功能加埋点"类任务时,observability-and-instrumentation 技能负责流程,本清单则作为逐项打勾的验收标准:先确认 On-Call 问题已写就,再逐项核对日志、指标、追踪、告警、仪表盘五组条目,最后以 "Verify the Telemetry" 的四项演练和 Pre-Launch Gate 的五条门禁作为收尾判据。

结语

references/observability-checklist.md 的价值在于把散落在技能长文档中的埋点规则压缩成一份"可执行判据":每个条目都是一个能回答"是/否"的检查点,且全部回溯到可操作的工程动作——写下问题、白名单字段、限定 label 集合、试触发告警、诱导故障验证。配合 skills/observability-and-instrumentation/SKILL.md 的完整流程与 evals/fixtures/observability-and-instrumentation/ 下的正反夹具,它构成了一套从"问题定义"到"上线门禁"的完整可观测性验收链条。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388