2. OpenTelemetry 核心概念:Trace、Span、Metrics、Logs、Context Propagation

在接入值班机器人之前,必须理解 OpenTelemetry 的五大核心概念。它们是构建可观测性数据的基石,也是后续链路追踪与告警配置的理论基础。本节将逐一拆解这些概念,并展示它们之间的协作关系。

2.1 核心概念总览

OpenTelemetry 将可观测性数据归纳为三大信号(Signals):Traces(链路)、Metrics(指标)和 Logs(日志)。其中 Traces 由 Span 构成,而 Context Propagation(上下文传播)则是将这些信号串联起来的核心机制。

概念 英文 一句话定义 在值班机器人场景中的作用
Trace Trace 一次请求或事务在分布式系统中的完整路径 追踪一条告警从产生、路由到机器人通知的完整生命周期
Span Span Trace 中的一个工作单元,包含开始/结束时间、属性、事件 记录告警处理链中每个步骤(如过滤、格式化、发送)的耗时与状态
Metrics Metrics 可聚合的数值测量,如计数、延迟、吞吐量 统计机器人每分钟发送的告警数、平均处理延迟、失败率
Logs Logs 带时间戳的结构化或非结构化文本记录 记录告警内容的详细载荷、错误堆栈、调试信息
上下文传播 Context Propagation 跨进程/线程传递 Trace 上下文(TraceId、SpanId)的机制 确保告警从上游系统传递到机器人时,链路不中断

关键理解: Trace 是树,Span 是节点,Metrics 是统计,Logs 是细节,Context Propagation 是粘合剂。值班机器人需要同时消费这四种数据,才能实现真正的端到端可观测。

2.2 Trace 与 Span:链路追踪的原子单位

Trace 代表一个端到端的请求流。在值班机器人场景中,一次告警处理就是一个 Trace。它从告警源(如 Prometheus Alertmanager)发出,经过路由、过滤、格式化,最终到达即时通讯平台(如钉钉、飞书)。

Span 是 Trace 的基本构建块。每个 Span 记录一个操作,包含:

  • Span Name:操作名称,如 alert.format、webhook.send
  • Span Context:唯一标识(TraceId、SpanId、ParentSpanId)
  • Timestamps:开始时间和结束时间
  • Attributes:键值对,如 alert.severity=critical、channel=dingtalk
  • Events:带时间戳的日志事件,如 retry.attempt=2
  • Status:成功/错误/未设置

实践建议: 在值班机器人的每个关键处理步骤(接收、解析、路由、发送、重试)都创建一个 Span。这样当告警延迟或丢失时,可以快速定位是哪个环节出了问题。

Trace 与 Span 结构示意图 Trace 与 Span 结构示意图 Trace: alert.process (TraceId: abc123) Span: alert.receive (ParentSpanId: root) Span: alert.format (ParentSpanId: root) Span: webhook.send (ParentSpanId: format) 说明 每个 Span 包含 TraceId + SpanId + ParentSpanId

2.3 Metrics:聚合的量化视图

Metrics 提供系统在时间维度上的聚合数据。与 Trace 的“一次请求”视角不同,Metrics 关注的是“一段时间内的统计”。OpenTelemetry 支持三种主要 Metric 类型:

Metric 类型 说明 值班机器人示例
Counter 单调递增的计数器,只增不减 alerts.total(总告警数)、alerts.sent(已发送数)
Histogram 对观测值进行分桶统计,可计算百分位 alert.processing.duration(处理延迟的 P50/P90/P99)
Gauge 可上下波动的瞬时值 webhook.queue.size(当前待发送队列长度)

注意: Metrics 不能替代 Trace。Metrics 告诉你“系统变慢了”,但 Trace 告诉你“是哪个环节变慢了”。两者必须配合使用。

2.4 Logs:结构化的事件记录

Logs 是最传统的可观测性信号。在 OpenTelemetry 中,Logs 被定义为带时间戳的结构化记录。与普通日志不同,OpenTelemetry 的 Logs 可以关联到 Trace 上下文,从而将日志与具体的请求链路绑定。

一个标准的 OpenTelemetry Log 记录包含:

  • Timestamp:事件发生时间
  • Severity:严重级别(TRACE、DEBUG、INFO、WARN、ERROR、FATAL)
  • Body:日志正文(字符串或结构化数据)
  • Attributes:键值对,如 service.name=robot、alert.id=12345
  • Trace Context:关联的 TraceId 和 SpanId(可选但强烈推荐)
// 示例:关联 Trace 的结构化日志
{
  "timestamp": "2025-01-15T10:30:00.123Z",
  "severity": "ERROR",
  "body": "Webhook send failed after 3 retries",
  "attributes": {
    "service.name": "alert-robot",
    "alert.id": "alert-98765",
    "channel": "dingtalk",
    "retry.count": 3
  },
  "traceId": "abc123def456",
  "spanId": "span789ghi012"
}

2.5 Context Propagation:串联一切的纽带

Context Propagation(上下文传播)是 OpenTelemetry 最核心也最容易被忽视的概念。它确保 Trace 上下文(TraceId、SpanId)能够在服务之间、线程之间、甚至异步回调之间正确传递。

传播机制分为两部分:

  • Propagation(传播):将上下文注入到请求中(如 HTTP 头、消息队列元数据),或从请求中提取上下文。
  • Context(上下文):存储当前活跃的 Span 信息,供同一进程内的后续操作使用。

常见的传播协议:

协议 HTTP Header 示例 适用场景
W3C TraceContext traceparent: 00-abc123...-def456...-01 标准推荐,跨语言兼容
B3 X-B3-TraceId: abc123... Zipkin 生态兼容
Jaeger uber-trace-id: abc123...:def456...:0:1 Jaeger 原生格式

值班机器人实战: 当告警从 Alertmanager 通过 Webhook 发送到机器人时,必须在 HTTP 请求头中传递 traceparent。机器人收到请求后,从 Header 中提取 TraceId,创建子 Span,这样整个告警链路才能完整串联。

Context Propagation 跨服务传递示意图 Context Propagation 跨服务传递示意图 服务 A Alertmanager Span: alert.fire 服务 B 值班机器人 Span: alert.receive 服务 C 钉钉/飞书 Span: webhook.send traceparent traceparent 上下文传播流程 服务 A 创建 TraceId → 通过 HTTP Header 传递给服务 B → 服务 B 提取上下文并创建子 Span → 再传递给服务 C

2.6 三大信号的关联与协作

在 OpenTelemetry 中,Trace、Metrics、Logs 并非孤立存在。通过 Context Propagation,它们可以相互关联:

  • Trace → Logs:日志中携带 TraceId,可以快速查询某条链路的所有日志。
  • Trace → Metrics:从 Trace 的 Span 持续时间中聚合出延迟指标(如 Histogram)。
  • Metrics → Trace:当指标出现异常(如延迟飙升),可以采样对应的 Trace 进行根因分析。
  • Logs → Trace:错误日志中携带的 TraceId 可以直接跳转到对应的链路详情。

值班机器人最佳实践: 在机器人代码中,确保所有日志输出都携带当前 Span 的 TraceId。这样当告警发送失败时,可以一键从日志跳转到链路追踪系统,查看完整的处理链路。

2.7 小结

本节覆盖了 OpenTelemetry 的五大核心概念:

  1. Trace:端到端的请求路径,由 Span 组成。
  2. Span:单个工作单元,包含时间、属性、状态。
  3. Metrics:聚合的量化数据,用于监控和告警。
  4. Logs:结构化的事件记录,关联 Trace 上下文。
  5. Context Propagation:跨服务传递 Trace 上下文的机制。