可观测性三大支柱深度解析:指标、日志、追踪

系统性梳理可观测性三大支柱(Metrics/Logs/Traces)的核心概念、数据模型、采集范式和适用场景。对比维度覆盖数据类型、查询方式、存储成本、采样策略、告警响应、根因定位。延伸至事件(Events)、剖析(Profiling)、真实用户监控(RUM)等第四/第五支柱,构建完整的云原生可观测性认知框架。

「监控是别人告诉你哪里坏了,可观测性是你自己发现为什么坏了。」 — Charity Majors(Honeycomb CEO)

传统监控(Monitoring)问的是:“系统是不是正常工作?“可观测性(Observability)问的是:“系统为什么是现在这样?“这两个层次的区别,决定了从被动告警到主动探索的根本转变。


一、可观测性的定义

1.1 核心定义

可观测性是系统的一种性质:通过其外部输出(指标、日志、追踪)就能推断其内部状态,无需额外部署代码或注入探针。

可观测性的本质:
  系统内部状态 ──可观测性──→ 外部输出
                                 ├── Metrics(聚合数值)
                                 ├── Logs(离散事件文本)
                                 └── Traces(请求链路图谱)

开发者通过这些输出回答:
  - 哪里慢?(Latency/延迟)
  - 哪里坏了?(Error/错误)
  - 有多少流量?(Traffic/流量)
  - 系统饱和了吗?(Saturation/饱和度)
  → Google SRE 的 "Four Golden Signals"

1.2 监控 vs 可观测性

维度监控(Monitoring)可观测性(Observability)
目标检测已知问题探索未知问题
问题类型「如果 X 发生则报警」「系统为什么是现在这样?」
数据使用预定义仪表板和告警临时查询、钻取、关联
工具Zabbix/NagiosPrometheus + Grafana + Jaeger + Loki
思维模式被动告警主动探索
前置条件预设故障模式高基数、高维度数据

二、第一支柱:Metrics(指标)

2.1 什么是指标

指标是随时间聚合的数值测量,回答"有多少/多长时间/多频繁"类问题。

指标的本质:时间序列数据
(timestamp, value, {label1=v1, label2=v2})

示例:
  http_requests_total{method="GET", status="200", route="/api/users"} = 15234
  cpu_usage_percent{instance="web-01", core="0"} = 45.2
  disk_io_bytes{direction="read", device="sda"} = 1024000

2.2 指标类型

类型说明示例适用场景
Counter单调递增(可重置)请求总数、错误总数、发送字节数累计量
Gauge可增可减当前温度、内存使用量、队列长度瞬时值
Histogram采样分布,自动分桶请求延迟分布、请求体大小分布SLA/SLO 分析
Summary分位数计算(客户端计算)p50/p99 延迟精确分位数(客户端成本高)

2.3 指标的数据模型

Prometheus 数据模型:
  metric_name{label1="value1", label2="value2"} value timestamp

  http_requests_total{method="POST", status="500", handler="/checkout"}  17  1690000000
  ↑ metric name     ↑ labels (key-value pairs)                           ↑ value   ↑ ts

高基数问题:
  ❌ user_requests_total{user_id="12345"}
     → user_id 有几万个值,cardinality 爆炸,存储和查询变慢

  ✅ user_requests_total 只按 method、status、route 分维度
     → user_id 放入 Logs/Traces

2.4 指标适合的问题

✅ 适合:
  - "过去 5 分钟的平均请求延迟是多少?"
  - "哪个服务的错误率最高?"
  - "CPU 使用率的趋势是什么?"
  - "按地区划分的 QPS 分布?"

❌ 不适合:
  - "这个用户的某个请求为什么失败了?" → 需要 Logs/Traces
  - "具体的错误堆栈是什么?" → 需要 Logs

三、第二支柱:Logs(日志)

3.1 什么是日志

日志是带有时间戳的离散事件记录,回答"发生了什么/在什么上下文/什么顺序"类问题。

