Observability

系统化梳理日志、指标与追踪的协同机制及成本控制策略。

已扫描
适合谁
后端开发工程师、DevOps 运维人员
不适合谁
无监控需求的初学者、仅需简单工具的普通用户
国内可用性
需网络配置。可能需要网络配置或第三方服务可访问。
安装难度
中等(★★☆)。基于终端操作、依赖、API Key 和本地环境要求的初步判断。

安装与下载

openclaw skills install @ivangdavila/observability

Skill 说明

命令、参数、文件名以原文为准

心智模型:三大信号,一个预算

  • 指标回答“是否出错,以及在哪里”:预先聚合、查询成本低、基数小,是你设置告警的信号。日志回答“为什么”:事件粒度的详细信息,可通过字段查询。追踪回答“请求路径中的哪个环节,耗时多久”:跨服务的跨度树结构。
  • 三大信号是互补而非冗余的:指标显示 p99 延迟上升;追踪显示具体哪个跨度;日志显示错误信息。用一种信号完成另一种的任务是大忌,例如用指标记录每个 request_id,或用日志计数代替计数器。
  • 示例(Exemplars)连接指标与追踪:一个包含 trace_id 的直方图桶,将“延迟高”转化为“这里有一个慢请求”。在添加标签前,优先考虑使用示例。
  • 仪器化预算:每个跨度、每条日志、每条时间序列都会产生采集、存储和查询成本。应像管理内存一样管理可观测性数据;一个服务每请求生成 1000 个跨度,相当于新的内存泄漏,只是按月计费。
  • 基数呈乘积关系,而非累加:10 个标签,每个有 10 个值,不是 100 个系列,而是 10^10 个。这一事实决定了低成本管道与六位数账单之间的区别。
  • 成本 = 采集(输入字节数)+ 存储(保留字节数)+ 查询(扫描字节数)。应在采集阶段削减成本,通过采样,而不是在查询阶段;一旦数据被存储,成本已发生。
  • 可观测性 vs 监控:监控覆盖已知未知(你编写的告警);可观测性允许你调查未知未知(新型故障),通过事后查询高基数字段。仅依赖预聚合指标的管道属于监控,而非可观测性。

指标:类型、聚合与百分位陷阱

  • 四种类型:计数器(单调递增,使用 rate())、仪表(当前值,不使用 rate)、直方图(分桶分布,主力工具)、摘要(客户端计算分位数,旧式,无法跨实例聚合)。使用直方图而非摘要:摘要无法在 Pod 间平均。
  • 四大黄金信号:延迟、流量、错误、饱和度。RED(速率、错误、持续时间)适用于请求驱动的服务;USE(利用率、饱和度、错误)适用于资源(CPU、磁盘、网络)。RED 用于服务,USE 用于主机。
  • 使用百分位而非平均值:告警和报告应基于 p99 延迟,而非均值。50ms 的平均值可能掩盖 5s 的 p99 延迟;当尾部已燃烧时,均值毫无意义。跨实例的 avg(p99) 无意义:应平均桶,而非分位数。
  • 将直方图桶设置为你的 SLO 边界,而非默认值:Prometheus 默认桶针对秒级场景,对亚 100ms 接口不准确。[25, 50, 100, 250, 500, 1000, 2500, 5000]ms 的桶适用于 Web 服务;高于 SLO 阈值的桶即为告警目标。
  • 标准查询为:histogram_quantile(0.99, rate(http_duration_bucket[5m])),它读取桶边界而非原始值。rate 需要至少两个样本,范围至少为采样间隔的两倍。1 分钟范围搭配 15 秒采样 = 4 个样本,噪声大;建议使用 5 分钟。
  • 记录规则预计算复杂查询:若仪表板查询耗时超过 1 秒,应移至记录规则,每 30-60 秒写入新指标。每服务 p99 查询是最典型的候选。
  • rate() 能处理重启导致的计数器重置;increase() 在长范围内可能跨重置重复计数。趋势分析信任 rate,精确计数避免使用 increase
  • 告警所依据的指标应直接发出:若告警基于 5xx / total,应在代码中分别发出两个计数器;不要从日志行推导总数。从日志推导指标相当于让日志承担指标的工作,成本约为 100 倍。
  • 仪表用于当前状态(队列深度、活跃连接数、内存);计数器用于累计事件(请求、错误)。将请求计数放入仪表会丢失速率信息和重置处理能力。

