2. OpenTelemetry 核心概念:理解 Trace、Span、Metrics、Logs 以及 Context Propagation 的基本原理

在接入值班机器人实现事件触发告警之前,必须理解 OpenTelemetry 的四大信号(Signals)以及它们如何协同工作。本章将拆解 Trace、Span、Metrics、Logs 的定义,并重点讲解 Context Propagation(上下文传播)——这是分布式追踪能够跨服务串联的基石。

2.1 四大信号(Signals)概览

OpenTelemetry 将可观测性数据抽象为四种标准信号,每种信号解决不同维度的观测问题:

信号 核心作用 典型问题 数据形态
Traces 追踪请求在分布式系统中的完整路径 请求为什么慢?哪个服务出错了? 树状 Span 结构
Metrics 聚合统计系统运行指标 CPU 使用率多少?QPS 是否异常? 时间序列数值
Logs 记录离散的事件与错误详情 具体报错信息是什么?堆栈是什么? 带时间戳的文本记录
Baggage 跨服务传递键值对上下文 用户 ID、会话 ID 如何透传? 键值对(K/V)
关键认知: 在告警场景中,Traces 用于定位故障链路,Metrics 用于触发阈值告警,Logs 用于告警后的根因分析。三者结合才能形成完整的告警闭环。

2.2 Trace 与 Span:分布式追踪的骨架

Trace 代表一个完整的请求生命周期,从入口到所有下游依赖的结束。一个 Trace 由多个 Span 组成,Span 是追踪的最小工作单元。

每个 Span 包含以下关键属性:

  • Span Name:操作名称,例如 HTTP GET /api/orders。
  • Span ID:当前 Span 的唯一标识。
  • Trace ID:整个 Trace 的唯一标识,所有 Span 共享。
  • Parent Span ID:父 Span 的 ID,用于构建父子层级关系。
  • Start / End Timestamp:开始与结束时间,用于计算延迟。
  • Attributes:键值对元数据,例如 http.status_code=200。
  • Events:Span 生命周期内的带时间戳事件,例如异常记录。
  • Status:成功/错误状态。
告警关联: 当值班机器人收到告警时,可以通过 Trace ID 快速关联到具体的请求链路,查看是哪个 Span 出现了错误或高延迟,从而精准定位故障服务。
Trace 与 Span 树状结构示例 Root Span: API Gateway Child Span: Auth Service Child Span: Order Service Child Span: Payment Service Grandchild Span: DB Query Trace ID: abc123 共享给所有 Span | 每个 Span 记录自己的开始/结束时间与状态 通过 Parent Span ID 形成树状层级,Root Span 是整个请求的入口

2.3 Metrics:聚合指标的告警基石

Metrics 是经过聚合的数值型数据,适合用于阈值告警。OpenTelemetry 支持三种主要 Metric 类型:

  • Counter(计数器):只增不减,例如请求总数、错误总数。
  • Histogram(直方图):记录值的分布,例如请求延迟的 P50/P99。
  • Gauge(仪表盘):可增可减,例如当前内存使用量、活跃连接数。
告警实践注意: 不要对 Histogram 直接设置固定阈值告警,建议使用百分位(P99)或滑动窗口聚合后的指标。Counter 适合用于“错误率超过 X%”的告警规则。

2.4 Logs:事件记录的细节补充

Logs 是最传统的可观测性信号,在 OpenTelemetry 中 Logs 可以与 Traces 关联。通过 trace_id 和 span_id 字段,可以将日志记录绑定到特定的 Span 上。

结构化日志示例:

{
  "timestamp": "2025-03-21T10:30:00.123Z",
  "severity": "ERROR",
  "body": "Database connection timeout",
  "attributes": {
    "service.name": "order-service",
    "trace_id": "abc123",
    "span_id": "span456",
    "db.system": "postgresql"
  }
}
告警联动: 当 Metrics 触发告警后,值班机器人可以自动拉取关联 Trace ID 的 Logs,帮助值班人员快速判断是代码 Bug、配置错误还是基础设施故障。

2.5 Context Propagation:串联一切的纽带

Context Propagation(上下文传播)是 OpenTelemetry 最核心的机制。它确保一个请求在跨越多个服务、线程或异步边界时,Trace ID、Span ID 以及 Baggage 能够被正确传递。

传播机制分为两部分:

组件 作用 实现方式
Propagator 将上下文注入到出站请求,并从入站请求中提取上下文 HTTP Headers(如 traceparent)、gRPC Metadata、消息队列属性
Context 存储当前请求的 Trace ID、Span ID 和 Baggage 语言特定的上下文对象(如 Python 的 contextvars)

W3C TraceContext 标准定义了 HTTP 传播的 Header 格式:

traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
              ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^
             版本          Trace ID                    Span ID      Trace Flags
Context Propagation 跨服务传播流程 Service A (Frontend) Service B (Auth) Service C (Database) Inject Inject Context Propagation 流程 1. Service A 创建 Trace ID,将上下文注入 HTTP Header (traceparent) 2. Service B 从 Header 提取上下文,创建子 Span,继续向下游注入 3. 所有 Span 共享同一个 Trace ID,最终汇聚到后端实现链路关联

2.6 四大信号与告警的协同关系

在值班机器人告警场景中,四种信号不是孤立的,而是形成以下协同链路:

  1. Metrics 触发告警:例如错误率突增超过 5%,Prometheus 发出 Alert。
  2. 告警携带 Trace ID:告警消息中包含当前异常的 Trace ID。
  3. 值班机器人查询 Trace:通过 Trace ID 获取完整的 Span 列表,定位到具体故障服务。
  4. 关联 Logs 分析根因:从故障 Span 中提取关联的 Logs,查看详细错误堆栈。
  5. Baggage 传递业务上下文:例如用户 ID、订单 ID,帮助值班人员快速理解影响范围。
最佳实践: 在告警通知中至少包含 trace_id 和 service.name 两个字段,这样值班人员可以直接从告警消息跳转到链路追踪系统,无需手动搜索。

2.7 本章小结

  • Trace 由多个 Span 组成树状结构,描述请求的完整路径。
  • Metrics 提供聚合指标,是阈值告警的主要数据源。
  • Logs 记录离散事件,通过 trace_id 与 Trace 关联。
  • Context Propagation 通过 W3C TraceContext 标准,确保跨服务传递 Trace ID 和 Span ID。
  • 四种信号协同工作,才能构建高效的告警与根因分析体系。