{
  "timestamp": "2026-08-13T14:32:01.234Z",
  "level": "ERROR",
  "service": "payment-svc",
  "trace_id": "abc123",
  "span_id": "def456",
  "message": "Payment processing failed",
  "error": "timeout connecting to bank API",
  "user_id": "user_789",
  "order_id": "order_456",
  "duration_ms": 30000,
  "retry_count": 3,
  "context": {
    "amount": 199.99,
    "currency": "CNY",
    "payment_method": "alipay"
  }
}

3.2 日志级别

级别使用场景生产环境比例
DEBUG开发调试,详细流程关闭
INFO关键流程节点70%
WARN异常但能恢复20%
ERROR功能失败需干预9%
FATAL系统崩溃<1%

3.3 结构化日志 vs 非结构化日志

非结构化(❌ 难解析):
  2024-08-13 14:32:01 [ERROR] Payment failed for user=user_789, order=order_456,
  amount=199.99, reason=timeout

结构化(✅ 可索引、可查询):
  {"timestamp":"2024-08-13T14:32:01Z","level":"ERROR","event":"payment_failed",
   "user_id":"user_789","order_id":"order_456","amount":199.99,"reason":"timeout"}

3.4 日志适合的问题

✅ 适合:
  - "这个订单在支付环节出了什么错误?"
  - "系统在这个时间点有什么异常?"
  - "完整的请求处理流程是什么样的?"
  - "找出所有涉及这个用户的操作记录"

❌ 不适合:
  - "过去一小时的平均响应时间?" → Metrics 更高效
  - "这个请求经过了哪些服务?" → Traces 更直观

四、第三支柱:Traces(追踪)

4.1 什么是追踪

追踪是记录请求在分布式系统中完整路径的因果链,回答"请求去了哪里/每个环节花了多久/哪里是瓶颈”。

Trace(追踪)= 一次端到端请求
  ├── Trace ID(全局唯一)
  └── Spans(片段,描述每个操作)
      ├── Span ID
      ├── Parent Span ID(形成树形结构)
      ├── Operation Name
      ├── Start/End Time → Duration
      ├── Tags(元数据:service、method、status)
      ├── Logs(事件:如 "cache miss")
      └── SpanContext(传播到下游)

示例 Trace:
[ Trace: trace_abc ]
├── [Span: GET /api/checkout]  0ms-200ms  service=ui
│   ├── [Span: validate-cart]  5ms-25ms   service=cart-svc
│   ├── [Span: process-payment] 30ms-180ms  service=payment-svc
│   │   ├── [Span: check-inventory] 35ms-60ms  service=inventory-svc
│   │   ├── [Span: auth-user]     65ms-95ms   service=auth-svc
│   │   └── [Span: call-bank]     100ms-170ms service=payment-svc
│   └── [Span: send-email]      185ms-195ms service=notification-svc

4.2 头传播与上下文传递

请求头中的追踪上下文:
  traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
  tracestate: rojo=00f067aa0ba902b7,congo=t61rcWkgMzE

  traceparent 格式:
  {version}-{trace_id}-{parent_id}-{trace_flags}
    version   = 00
    trace_id  = 16 bytes hex(全局唯一)
    parent_id = 8 bytes hex(当前 span id)
    trace_flags = 01(sampled)/ 00(未采样)

4.3 采样策略

策略说明适用
头部采样决定整棵树是否采集简单、低开销
概率采样随机采集 1% / 0.1%高吞吐量系统
尾部采样采集全部,保留异常的 Span存储成本高但精准
自适应采样根据流量动态调整智能但复杂

4.4 追踪适合的问题

✅ 适合:
  - "这个慢请求在哪个服务花了最多时间?"
  - "服务 A 调用服务 B 的延迟分布?"
  - "两个服务之间的调用关系是什么样的?"
  - "找到所有经过支付服务且响应时间 > 2s 的请求"

❌ 不适合:
  - "系统的总请求量是多少?" → Metrics
  - "查看请求的原始响应体?" → Logs

五、三大支柱对比