高基数:乘法成本

  • 基数 = 不同标签-值组合的数量。成本随标签乘积增长:user_id(100 万个值)× endpoint(50 个)= 5000 万个系列。一个不良标签即可拖垮整个管道。
  • 黑名单,永远不要作为指标标签:user_idemailrequest_idsession_idtrace_idip、原始 URL。这些应放在跨度和日志中,或作为示例,绝不能作为指标标签。
  • 合理预算:每指标 < 10 个标签,每服务 < 10 万活跃系列。超过每后端 100 万系列后,查询延迟和存储成本非线性恶化;真正致命的是“悬崖”,而非“斜坡”。
  • 定期审计:使用 /api/v1/status/tsdb(Prometheus)或等效的 top-series 端点,列出各标签的唯一值数量。每月运行一次;标签值超过 10 万个即为严重警告。
  • 若某指标需要按用户拆分,说明误用指标替代日志:应将该维度移到跨度属性(采样,有界)或结构化日志字段(索引,可查询),而非标签。
  • 基数悬崖是阶跃而非渐变:成本线性增长后,在突破分片限制或触发索引重哈希时突然飙升。关注系列数趋势,而不仅是账单;趋势断裂早于账单激增。
  • 在收集器阶段丢弃高基数属性,防止其到达后端:OTel 处理器应剥离 http.target(原始 URL),保留 http.route(模板化路径)。收集器是最后的免费转换机会。
  • 新标签是一次成本决策,应在 PR 审查时决定,而非账单结算时。审查标签新增如同审查模式变更;提出“这个字段最多有多少不同值?”的评审者才尽到了责任。

日志:结构、级别与追踪桥梁

  • 结构化日志是强制要求:使用 JSON 或 logfmt 格式,禁止自由文本。每行日志必须包含 timestamplevelmessagetrace_idspan_id 以及上下文字段。自由文本在大规模场景下无法查询。
  • 使用模板化消息和可变字段:user logged in + {user_id: 12345} 是一条日志流;而 user 12345 logged in 会生成 100 万条独立流。日志聚合基于模板索引,而非具体值;高基数消息会导致索引膨胀。
  • 日志级别用于采样决策:ERROR 表示“需要触发告警”;若不值得告警,则应为 WARN。生产环境默认使用 INFO,DEBUG 仅限主动排查时启用。生产环境中服务处于 DEBUG 状态会造成日志体积泄漏。
  • 每条日志必须携带 trace_id,这是不可妥协的:它是从指标(计数上升)→ 跟踪(哪个请求)→ 日志(说了什么)之间的桥梁。缺少 trace_id 将导致三者完全割裂。
  • 不要同时记录日志和指标同一事件:如果需要计数,就发出计数器;如果需要详细信息,才记录日志。每请求记录一行日志再通过匹配计数,成本约为计数器的 100 倍。
  • 日志体积目标:稳态下每请求 1-5 条日志,而非 50 条。一个服务每请求输出 1KB,每秒 1 万请求 = 10MB/s ≈ 800GB/天。超过此阈值,日志已承担了指标或追踪的任务。
  • 敏感信息与密钥:禁止记录令牌、密码、完整卡号、原始个人身份信息(PII)。应在收集端部署脱敏处理器;管道内脱敏比发生数据泄露更经济,并能捕获代码遗漏的情况。
  • 日志级别不能替代采样:INFO 以全量级别输出仍会过载。应在追踪层使用尾部采样(tail-based sampling),按整请求丢弃,仅当其追踪被保留时才保留日志。

