Observability & Reliability Engineering

提供完整的可观测性与可靠性工程框架,涵盖日志、指标、链路追踪等核心能力。

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

安装与下载

openclaw skills install @1kalin/afrexai-observability-engine

Skill 说明

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

可观测性与可靠性工程

构建可观测、高可靠服务的完整体系 —— 从结构化日志到事件响应,再到以 SLO 为导向的开发。


快速健康检查 (/16)

评估您当前的可观测性水平:

信号健康 (2)薄弱 (1)缺失 (0)
结构化日志包含 trace_id 关联的 JSON 日志日志存在但非结构化console.log / print 语句
指标采集RED/USE 指标并配有仪表盘有部分指标,无仪表盘无指标
分布式追踪完整请求链路且有采样部分追踪,仅关键服务无追踪
告警机制基于 SLO 的告警 + 运维手册阈值告警,部分运维手册无告警或全是噪音
事件响应有明确流程、角色分工及事后复盘临时响应,部分文档“谁发现谁修”
SLO 定义有 SLO 并每周跟踪错误预算非正式可用性目标无可靠性目标
应急轮班有结构化的轮班与升级机制非正式“叫人”方式无应急轮班
成本管理观测性预算每月跟踪对成本有一定意识不清楚实际支出

12-16: 生产就绪。重点优化。

8-11: 基础已建立。系统性填补短板。

4-7: 风险显著。优先完善告警与事件响应。

0-3: 盲目运行。立即启动第一阶段。


第一阶段:结构化日志

日志架构

应用 → 结构化 JSON → 日志路由器 → 存储 → 查询引擎
                                    ↓
                              告警处理管道

必需字段(每条日志)

字段类型用途示例
timestampISO-8601 UTC时间戳2026-02-22T18:30:00.123Z
level枚举严重程度info, warn, error, fatal
service字符串所属服务payment-api
version字符串当前部署版本v2.3.1
environment字符串环境标识production
message字符串发生了什么支付处理成功
trace_id字符串请求关联标识abc123def456
span_id字符串跟踪中的操作标识span_789
duration_ms数字执行耗时(毫秒)142

上下文字段(按业务域添加)

# HTTP 请求上下文
http:
  method: POST
  path: /api/v1/orders
  status: 201
  client_ip: 203.0.113.42  # 如需保护隐私可匿名化
  user_agent: "Mozilla/5.0..."
  request_id: "req_abc123"

# 业务上下文
business:
  user_id: "usr_456"
  tenant_id: "tenant_789"
  order_id: "ord_012"
  action: "checkout"
  amount_cents: 4999
  currency: "USD"

# 错误上下文
error:
  type: "PaymentDeclinedError"
  message: "卡被拒:余额不足"
  code: "CARD_DECLINED"
  stack: "..." # 仅在非生产环境或 DEBUG 级别启用
  retry_count: 2
  retryable: true

日志级别决策树

是否即将崩溃?
  → FATAL(记录后退出)

是否有操作失败需要人工介入?
  → ERROR(通知相关人员或创建工单)

是否有意外情况但已恢复?
  → WARN(每日排查中关注)

是否为正常业务事件值得记录?
  → INFO(审计轨迹、业务指标)

是否对调试有用但在生产中过于嘈杂?
  → DEBUG(生产关闭,预发开启)

是否仅在逐步调试代码时有用?
  → TRACE(永远不在生产环境使用)

日志级别规则

  1. ERROR 表示必须采取行动 —— 若无人需响应,则应降级为 WARN
  2. INFO 用于业务事件 —— 不应包含内部实现细节
  3. 避免在紧循环中日志 —— 聚合后记录摘要
  4. 在边界处记录日志 —— API 入口/出口、队列消费/发布、数据库调用
  5. 绝不记录敏感信息 —— API 密钥、令牌、密码、个人身份信息(见下文清洗规则)

PII 与密钥清洗

scrub_patterns:
  # 始终脱敏
  - field_patterns: ["password", "secret", "token", "api_key", "authorization"]
    action: replace_with_redacted

  # 哈希处理,用于关联而不暴露
  - field_patterns: ["email", "phone", "ssn", "national_id"]
    action: sha256_hash

  # 部分掩码
  - field_patterns: ["credit_card", "card_number"]
    action: mask_last_4  # "****-****-****-1234"

  # IP 地址匿名化
  - field_patterns: ["client_ip", "ip_address"]
    action: zero_last_octet  # 203.0.113.0

日志器配置(按语言)

Node.js (Pino):

import pino from 'pino';
import { AsyncLocalStorage } from 'node:async_hooks';

const als = new AsyncLocalStorage<Record<string, string>>();

const logger = pino({
  level: process.env.LOG_LEVEL || 'info',
  formatters: {
    level: (label) => ({ level: label }),
  },
  mixin: () => als.getStore() ?? {},
  redact: ['req.headers.authorization', '*.password', '*.token'],
  timestamp: pino.stdTimeFunctions.isoTime,
});

// 中间件:注入上下文
app.use((req, res, next) => {
  const ctx = {
    trace_id: req.headers['x-trace-id'] || crypto.randomUUID(),
    request_id: crypto.randomUUID(),
    service: 'payment-api',
    version: process.env.APP_VERSION,
  };
  als.run(ctx, () => next());
});

Python (structlog):

import structlog
structlog.configure(
    processors=[
        structlog.contextvars.merge_contextvars,
        structlog.processors.add_log_level,
        structlog.processors.TimeStamper(fmt="iso", utc=True),
        structlog.processors.JSONRenderer(),
    ],
)
log = structlog.get_logger()
# 绑定每请求上下文:
structlog.contextvars.bind_contextvars(trace_id=trace_id, user_id=user_id)

