2. OpenTelemetry 核心概念:Trace、Span、Metric、Log、Context Propagation

OpenTelemetry(简称 OTel)是 CNCF 孵化的可观测性标准框架,它统一了遥测数据的采集、关联与导出规范。要构建值班机器人的自动化诊断能力,必须理解其五大核心概念:Trace、Span、Metric、Log 和 Context Propagation。这五者共同构成了从“发生了什么”到“为什么发生”的完整数据链路。

2.1 核心概念总览

下表从定义、用途、数据形态三个维度对比五大概念,帮助建立全局认知:

概念 定义 核心用途 数据形态
Trace 一次请求或事务在分布式系统中的完整路径 端到端延迟分析、依赖关系发现 树状结构,由多个 Span 组成
Span Trace 中的单个工作单元,代表一个操作 定位瓶颈、记录操作属性与事件 包含名称、开始/结束时间、属性、状态
Metric 可聚合的数值测量,如计数、直方图 系统健康监控、告警阈值、容量规划 时间序列数据点,带标签
Log 带时间戳的结构化或非结构化文本记录 详细事件排查、异常堆栈追踪 记录行,可关联 TraceId/SpanId
Context Propagation 跨进程/服务传递 Trace 上下文信息的机制 保证 Trace 完整性,串联上下游 W3C TraceContext 等协议头
值班机器人视角: 当告警触发时,机器人首先通过 Metric 发现异常(如 P99 延迟飙升),然后通过 Trace 定位到具体服务,再深入 Span 查看操作细节,最后结合关联的 Log 获取错误堆栈。Context Propagation 确保这一系列数据能够跨服务串联。

2.2 Trace 与 Span:分布式追踪的基石

Trace 是一个端到端的请求生命周期,它由多个 Span 组成的有向无环图(DAG)。每个 Span 代表一个具名操作,例如“数据库查询”、“HTTP 调用”或“消息队列发送”。Span 之间通过 父-子关系 形成层级结构。

一个 Span 包含以下关键字段:

  • SpanId:全局唯一标识该 Span。
  • TraceId:标识该 Span 所属的 Trace。
  • ParentSpanId:父 Span 的 ID,根 Span 此字段为空。
  • Name:操作名称,如 HTTP GET /api/users。
  • StartTime / EndTime:操作的时间范围。
  • Attributes:键值对元数据,如 http.method、db.system。
  • Events:带时间戳的注解,用于记录异常或关键节点。
  • Status:操作结果状态(OK / Error / Unset)。
关键原则: 一个 Trace 只有一个根 Span(Root Span),根 Span 没有父 Span。所有子 Span 通过 ParentSpanId 回溯到根,形成完整的调用链。
Trace 与 Span 树状结构示例 Root Span: /checkout TraceId: abc123 Span: auth.verify Parent: Root Span: cart.load Parent: Root Span: payment.charge Parent: Root Span: db.query.items Parent: cart.load 每个 Span 记录一个操作的时间、属性和状态,通过 ParentSpanId 形成调用链树。

2.3 Metric:聚合的量化视图

与 Trace 关注“单个请求路径”不同,Metric 关注的是“聚合后的系统状态”。OpenTelemetry 定义了三种核心 Metric 类型:

Metric 类型 语义 典型场景 示例
Counter 单调递增的计数,只增不减 请求总数、错误总数 http.requests.total
Histogram 对观测值进行分桶统计 请求延迟分布、响应大小分布 http.request.duration
Gauge 可上下波动的瞬时值 CPU 使用率、内存占用、队列深度 system.memory.usage
值班机器人告警设计要点: 不要仅依赖 Gauge 设置固定阈值。结合 Histogram 的 P99/P90 分位数,可以更早发现长尾延迟问题。例如,当 http.request.duration 的 P99 超过 500ms 时触发告警,比单纯的平均值告警更有效。

2.4 Log:事件记录的锚点

在 OpenTelemetry 体系中,Log 不再是孤立的文本流。通过 TraceId 和 SpanId 字段,Log 可以与 Trace 和 Span 建立关联,形成“可观测性信号关联”。

一个 OTel 结构化 Log 记录通常包含:

  • Timestamp:日志产生时间。
  • Body:日志正文,可以是字符串或结构化对象。
  • SeverityNumber / SeverityText:日志级别(如 ERROR、INFO)。
  • TraceId / SpanId:关联到当前请求的追踪上下文。
  • Attributes:自定义键值对,如 service.name、error.type。
最佳实践: 在代码中记录错误日志时,务必通过 OpenTelemetry API 获取当前活跃的 TraceId 和 SpanId,并写入日志属性。这样在值班机器人诊断时,可以从告警 Metric 直接跳转到关联的 Trace 和 Log,无需手动搜索。

2.5 Context Propagation:串联一切的纽带

Context Propagation 是分布式追踪能够跨服务工作的核心机制。它确保当一个请求从服务 A 调用服务 B 时,TraceId 和 SpanId 能够被正确传递,从而在 B 中创建的子 Span 能够挂接到 A 的 Span 下。

OpenTelemetry 默认使用 W3C TraceContext 标准,通过 HTTP 头 traceparent 和 tracestate 传递上下文:

# traceparent 格式:版本- TraceId - SpanId - TraceFlags
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01

# tracestate 用于携带供应商特定的元数据
tracestate: rojo=00f067aa0ba902b7,congo=t61rcWkgMzE

传播过程分为两个阶段:

  1. 注入(Inject):在客户端(如 HTTP 请求发起方)将当前上下文写入传播载体(如 HTTP 头)。
  2. 提取(Extract):在服务端从传播载体中读取上下文,并设置为当前活跃上下文。
Context Propagation 跨服务传递流程 服务 A (前端) Span: /api/order TraceId: abc 服务 B (订单) Span: create.order TraceId: abc HTTP 请求 traceparent: 00-abc-xxx-01 (注入到 HTTP 头) 服务 B 提取上下文 创建子 Span

2.6 信号关联:值班机器人的诊断数据模型

在值班机器人场景中,五大概念并非孤立存在,而是通过 TraceId 和 资源属性 紧密关联。下图展示了告警触发后的数据关联路径:

关联流程:
  1. Metric 告警:Prometheus 等监控系统检测到 http.request.duration 的 P99 超过阈值,触发告警。
  2. Trace 定位:告警携带的标签(如 service.name、endpoint)用于过滤 Trace,找到延迟最高的 Trace。
  3. Span 分析:在 Trace 中查看各 Span 的耗时,定位到慢 Span(如数据库查询)。
  4. Log 排查:通过慢 Span 的 TraceId 和 SpanId,关联查询对应的结构化日志,获取错误详情或慢查询 SQL。

这种关联能力使得值班机器人能够自动执行“告警 → 追踪 → 日志”的诊断流水线,大幅缩短平均修复时间(MTTR)。

2.7 本章小结

  • Trace 和 Span 提供了请求级别的细粒度路径追踪。
  • Metric 提供了聚合的、可告警的系统健康视图。
  • Log 提供了事件级别的详细记录,通过 TraceId 与 Trace 关联。
  • Context Propagation 是分布式环境下保证 Trace 完整性的基础设施。
  • 值班机器人的自动化诊断能力,正是建立在这五大概念的信号关联之上。