追踪:跨度、传播、尾部采样

  • 一次追踪是一个跨度树,每个服务调用对应一个跨度。一个跨度包含 operationstart/durationstatusattributesspan_idparent_span_idtrace_id。树的结构即为请求的实际路径。
  • 传播是最常见的失败点:W3C traceparent 必须在每次边界(HTTP、队列、RPC)发送时注入,在接收时提取。缺失任一环节将导致追踪断裂,形成两个不连贯的部分。
  • 头部采样(在执行前于根节点决定)成本低且确定,但会在知晓结果前丢弃请求:会丢失错误信息。仅适用于低流量场景,或尾部采样不可行时使用。
  • 尾部采样(在追踪完成后决定)可保留 100% 的错误,对成功请求进行抽样:确保 status != ok 的请求 100% 保留,latency > p99 的请求 100% 保留,其余按 1%-10% 抽样。这是实现完整故障信号而不带来全量数据负担的关键。
  • 跨度属性是高基数通道:user_idrequest_idhttp.methoddb.statementhttp.status_code 应放在跨度上,而非指标标签。采样可控制基数:5% 的采样率将 100 万用户标签缩减至约 5 万跨度。
  • 使用模板化跨度名称,而非原始值:如 GET /users/{id},而非 GET /users/12345。原始 URL 会爆炸跨度名称基数并破坏聚合;路由模板才是分组依据。
  • 避免过度拆分跨度:在一个循环中为每行数据库记录创建一个跨度 = 每请求 1000 个跨度。应仅对循环整体打一个跨度,并添加 rows 数量属性,或对内部跨度采样。过度拆分相当于追踪中的内存泄漏。
  • 关键路径决定延迟,而非最长跨度:一个 200ms 的跨度与一个 50ms 的跨度并行,总延迟为 200ms;两个 50ms 的跨度串行,总延迟为 100ms。应关注树中最长链路,而非最大节点。
  • 尾部采样需要收集器持有完整追踪,这会引入与追踪持续时间成比例的延迟和内存开销。需限制追踪时长(丢弃超过 30 秒的跨度),否则在负载高峰时最需要它时,收集器可能因内存溢出而崩溃。

SLO 与错误预算

  • SLI = 用户可感知的质量指标(例如:延迟 < 500ms 且状态码 < 500 的请求占比)。SLO = 该指标的目标值(例如:28 天内达到 99.9%)。错误预算 = 1 - SLO(0.1%):允许的不可靠性额度,可用于承担风险。
  • SLI 必须反映用户感知:关注请求延迟和可用性,而非 CPU 或磁盘使用率。CPU 是仪表板的辅助指标;将其作为 SLI 会优化错误目标。
  • 使用 28 天滚动窗口(非 30 天):与周周期对齐,平滑工作日与周末的波动,符合 SRE 通用实践。30 天窗口会随时间偏移星期几,产生漂移。
  • 告警应基于消耗速率,而非原始 SLI:28 天窗口会掩盖 1 小时的中断(占窗口的 0.15%)。消耗速率 = 预算消耗速度;1 小时内 14.4 倍的消耗速率意味着整个预算将在约 1 小时内耗尽。
  • 多窗口多消耗速率告警(Google SRE 模式):若 1 小时内消耗速率 > 14.4x 且 5 分钟内 > 14.4x,则触发告警;若 6 小时内 > 6x 且 30 分钟内 > 6x,则生成工单。两个窗口的 AND 条件可减少误报;快速消耗触发告警,缓慢消耗生成工单。
  • 错误预算策略:当预算耗尽时,冻结功能开发并优先修复可靠性问题。若无冻结机制,SLO 只是形式主义;团队会继续在红色预算下发布,最终发现 SLO 并无约束力。
  • SLO 应基于用户需求设定,而非当前性能:若用户察觉到 500ms 延迟,即使系统目前表现良好(如 200ms),SLO 也应设为 < 500ms。舒适的 SLO 是谎言,会掩盖性能退化。
  • 每个用户旅程设置一个 SLI,而非每个接口:如“结账在 < 1 秒内完成”优于 50 个接口级 SLO。用户不关心接口 N,只关心旅程是否顺畅。