Go (zerolog):

log := zerolog.New(os.Stdout).With().
    Timestamp().
    Str("service", "payment-api").
    Str("version", version).
    Logger()
// 每个请求:
reqLog := log.With().Str("trace_id", traceID).Logger()

日志存储决策

体积解决方案保留策略成本
<10 GB/天Loki + Grafana30天热存储,90天冷存储
10-100 GB/天Elasticsearch / OpenSearch14天热存储,90天 S3 冷存储中等
100+ GB/天ClickHouse 或 Datadog7天热存储,30天归档
预算受限Loki + S3 后端90天全冷存储极低

10 大日志反模式

#反模式修复建议
1log.error(err) 无上下文信息始终包含:操作内容、输入数据、系统状态
2记录请求/响应体仅在 DEBUG 级别记录;敏感字段需脱敏
3日志消息使用字符串拼接使用结构化字段:log.info("processed", { order_id, amount })
4捕获异常后记录并重新抛出在处理层记录日志,而非每一层都记录
5不同服务使用不同日志格式所有服务统一日志 schema
6无日志轮转或保留策略设置最大大小 + TTL;归档至冷存储
7在热点路径中频繁日志输出聚合日志:每 N 条记录或每隔一段时间汇总一次
8缺失关联 ID(Correlation ID)从入口点传播 trace_id 到所有服务
9使用布尔型日志级别(如 verbose: true使用标准日志级别,并支持最小级别配置
10明文记录 PII 信息在日志器层级实现数据清洗

阶段 2:指标采集

RED 方法(请求驱动型服务)

针对每个服务接口,应监控以下指标:

指标含义Prometheus 示例
Rate每秒请求量http_requests_total{method, path, status}
Errors每秒失败请求数http_requests_total{status=~"5.."} / 总数
Duration延迟分布http_request_duration_seconds{method, path}(直方图)

USE 方法(基础设施资源)

针对每个资源(CPU、内存、磁盘、网络):

指标含义示例
Utilization资源使用率(百分比)CPU 使用率 78%
Saturation队列深度 / 背压情况当前排队 12 个请求
Errors资源错误数量3 次磁盘 I/O 错误

黄金信号(Google SRE)

信号含义数据来源
延迟请求响应时间RED Duration
流量系统负载需求RED Rate
错误失败请求数率RED Errors
饱和度服务“满载”程度USE Saturation

指标类型及适用场景

类型使用场景示例
Counter只增不减的数值总请求数、错误数、发送字节数
Gauge上下波动的当前值活跃连接数、队列深度、温度
Histogram数值分布统计请求延迟、响应大小
Summary预计算的分位数客户端延迟(需要精确分位数时)

规则: 多数情况下优先使用直方图而非 Summary —— 因为直方图可在实例间聚合。

命名规范

# 格式: <命名空间>_<子系统>_<名称>_<单位>
http_server_request_duration_seconds
http_server_requests_total
db_pool_connections_active
queue_messages_pending
cache_hit_ratio

# 规则:
# 1. 使用 snake_case
# 2. 包含单位后缀(_seconds, _bytes, _total)
# 3. 计数器使用 _total 后缀
# 4. 不在指标名中包含标签名称
# 5. 使用基础单位(秒而非毫秒,字节而非千字节)

标签设计规则

规则原因示例
单个标签基数 <100高基数会严重影响性能status="200" 而非 status="200 OK"
标签中禁止使用用户 ID会导致基数无限增长使用日志关联替代
请求路径中禁止包含 ID/api/users/123 会产生数百万个时间序列正常化为 /api/users/:id
每个指标最多 5-7 个标签每个组合即为一个时间序列{method, path, status, service}

代码埋点检查清单

application_metrics:
  # HTTP 层
  - http_request_duration_seconds: histogram {method, path, status}
  - http_request_size_bytes: histogram {method, path}
  - http_response_size_bytes: histogram {method, path}
  - http_requests_in_flight: gauge

  # 业务逻辑
  - orders_processed_total: counter {status, payment_method}
  - order_value_dollars: histogram {payment_method}
  - user_signups_total: counter {source}

  # 依赖项
  - db_query_duration_seconds: histogram {query_type, table}
  - db_connections_active: gauge {pool}
  - db_connections_idle: gauge {pool}
  - cache_requests_total: counter {result: hit|miss}
  - external_api_duration_seconds: histogram {service, endpoint}
  - external_api_errors_total: counter {service, error_type}

  # 队列 / 异步处理
  - queue_messages_published_total: counter {queue}
  - queue_messages_consumed_total: counter {queue, status}
  - queue_processing_duration_seconds: histogram {queue}
  - queue_depth: gauge {queue}
  - queue_consumer_lag: gauge {queue, consumer_group}

infrastructure_metrics:
  # Node Exporter / cAdvisor 自动提供
  - cpu_usage_percent: gauge {instance}
  - memory_usage_bytes: gauge {instance}
  - disk_usage_bytes: gauge {instance, mount}
  - disk_io_seconds: counter {instance, device}
  - network_bytes: counter {instance, direction}
  - container_cpu_usage: gauge {pod, container}
  - container_memory_usage: gauge {pod, container}

技术栈推荐

组件可选方案推荐方案
采集Prometheus、OTEL Collector、Datadog AgentPrometheus(免费)或 OTEL Collector(厂商中立)
存储Prometheus、Thanos、Mimir、VictoriaMetricsVictoriaMetrics(性价比最优)或 Mimir(Grafana 生态)
可视化Grafana、Datadog、New RelicGrafana(免费、可扩展)
告警Alertmanager、Grafana Alerting、PagerDutyAlertmanager + PagerDuty 路由

阶段 3:分布式追踪

跟踪架构

客户端请求
  → API 网关(根跨度)
    → 认证服务(子跨度)
    → 订单服务(子跨度)
      → 数据库查询(子跨度)
      → 支付服务(子跨度)
        → Stripe API(子跨度)
    → 通知服务(子跨度)
      → 邮件服务商(子跨度)

OpenTelemetry 设置

自动注入(Node.js):

// tracing.ts — 在其他任何导入之前引入
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';

const sdk = new NodeSDK({
  traceExporter: new OTLPTraceExporter({
    url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318/v1/traces',
  }),
  instrumentations: [getNodeAutoInstrumentations({
    '@opentelemetry/instrumentation-http': { ignoreIncomingPaths: ['/health', '/ready'] },
    '@opentelemetry/instrumentation-express': { enabled: true },
  })],
  serviceName: process.env.OTEL_SERVICE_NAME || 'payment-api',
});
sdk.start();

自定义跨度用于业务逻辑:

import { trace, SpanStatusCode } from '@opentelemetry/api';

const tracer = trace.getTracer('payment-service');

async function processPayment(order: Order) {
  return tracer.startActiveSpan('process-payment', async (span) => {
    span.setAttributes({
      'order.id': order.id,
      'order.amount_cents': order.amountCents,
      'payment.method': order.paymentMethod,
    });
    try {
      const result = await chargeCard(order);
      span.setAttributes({ 'payment.status': result.status });
      return result;
    } catch (err) {
      span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
      span.recordException(err);
      throw err;
    } finally {
      span.end();
    }
  });
}

采样策略

策略适用场景配置
始终开启开发/预发布环境,低流量(<100 rps)ratio: 1.0
概率采样中等流量(100-1000 rps)ratio: 0.1(10%)
速率限制高流量(>1000 rps)max_traces_per_second: 100
尾部采样希望捕获所有错误和慢请求由收集器端决定:若存在错误或持续时间超过 p99 则保留
父级基于尊重上游的采样决策若父跨度被采样,则子跨度也采样

建议: 初始采用父级基于 + 概率采样(10%)。在收集器端添加尾部采样以确保捕获所有错误。

上下文传播

头部标准格式
traceparentW3C Trace Context00-{trace_id}-{span_id}-{flags}
tracestateW3C Trace Context供应商特定的键值对
b3Zipkin B3{trace_id}-{span_id}-{sampled}

规则: 优先使用 W3C Trace Context(traceparent)。为兼容旧版 Zipkin 系统,支持 B3 格式。

跟踪数据存储

数据量解决方案保留周期
<50 GB/天Jaeger + Elasticsearch7 天
50-500 GB/天Tempo + S314 天
500+ GB/天Tempo + S3 并配合激进采样7 天
预算受限Jaeger + Badger(本地磁盘)3 天

第四阶段:SLO、SLI 与错误预算

按服务类型选择 SLI

服务类型主要 SLI次要 SLI测量方式
API / Web可用性 + 延迟错误率服务端 + 合成监控
数据管道新鲜度 + 正确性吞吐量管道时间戳 + 校验和
存储持久性 + 可用性延迟校验和 + 运行时监控
流式处理吞吐量 + 延迟消息丢失率消费者延迟 + 端到端延迟
批处理任务成功率 + 新鲜度执行时长作业调度器指标

SLO 定义模板

slo:
  name: "支付 API 可用性"
  service: payment-api
  owner: payments-team

  sli:
    type: availability
    definition: "非 5xx 响应的比例"
    measurement: |
      sum(rate(http_requests_total{service="payment-api",status!~"5.."}[5m]))
      /
      sum(rate(http_requests_total{service="payment-api"}[5m]))

  target: 99.95%  # 每月最多 21.9 分钟停机
  window: rolling_30d

  error_budget:
    total_minutes: 21.9  # 每 30 天
    burn_rate_alerts:
      - severity: critical
        burn_rate: 14.4x  # 预算在 2 小时内耗尽
        short_window: 5m
        long_window: 1h
      - severity: warning
        burn_rate: 6x    # 预算在 5 天内耗尽
        short_window: 30m
        long_window: 6h
      - severity: ticket
        burn_rate: 1x    # 预算在 30 天内耗尽
        short_window: 6h
        long_window: 3d

  consequences:
    budget_remaining_above_50pct: "正常开发速度"
    budget_remaining_20_to_50pct: "优先处理可靠性工作"
    budget_remaining_below_20pct: "暂停新功能;仅聚焦可靠性"
    budget_exhausted: "全员投入可靠性,直至预算恢复"

常见 SLO 目标

服务层级可用性p50 延迟p99 延迟每月停机时间
Tier 0(支付、认证)99.99%<100ms<500ms4.3 分钟
Tier 1(核心 API)99.95%<200ms<1s21.9 分钟
Tier 2(非关键)99.9%<500ms<2s43.8 分钟
Tier 3(内部工具)99.5%<1s<5s3.6 小时
批处理 / 管道99%(成功率)N/AN/AN/A

错误预算追踪

# 每周错误预算审查模板
error_budget_review:
  week: "2026-W08"
  service: payment-api
  slo_target: 99.95%

  budget:
    total_minutes_this_period: 21.9
    consumed_minutes: 8.2
    remaining_minutes: 13.7
    remaining_percent: 62.6%

  incidents_consuming_budget:
    - date: "2026-02-18"
      duration_minutes: 5.1
      cause: "数据库连接池耗尽"
      preventable: true
      action: "增加连接池大小 + 添加饱和度告警"
    - date: "2026-02-20"
      duration_minutes: 3.1
      cause: "上游支付服务商超时"
      preventable: false
      action: "添加熔断机制并启用降级方案"

  velocity_decision: "正常 — 剩余预算 62.6%"
  reliability_work_this_week:
    - "添加连接池饱和度告警"
    - "为支付服务商实现熔断机制"

---

## 阶段 5:告警设计

### 告警质量原则

1. **每个告警必须可操作** — 如果无人需要响应,就不是告警
2. **每个告警需有运行手册(Runbook)** — 在告警注解中直接链接
3. **基于症状而非原因** — 告警应关注“用户无法下单”,而非“CPU 升高”
4. **多窗口燃烧速率** — 不使用静态阈值(参见 SLO 告警)
5. **告警异常状态,而非正常状态** — “15 分钟内无订单” 可捕捉静默故障

### 告警严重等级

| 严重等级 | 响应时间 | 通知渠道 | 责任人 | 示例 |
|----------|----------|----------|--------|------|
| **P0 — 关键** | <5 分钟 | 页面通知(PagerDuty/Opsgenie) | 当班工程师 | 支付系统宕机 |
| **P1 — 高** | <30 分钟 | 工作时间页面通知,全天候 Slack | 当班工程师 | 错误率 >5% 持续 10 分钟 |
| **P2 — 中** | <4 小时 | Slack 频道 | 团队 | p99 延迟升高 2 倍 |
| **P3 — 低** | 下一个工作日 | 自动创建工单 | 团队待办事项 | 磁盘使用率 >80% |
| **信息** | N/A | 仅仪表板显示 | 无人 | 部署完成 |

### 告警设计反模式

| 反模式 | 问题 | 解决方案 |
|--------|------|----------|
| 静态 CPU/内存阈值 | 产生大量噪音,与用户体验无关 | 使用基于 SLO 的燃烧速率告警 |
| 每实例独立告警 | 50 个实例 = 50 条相同告警 | 聚合:在服务级别监控错误率 |
| 无去重机制 | 同一告警触发 100 次 | 按服务 + 告警名称分组;设置重复间隔 |
| 缺少运行手册 | 工程师被唤醒却不知如何处理 | 每条告警必须链接运行手册 |
| 阈值过于敏感 | 对短暂波动即触发 | 使用 `for: 5m` 要求持续条件满足 |
| P0 告警过多 | 告警疲劳 → 忽略真实事件 | 每月审计;对噪音告警降级或移除 |

### 告警模板(Prometheus Alertmanager)

groups:

- name: payment-api-slo

rules:

- alert: PaymentAPIHighErrorRate

expr: |

(

sum(rate(http_requests_total{service="payment-api",status=~"5.."}[5m]))

/

sum(rate(http_requests_total{service="payment-api"}[5m]))

) > 0.01

for: 5m

labels:

severity: critical

service: payment-api

team: payments

annotations:

summary: "支付 API 错误率 {{ $value | humanizePercentage }} (>1%)"

description: "5xx 错误率已超过 1%,持续 5 分钟"

runbook: "https://wiki.internal/runbooks/payment-api-errors"

dashboard: "https://grafana.internal/d/payment-api"

- alert: PaymentAPINoTraffic

expr: |

sum(rate(http_requests_total{service="payment-api"}[15m])) == 0

for: 5m

labels:

severity: critical

service: payment-api

annotations:

summary: "支付 API 连续 5 分钟无流量"

runbook: "https://wiki.internal/runbooks/payment-api-no-traffic"

- alert: PaymentAPILatencyHigh

expr: |

histogram_quantile(0.99,

sum(rate(http_request_duration_seconds_bucket{service="payment-api"}[5m])) by (le)

) > 2

for: 10m

labels:

severity: warning

annotations:

summary: "支付 API p99 延迟 {{ $value }}s (>2s 持续 10 分钟)"

runbook: "https://wiki.internal/runbooks/payment-api-latency"

### 运行手册模板

运行手册:PaymentAPIHighErrorRate

告警含义

支付 API 在 5 分钟窗口内返回的 5xx 错误率超过 1%。

用户可能无法完成支付流程。

影响范围

  • 用户无法进行支付
  • 收入损失:约每分钟 $X(基于平均流量估算)
  • SLO:支付 API 可用性(目标:99.95%)

紧急应对措施

  1. 查看错误仪表板:[链接]
  2. 检查最近部署记录:kubectl rollout history deployment/payment-api
  3. 检查上游依赖项:

- 数据库:[仪表板链接]

- Stripe API:[状态页]

- Redis 缓存:[仪表板链接]

  1. 检查应用日志:
kubectl logs -l app=payment-api --since=10m | jq 'select(.level=="error")'

常见原因与解决方案

原因诊断方法解决方案
部署异常错误出现时间与部署时间一致kubectl rollout undo deployment/payment-api
数据库连接耗尽db_connections_active 达到上限滚动重启 Pod + 增加连接池大小
Stripe 服务中断Stripe 状态页显示红色启用备用支付处理器
内存泄漏内存持续上升,出现 OOMKilled 事件滚动重启 + 进行排查

升级流程

  • 若 15 分钟内未解决:通知支付团队负责人
  • 若收入影响超过 $10,000:通知工程副总裁
  • 若为 Stripe 故障:通知支持团队以便向客户通报

问题解决后

  • 确认错误率持续 10 分钟低于 0.1%
  • 在 #incidents 频道发布:根因、持续时间、影响范围
  • 若停机时间超过 5 分钟,安排事后复盘会议
---

## 阶段 6:仪表板架构

### 仪表板层级结构

L1:管理层/业务仪表板(非技术干系人)
↓
L2:服务概览仪表板(值班人员、快速排查)
↓
L3:服务深度分析仪表板(定位特定服务问题)
↓
L4:基础设施仪表板(资源级别详情)

### L1:业务仪表板

panels:

- title: "每分钟收入"

type: stat

query: "sum(rate(orders_total{status='completed'}[5m])) * avg(order_value_dollars)"

- title: "活跃用户数(5分钟)"

type: stat

query: "count(count by (user_id) (http_requests_total{...}[5m]))"

- title: "结账成功率"

type: gauge

query: "sum(rate(checkout_total{status='success'}[1h])) / sum(rate(checkout_total[1h]))"

thresholds: [95, 98, 99.5]

- title: "错误预算剩余"

type: gauge

query: "1 - (error_budget_consumed / error_budget_total)"

### L2:服务概览仪表板

每个服务都配备一个结构一致的仪表板:

row_1_traffic:

- "请求速率(rps)" — 时间序列,按状态码分组

- "错误率(%)" — 时间序列,设置 SLO 阈值线

- "当前活跃请求数" — 指标仪表盘

row_2_latency:

- "延迟分布" — 热力图

- "p50 / p95 / p99" — 时间序列,设置阈值线

- "各端点延迟" — 表格,按 p99 排序

row_3_dependencies:

- "下游延迟" — 按依赖项的时间序列

- "下游错误率" — 按依赖项的时间序列

- "数据库查询耗时" — 按查询类型的时间序列

row_4_resources:

- "CPU 使用率" — 按 Pod 的时间序列

- "内存使用率" — 按 Pod 的时间序列

- "Pod 重启次数" — 统计指标

row_5_business:

- "业务指标 1" — 服务特有

- "业务指标 2" — 服务特有

### 仪表板规则

1. **默认时间范围:最近 1 小时** — 大多数排查发生在近期
2. **顶部设置变量选择器**:环境、服务、实例
3. **统一颜色编码**:绿色=正常,黄色=降级,红色=异常,所有仪表板保持一致
4. **告警链接至仪表板** — 每个告警注释中包含仪表板 URL
5. **单个仪表板不超过 15 个面板** — 若超出则拆分为 L3 仪表板
6. **包含“截至”时间戳** — 确保事故截图可追溯
7. **仪表板即代码** — 将 Grafana JSON 存储在 Git 中,通过 API 自动化部署

---

## 阶段 7:事故响应

### 事故严重性分级

| 严重性 | 判定标准 | 响应要求 | 通知策略 |
|--------|----------|----------|----------|
| **SEV-1** | 服务不可用,数据丢失风险,安全事件 | 全员响应,设立应急指挥室 | 状态页每 15 分钟更新一次 |
| **SEV-2** | 服务降级,SLO 受到威胁,部分中断 | 值班人员 + 备岗支持 | 状态页每 30 分钟更新一次 |
| **SEV-3** | 轻微降级,存在临时解决方案 | 值班人员在工作时间内响应 | 内部 Slack 更新 |
| **SEV-4** | 外观问题,影响极小 | 下个迭代处理 | 无需通知 |

### 事故角色职责

| 角色 | 职责 | 人选 |
|------|------|------|
| **事故指挥官(IC)** | 主导事故处理。协调各方。做出关键决策。 | 值班负责人 |
| **技术负责人** | 诊断并修复问题。向 IC 汇报技术进展。 | 高级工程师 |
| **沟通负责人** | 更新状态页、Slack、外部干系人。 | 产品/支持团队 |
| **记录员** | 实时记录时间线、行动和决策。 | 任意可用成员 |

### 事故响应流程
  1. 检测

- 告警触发 → 值班人员被通知

- 客户报告 → 支持团队升级

- 内部发现 → 工程师主动上报

  1. 初步评估(前 5 分钟)

- 确认问题真实存在(排除误报)

- 判定严重等级(SEV-1 至 SEV-4)

- 开启事故频道:#inc-YYYY-MM-DD-简短描述

- 分配角色(IC、技术负责人、沟通负责人)

  1. 应急处置(接下来 5–30 分钟)

- 目标:立即止血,而非立即定位根因

- 可选操作(按顺序尝试):

a. 回滚最近一次发布

b. 扩容或重启 Pod

c. 关闭功能开关

d. 流量重定向或启用备用方案

e. 手动数据修复

- 记录每一步操作及时间戳

  1. 稳定化

- 确认缓解措施生效(指标恢复正常)

- 监控 15–30 分钟,确认无复发

- 更新状态页:“正在监控修复”

  1. 完全解决

- 确认所有指标持续健康超过 30 分钟

- 更新状态页:“已解决”

- 安排事后复盘(SEV-1/2 类事故需在 48 小时内完成)

- 向干系人发送内部总结报告

### 事故频道模板

📋 事故:支付 API 5xx 错误

🔴 严重性:SEV-2

🕐 开始时间:2026-02-22 14:23 UTC

👤 指挥官:@alice

🔧 技术负责人:@bob

📢 沟通负责人:@charlie

状态:正在处置

影响范围:约 5% 的结账请求失败

是否影响客户:是

时间线:

14:23 — 告警触发:PaymentAPIHighErrorRate

14:25 — 指挥官 @alice 确认,通过仪表板验证问题真实

14:28 — 技术负责人发现错误日志显示部署后连接池耗尽

14:31 — 回滚版本 v2.3.1 → v2.3.0

14:35 — 错误率下降,开始监控

14:50 — 错误率 <0.1%,标记为已解决

---

## 阶段 8:事后复盘框架

### 无责复盘模板

yaml
post_mortem:
  title: "支付 API 连接池耗尽"
  date: "2026-02-22"
  severity: SEV-2
  duration: 27 分钟(14:23 — 14:50 UTC)
  authors: ["@alice", "@bob"]
  reviewers: ["@engineering-leads"]
  status: action_items_in_progress

  summary: |
    14:15 的部署引入了支付 API 中的连接泄漏问题。
    连接池于 14:23 耗尽,导致约 5% 的结账请求出现 5xx 错误。
    14:31 开始回滚;14:50 恢复正常。

  impact:
    user_impact: "~340 名用户在 27 分钟内遭遇结账失败"
    revenue_impact: "$2,100 估算(基于平均订单金额 × 失败的结账次数)"
    slo_impact: "消耗了每月 21.9 分钟错误预算中的 5.1 分钟(占 23%)"
    data_impact: "无数据丢失。12 笔订单失败;用户可重试并成功完成"

  timeline:
    - time: "14:15"
      event: "部署 v2.3.1(3/3 个 Pod 已更新)"
    - time: "14:23"
      event: "PaymentAPIHighErrorRate 告警触发"
    - time: "14:25"
      event: "应急负责人(IC)指派,通过仪表盘确认"
    - time: "14:28"
      event: "根因定位:新 ORM 查询未释放连接"
    - time: "14:31"
      event: "开始回滚:v2.3.1 → v2.3.0"
    - time: "14:35"
      event: "错误率下降"
    - time: "14:50"
      event: "已解决:错误率持续低于 0.1%"

  root_cause: |
    v2.3.1 部署引入了订单验证路径中的新数据库查询。
    该查询使用了原始连接而非池管理的客户端,导致连接被获取但未释放。
    在负载下,连接池在 8 分钟内即耗尽。

  contributing_factors:
    - "缺乏对连接池行为在负载下的集成测试"
    - "连接池饱和指标存在,但未配置告警"
    - "代码审查未发现原始连接的使用"

  what_went_well:
    - "部署后 8 分钟内触发告警"
    - "应急负责人 2 分钟内指派"
    - "根因在 3 分钟内识别(日志清晰)"
    - "回滚操作顺利执行"

  what_went_wrong:
    - "部署后存在 8 分钟的检测延迟"
    - "未采用灰度发布,在全量上线前未能发现问题"
    - "连接池饱和状态无告警"

  action_items:
    - action: "添加连接池饱和告警(>80% 持续 2 分钟)"
      owner: "@bob"
      priority: P1
      due: "2026-02-25"
      status: in_progress
      ticket: "ENG-1234"
    - action: "为 payment-api 启用灰度发布"
      owner: "@alice"
      priority: P1
      due: "2026-03-01"
      ticket: "ENG-1235"
    - action: "添加 linting 规则:禁止应用代码中使用原始数据库连接"
      owner: "@charlie"
      priority: P2
      due: "2026-03-07"
      ticket: "ENG-1236"
    - action: "在预发环境对 payment-api 连接池进行负载测试"
      owner: "@bob"
      priority: P2
      due: "2026-03-07"
      ticket: "ENG-1237"

  lessons_learned:
    - "资源饱和指标需要告警,而不仅仅是仪表盘展示"
    - "对于 Tier 0 服务,灰度发布是强制要求"
    - "ORM 抽象不能保证连接安全——需审查原始查询"

---

### 事后分析会议议程(60 分钟)
  1. (5 分钟) 背景介绍 —— 应急负责人朗读摘要
  2. (15 分钟) 时间线回顾 —— 发生了什么、何时发生、由谁负责
  3. (15 分钟) 根因深入分析 —— 使用“五个为什么”方法
  4. (5 分钟) 做得好的地方 —— 表扬响应表现
  5. (15 分钟) 行动项 —— 明确负责人、优先级和截止日期
  6. (5 分钟) 总结 —— 确定行动项检查时间
---

### 五个为什么分析

问题:支付 API 出现 5xx 错误

为什么 1:数据库连接被耗尽

为什么 2:新查询获取了连接但未释放

为什么 3:查询使用了原始连接而非连接池管理器

为什么 4:ORM 的原始查询 API 不会自动释放(设计如此)

为什么 5:我们没有针对原始连接使用的 linting 规则或代码审查清单

根因:应用代码中缺少对原始连接使用的防护机制

系统性修复:增加 linting 规则 + 连接池饱和告警机制

---

## 第九阶段:值班运营

### 值班结构

on_call:

rotation: 每周轮换

handoff_day: 周一 10:00 UTC

primary:

response_time: 5 分钟(SEV-1/2),30 分钟(SEV-3)

escalation_after: 15 分钟未确认响应

secondary:

response_time: 15 分钟(SEV-1),1 小时(SEV-2/3)

escalation_after: 30 分钟未确认响应

manager_escalation:

trigger: SEV-1 事件在 30 分钟内未解决

handoff_checklist:

- 查看当前待处理事件和活跃告警

- 检查所有服务的错误预算状态

- 阅读上周的事故复盘报告

- 确认 PagerDuty 排班和联系信息准确

- 测试告警路由(发送测试通知)

### 值班健康指标

| 指标 | 健康 | 需关注 | 不健康 |
|------|------|--------|--------|
| 每周告警次数 | <5 | 5-15 | >15 |
| 每周非工作时间告警次数 | <2 | 2-5 | >5 |
| 误报率 | <10% | 10-30% | >30% |
| 平均响应时间 | <5 分钟 | 5-15 分钟 | >15 分钟 |
| 平均解决时间 | <30 分钟 | 30-120 分钟 | >120 分钟 |
| 事务性工作比例(手动 vs 自动化) | <30% | 30-60% | >60% |

### 每周值班复盘模板

on_call_review:

week: "2026-W08"

engineer: "@bob"

incidents:

total: 7

sev_1: 0

sev_2: 1

sev_3: 4

false_positives: 2

after_hours: 3

time_spent:

incident_response: "4.5 小时"

toil_automation: "2 小时"

runbook_updates: "1 小时"

improvements_made:

- "静音开发环境磁盘告警"

- "为 Pod 重启阈值添加自动修复功能"

improvements_needed:

- "缓存过期告警每周二凌晨 03:00 触发 —— 需调查原因"

- "支付重试逻辑需引入熔断机制(导致 3 次告警)"

handoff_notes: |

关注 payment-api 的 p99 延迟 —— 自周三起持续上升。

Stripe 更改了沙箱端点;预发环境可能出现错误。

阶段 10:混沌工程与可靠性测试

混沌工程原则

  1. 从假设开始:“如果 X 失效,系统应能 Y”
  2. 在生产环境运行(从小范围开始——单个实例、单个可用区)
  3. 通过自动回滚最小化影响范围
  4. 逐步建立信心:从预发环境 → 灰度发布 → 生产环境

混沌实验模板

chaos_experiment:
  name: "支付数据库故障转移"
  hypothesis: "如果主数据库不可用,流量应在 30 秒内切换到副本,且错误率上升低于 1%"

  steady_state:
    - metric: "checkout_success_rate"
      expected: ">99.5%"
    - metric: "db_query_duration_p99"
      expected: "<200ms"

  injection:
    type: "network_partition"
    target: "payment-db-primary"
    duration: "5 minutes"
    blast_radius: "single AZ"

  abort_conditions:
    - "checkout_success_rate < 95% 持续超过 60 秒"
    - "每分钟收入下降超过 50%"
    - "任何 SEV-1 事件被宣布"

  results:
    failover_time: "22 seconds"
    error_spike: "0.3% 持续 25 秒"
    hypothesis_confirmed: true

  follow_up_actions:
    - "在运行手册中记录故障转移行为"
    - "将故障转移时间作为 SLI(目标:<30s)"

混沌工程成熟度等级

等级测试内容工具
1:手动手动删除 Pod,观察系统反应kubectl delete pod
2:自动化定期删除 Pod、网络延迟注入Chaos Monkey, Litmus
3:演练日多故障场景下的团队协作演练自定义脚本 + 协调机制
4:持续性生产环境中自动执行混沌并支持自动回滚Gremlin, Chaos Mesh

阶段 11:可观测性成本优化

成本驱动因素(按优先级排序)

#驱动因素典型占比优化建议
1日志量40-60%降低日志级别,丢弃 DEBUG 信息,对重复日志采样
2指标基数15-25%清理无用指标,限制标签数量
3跟踪数据量10-20%采用采样策略,使用尾部采样
4数据保留周期10-15%分层存储(热 → 温 → 冷)
5查询成本5-10%优化仪表盘查询,设置最大扫描限制

成本削减检查清单

cost_optimization:
  logs:
    - action: "在生产环境丢弃 DEBUG/TRACE 日志"
      savings: "日志量减少 30-50%"
    - action: "对健康检查日志进行采样(1:100)"
      savings: "日志量减少 5-15%"
    - action: "去重相同错误的集中爆发"
      savings: "故障期间减少 10-20%"
    - action: "将超过 7 天的日志移至 S3/冷存储"
      savings: "存储成本降低 60-80%"
    - action: "关闭请求/响应体日志记录"
      savings: "日志量减少 20-40%"

  metrics:
    - action: "审计未使用的指标(无仪表盘、无告警)"
      savings: "指标系列减少 10-30%"
    - action: "减少直方图桶数量(默认 11 → 8)"
      savings: "直方图系列减少约 27%"
    - action: "移除高基数标签"
      savings: "可变 —— 降幅可能极大"
    - action: "提高非关键指标的采集间隔(15s → 60s)"
      savings: "相关指标数据点减少 75%"

  traces:
    - action: "实施尾部采样"
      savings: "跟踪数据量减少 80-95%"
    - action: "丢弃内部健康检查的跟踪数据"
      savings: "跟踪数据量减少 5-20%"
    - action: "减小跨度属性大小(截断长字符串)"
      savings: "跟踪存储减少 10-30%"

  general:
    - action: "每季度审查并合理调整保留策略"
    - action: "在仪表盘中设置查询超时和结果上限"
    - action: "对高开销查询使用记录规则"

每月可观测性成本审查模板

observability_cost_review:
  month: "2026年2月"
  total_cost: "$X,XXX"

  breakdown:
    logs: { volume: "X TB", cost: "$X", pct: "X%" }
    metrics: { series: "X 百万", cost: "$X", pct: "X%" }
    traces: { volume: "X TB", cost: "$X", pct: "X%" }
    infrastructure: { instances: X, cost: "$X", pct: "X%" }

  cost_per:
    request: "$0.000X"
    service: "$X 平均"
    engineer: "$X 每位工程师"

  optimizations_applied: []
  optimizations_planned: []
  budget_status: "on_track | over_budget | under_budget"

阶段 12:高级模式

关联:连接三大支柱

每个日志条目包含:trace_id, span_id
每个跟踪跨度包含:service, operation
每个指标包含:service 标签

关联路径:
  告警触发(指标)→ 点击 → 仪表盘(指标)→ 按时间窗口筛选
    → 跟踪搜索(同服务 + 同时间)→ 定位失败的跟踪
    → 日志(按 trace_id 过滤)→ 查看具体错误信息

  支持工单(用户反馈)→ 在日志中查找 request_id
    → 提取 trace_id → 查看完整跟踪 → 定位慢的跨度
    → 检查该跨度的服务指标 → 验证模式是否存在

合成监控

synthetic_checks:
  - name: "结账流程"
    type: browser
    frequency: 5m
    locations: [us-east, eu-west, ap-southeast]
    steps:
      - navigate: "https://app.example.com/products"
      - click: "加入购物车"
      - click: "结账"
      - assert: "订单确认页面加载时间 <3秒"
    alert_on: "同一位置连续两次失败"

  - name: "API 健康状态"
    type: api
    frequency: 1m
    endpoints:
      - url: "https://api.example.com/health"
        expected_status: 200
        max_latency_ms: 500
      - url: "https://api.example.com/v1/products?limit=1"
        expected_status: 200
        max_latency_ms: 1000

特性开关可观测性

# 将特性开关与指标关联
feature_flag_monitoring:
  - flag: "new_checkout_flow"
    metrics_to_compare:
      - "checkout_conversion_rate" # 按开关版本对比
      - "checkout_error_rate"
      - "checkout_latency_p99"
    alerts:
      - "若新版本错误率 > 控制版本的 2 倍,则自动禁用该特性开关"

可观测性成熟度模型

可观测性与可靠性工程

能力维度分级

维度等级 1等级 2等级 3等级 4
日志非结构化日志结构化 JSON,集中存储与链路追踪关联自动化日志分析
指标基础基础设施指标服务级 RED/USE 指标基于 SLO 的指标,含错误预算预测性(异常检测)
链路追踪无追踪关键服务已接入全链路分布式追踪基于追踪的测试
告警固定阈值多信号告警基于 SLO 的燃烧率自动修复
事故响应临时处理有流程和角色定义有行动项跟踪的复盘报告生产环境混沌工程
文化“运维团队负责”共同责任(你构建,你运行)基于 SLO 的开发速度可靠性作为功能特性

质量评分标准(0-100)

维度权重0510
日志质量15%非结构化,无关联结构化 JSON,字段缺失完整 Schema,支持链路关联,敏感信息脱敏
指标覆盖15%无指标仅使用 RED 或 USERED + USE + 业务指标 + 自定义指标
链路追踪完整性10%无追踪关键服务全路径覆盖,采样策略,尾部采样
SLO 成熟度15%无可靠性目标非正式目标包含错误预算、燃烧率告警、每周评审
告警质量15%噪音大或缺失可操作,部分运行手册基于 SLO,完整运行手册,低误报率
事故响应10%临时处理有流程完整流程、角色分工、复盘报告、混沌工程
仪表板设计10%无仪表板基础面板分层 L1-L4,风格统一,与告警联动
成本效率10%成本未知已跟踪优化并每月审查,控制在预算内

90-100:世界级水平。可指导他人。

70-89:生产就绪。填补特定短板。

50-69:基本可用但脆弱。

<50:存在重大可靠性风险。


10 条可观测性戒律

  1. 结构化,否则等于不存在 — 非结构化日志是技术债
  2. 一切都要关联trace_id 将日志、链路和指标串联起来
  3. 告警症状,而非原因 — 用户不关心 CPU 使用率,只关心延迟
  4. 每个告警必须有运行手册 — 无运行手册 = 无告警
  5. SLO 驱动开发速度 — 错误预算决定何时发布或稳定
  6. 仪表板要有层级 — 高管不需要查看 Pod CPU 图表
  7. 永远采用无责复盘 — 归咎于人会阻碍学习
  8. 成本也是一种特性 — 让公司破产的可观测性不是真正的可观测性
  9. 你构建,你运行 — 发布代码的团队需承担其可观测性责任
  10. 主动练习失败 — 混沌工程提升系统信心

12 个自然语言指令

指令功能说明
"审计我们的可观测性"执行 /16 健康检查,评估各维度得分,识别优先改进项
"为 [服务] 设计日志方案"生成该服务的结构化日志 Schema,包含上下文字段
"为 [服务] 设置指标"制定 RED + USE + 业务指标的埋点实施计划
"为 [服务] 创建 SLO"定义 SLI、目标值、错误预算及燃烧率告警规则
"为 [服务] 设计告警"创建带严重等级、阈值和运行手册模板的告警规则
"为 [服务] 构建仪表板"设计 L2 级服务概览仪表板,明确面板配置
"为 [告警] 编写运行手册"生成结构化运行手册,包含诊断步骤与解决方案
"为 [事故] 进行复盘"生成无责复盘文档,包含时间线与待办事项
"为 [团队] 设置值班制度"设计轮班机制、升级策略与交接清单
"规划 [场景] 的混沌实验"设计实验,包含假设、注入方式与终止条件
"优化可观测性成本"审计当前支出,识别主要节省点,制定降本计划
"为 [系统] 设计链路追踪"制定 OpenTelemetry 埋点方案,含采样策略

⚡ 提升你的可观测性能力

本技能提供方法论。如需行业落地模式:

  • SaaS 公司:[AfrexAI SaaS 场景包 ($47)](https://afrexai-cto.github.io/context-packs/) — 包含 SaaS 特有的 SLO、多租户监控、基于用量的计费可观测性
  • 金融科技:[AfrexAI Fintech 场景包 ($47)](https://afrexai-cto.github.io/context-packs/) — 合规审计日志、交易监控、欺诈检测信号
  • 医疗健康:[AfrexAI Healthcare 场景包 ($47)](https://afrexai-cto.github.io/context-packs/) — HIPAA 审计轨迹、PHI 访问日志、高可用要求

🔗 AfrexAI 其他免费技能

  • afrexai-devops-engine — CI/CD、基础设施、部署策略
  • afrexai-api-architect — API 设计、安全、版本管理
  • afrexai-database-engineering — Schema 设计、查询优化、迁移
  • afrexai-code-reviewer — 使用 SPEAR 框架的代码审查方法
  • afrexai-prompt-engineering — 系统提示词设计、测试与优化

浏览全部 AfrexAI 技能:[clawhub.com](https://clawhub.com) | [完整商品页](https://afrexai-cto.github.io/context-packs/)

1
@1kalin

已收录 14 个 Skill

相关推荐