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。这样当告警延迟或丢失时,可以快速定位是哪个环节出了问题。
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,这样整个告警链路才能完整串联。
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 的五大核心概念:
- Trace:端到端的请求路径,由 Span 组成。
- Span:单个工作单元,包含时间、属性、状态。
- Metrics:聚合的量化数据,用于监控和告警。
- Logs:结构化的事件记录,关联 Trace 上下文。
- Context Propagation:跨服务传递 Trace 上下文的机制。