告警:症状、消耗速率、疲劳

  • 告警应聚焦于症状,而非底层指标。避免基于 CPU、内存等资源指标直接告警,这些是中间状态,不是用户影响。
  • 消耗速率是核心判断依据:关注错误预算的消耗速度,而非单一指标值。快速消耗表明系统正在恶化。
  • 减少告警疲劳:通过合理设计告警层级(如分级通知)、抑制重复告警、结合上下文信息,避免因频繁告警导致响应麻木。
  • 告警应具备可操作性:每个告警都应明确指出“谁需要做什么”,避免模糊或无行动指引的提示。
  • 告警生命周期管理:定期审查告警有效性,关闭无效或过时的告警规则,保持告警系统的健康。
  • 页面关注用户可见的症状,而非根本原因:关注错误率和延迟,而非 CPU 或磁盘使用率。CPU 高但未影响延迟的情况应作为仪表板指标,而非独立页面。
  • 饱和度是首要预警指标:CPU > 85%-90%、内存接近上限、队列深度上升。饱和度告警会在延迟升高前触发,是早期预警;延迟升高则是确认信号。
  • 告警疲劳是隐形杀手:每个未被处理的告警都会削弱团队信任。目标为每人每班次 <1 页,每人每天 <5 个工单。每周触发超过一次且无操作手册的告警属于噪音,应删除或调优。
  • 每个告警必须附带操作手册链接:这是值班人员的第一步操作。操作手册应列出检查顺序及解决步骤。没有操作手册的告警只算一半,值班人员只能凭经验摸索,效率低下。
  • 多窗口告警中 AND 与 OR 的使用:AND(两个窗口都触发)可减少误报,用于页面告警;OR(任一触发)会增加误报,用于工单。两者混淆是常见配置错误。
  • 告警基于 SLO 燃烧速率,而非组件健康状态:用户可见的 SLO 是核心页面,组件仪表板仅用于排查。若本末倒置,将导致陷入噪音并错过真实故障。
  • 避免对原始计数器告警:应告警 rate(errors[5m]) / rate(total[5m])(比率),而非直接告警 errors(其随流量增长而放大)。流量突增会导致错误数翻倍,但未必存在缺陷。

数据管道:OTel、采集器、成本经济

  • OpenTelemetry 是值得投入的唯一标准:一套 SDK、一种传输格式(OTLP),支持多种后端。使用 OTel 一次接入,即可发送至 Prometheus、Tempo、Jaeger 或 Datadog。使用厂商 SDK 会锁定单一供应商。
  • 采集器是服务与后端之间的转换层:支持尾部采样、属性丢弃、敏感信息脱敏、指标聚合等操作,在支付存储费用前完成。切勿直接将跨度数据发送至 SaaS 平台:按字节计费,且失去转换能力。
  • 采集器部署策略:每个节点部署一个代理(DaemonSet)收集数据;网关集群负责尾部采样与分发。在网关处进行尾部采样可获取完整链路;在代理处仅能获取节点内跨度。
  • 按信号类型设定保留周期:指标 3-6 个月(1-2 周后降采样),日志 7-30 天(采样),链路 1-7 天全量 + 30 天仅保留错误。超过一周的原始链路极少被重新查询;建议保留错误,其余采样。
  • 自动化注入(OTel SDK、eBPF)虽减轻代码负担,但引入噪声:捕获所有 HTTP 跨度,包括健康检查和指标拉取。应在采集器处丢弃 /healthz/readyz/metrics 路径,避免主导链路体积。
  • 季度审计三张清单:按序列数排名前 10 的指标、按体积排名前 10 的日志模板、按数量排名前 10 的跨度名称。任一清单增长缓慢即为成本杀手;部署后出现的峰值往往是问题所在。
  • 自建 vs 云厂商后端:在日摄入量低于约 1 TB/天时,云厂商在上线速度和查询体验上占优;超过该阈值后,自建方案(如 Mimir + Tempo + Loki,或 ClickHouse)在成本上更具优势。此拐点真实存在,需每年评估随数据量增长的策略。

典型场景应对