维度MetricsLogsTraces
数据形态时间序列数值离散结构化文本因果树状结构
存储成本低(聚合度高)高(原始数据量大)中(取决于采样率)
查询速度毫秒级秒级(需索引)毫秒-秒级
基数(Cardinality)低(可控标签)高(每条记录独特)中(Trace ID + Spans)
最佳问题“有多少/频率/趋势”“发生了什么/上下文”“请求去了哪里/瓶颈”
告警能力最强
根因定位指出方向提供细节定位位置
代表工具Prometheus/VictoriaMetricsLoki/ELK/SplunkJaeger/Tempo/Zipkin

六、第四/第五支柱

6.1 Events(事件)

事件是对系统行为更有意义的抽象,介于日志和追踪之间。“用户购买完成"是一个事件,由多个日志和 Spans 组成。

{
  "event_type": "user_purchase_completed",
  "timestamp": "2026-08-13T10:00:00Z",
  "user_id": "u123",
  "order_id": "o456",
  "total_amount": 299.99,
  "payment_method": "wechat_pay",
  "items_count": 3,
  "duration_ms": 2500,
  "trace_id": "trace_abc"
}

6.2 Profiling(剖析/性能分析)

Continuous Profiling(持续性能分析):
├── CPU Profiling — 找出热点函数
├── Memory Profiling — 内存分配分析
├── Goroutine/Thread Profiling — 并发分析
├── Block/Mutex Profiling — 锁竞争分析
└── IO Profiling — 磁盘/网络 IO 分析

工具:
  - Go: pprof(内置)
  - Java: async-profiler
  - Python: py-spy
  - 通用: Parca, Pyroscope, Grafana Profiles

6.3 RUM(Real User Monitoring)

RUM = 从真实用户浏览器采集性能数据
├── 页面加载时间(Web Vitals: LCP, INP, CLS)
├── 请求延迟(API Response Time)
├── JS 错误(Error Rate)
├── 会话回放(Session Replay)
└── 用户路径分析

工具:Datadog RUM, New Relic Browser, Sentry Performance

七、实际场景:如何选择工具

场景:收到告警「支付服务 P99 延迟 > 2s」

排查流程:
1. Metrics → 确认问题范围和影响
   - "P99 延迟确实从 500ms 飙升到 3s"
   - "只影响 /v2/payments 接口,其他接口正常"
   - "问题从 14:32 开始,持续 15 分钟"

2. Traces → 定位延迟发生在哪个环节
   - "trace_id: abc123 显示总延迟 3.2s"
   - "调用银行接口占 2.8s(正常 200ms)"
   - "银行服务是瓶颈"

3. Logs → 获取错误细节和上下文
   - "call-bank 日志显示连接超时"
   - "银行服务商 14:30-14:50 维护公告"

4. Metrics → 验证恢复情况
   - "14:50 后延迟恢复正常"

---

结论:Metrics 发现问题,Traces 定位位置,Logs 解释原因

八、可观测性成熟度模型

Level 1: 基础监控
  ├── 使用传统监控工具(Nagios/Zabbix)
  ├── 基于阈值的简单告警
  └── 事后排查靠 SSH 登机器查日志

Level 2: 指标驱动
  ├── Prometheus + Grafana
  ├── Dashboard 覆盖核心指标
  ├── 告警基于 Four Golden Signals
  └── 有基本的指标查询能力

Level 3: 全链路可观测
  ├── Metrics + Logs + Traces 三支柱齐全
  ├── OpenTelemetry 标准化
  ├── 日志结构化
  ├── 分布式追踪覆盖核心链路
  └── 告警降噪 + 分优先级

Level 4: 数据驱动 SRE
  ├── SLO/SLI 定义清晰
  ├── 错误预算管理
  ├── Burn Rate 告警
  ├── 自动化运维
  └── 事后复盘变成常态

Level 5: 智能可观测
  ├── 异常检测(非阈值)
  ├── 根因自动关联
  ├── 容量预测
  ├── 自动修复(Self-healing)
  └── AI 辅助决策

参考与延伸阅读

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「infra」更多文章

  1. 可观测性数据存储选型:TSDB、列式存储、对象存储与成本优化
  2. 云原生 APM 与性能剖析:Continuous Profiling 与火焰图
  3. Kubernetes 可观测性实战:集群、Pod、网络、存储全链路监控