场景应对策略
p99 延迟突增,无明显原因从延迟直方图中提取一个示例 trace_id,打开链路追踪,阅读关键路径,而非最长跨度。
指标存储账单一夜飙升通过 /api/v1/status/tsdb 审计基数;新高基数标签与其他标签组合导致爆炸式增长。回滚该标签为跨度属性。
链路在某个服务边界中断上下文传播问题:W3C traceparent 未注入或提取。检查消息队列消费者或 RPC 客户端;链路断裂处即上下文丢失点。
值班人员每晚收到告警,无人响应告警疲劳:删除每周触发超过一次且无操作手册的告警;基于 SLO 燃烧率重新基线,而非 CPU 使用率。
调试单个用户的失败请求不要添加新的指标标签。通过 trace_id(每行日志均包含)搜索日志 → 打开链路 → 查看各跨度内容。
服务日志量约 800GB/天统计每请求次数与错误数;仅记录错误和警告;其余日志在采集器处尾部采样,比例 1%-5%。
仪表板查询超时移至录制规则(每 30 秒预计算各服务的 p99);仪表板读取新生成的指标。
需要保留所有错误,采样成功请求尾部采样策略:保持 status != ok 和慢速请求 100% 保留,其余请求采样 1%-10%,在采集器处执行。
部署后基数突然飙升原始 URL 或 user_id 成为标签。应在采集器处剥离,移至跨度属性。
SLI 显示绿色,但用户投诉SLI 设定错误:平均延迟或测量可用性而非用户感知速度。应基于用户实际感知重新推导 SLI。

争议点

  • 指标优先 vs 日志优先 vs 跟踪优先:指标优先(Prometheus 文化)在成本和告警方面占优;日志优先(ELK 文化)在临时调查和事后查询方面占优;跟踪优先在请求跨 10+ 服务的分布式系统中占优。OpenTelemetry(OTel)统一了三者,但预算仍迫使选择主信号:应根据故障模式选择,而非团队习惯。
  • 头采样 vs 尾采样:头采样成本低、确定性强、无状态,但会丢弃最需要的失败数据;尾采样能保留错误和慢速跟踪的 100%,但需要有状态的收集器,增加延迟。前沿实践:低流量或新项目用头采样;任何需通过故障调试的生产环境用尾采样。
  • 平均值 vs 百分位数用于 SLI:百分位数(如 p99)反映用户感知质量,是正确的 SLI 指标;平均值用于容量和资源规划,因均值可建模负载。将平均延迟作为 SLI 会掩盖用户实际感受到的尾部延迟。
  • 厂商托管后端 vs 自托管后端:厂商方案在价值交付速度、查询体验和关联分析方面占优,直到摄入量超过每日 ~1 TB;自托管(如 Mimir/Tempo/Loki 或 ClickHouse)在超出该阈值后更具成本优势。交叉点由数据量决定,而非偏好;随摄入量增长应重新评估。
  • 严格 SLO vs 倡议性 SLO:严格 SLO(预算耗尽时冻结功能开发)适用于成熟的可靠性文化;倡议性 SLO(仅追踪但不强制执行)适用于缺乏政治支持的冻结机制。没有冻结机制的严格 SLO 是最差情况:看似合同,实则无效。
  • 结构化 JSON vs logfmt:JSON 适合嵌套或复杂事件(如一个跟踪跨度作为日志);logfmt 适合高吞吐的扁平日志(如请求日志)。两者均为结构化格式;分歧在于解析成本与可读性,二者均优于自由文本。

相关技能

通过 clawhub install <slug> 安装,若用户确认:

  • metrics - 本技能生成的计数器、度量、直方图类型及 Prometheus 查询
  • grafana - 覆盖指标、跟踪和日志管道的仪表板与查询层
  • alerts - 告警规则、运行手册和疲劳管理,本技能的 SLO 燃烧率方法所针对的目标
  • monitoring - 监控与可观测性的边界以及已知未知的覆盖范围
  • devops - 信号消费所需的运维节奏和轮值文化
I
@ivangdavila

已收录 27 个 Skill

相关推荐