3. OpenTelemetry 核心概念:Signal、Span、Trace、Metric、Log、Context Propagation、Resource

在构建发布工程自助门户的可观测性时,OpenTelemetry 提供了一套标准化的数据模型与协议。理解其核心概念是设计有效观测方案的前提。本章将逐一拆解这些概念,并阐明它们如何在发布流水线中协同工作。

3.1 三大信号(Signal)

OpenTelemetry 将可观测性数据抽象为三种核心信号(Signal),分别对应传统监控的三大支柱,但通过统一的 SDK 和导出协议实现了数据关联。

信号类型 英文 核心作用 发布工程场景示例
链路 Traces 记录请求在分布式系统中的完整路径与耗时 一次“构建-部署”请求从用户点击到容器启动的全链路追踪
指标 Metrics 聚合测量系统状态与性能的数值 构建队列长度、部署成功率、环境资源使用率
日志 Logs 记录离散的事件消息与上下文 构建失败的具体错误堆栈、部署阶段的配置变更记录
关键原则:OpenTelemetry 不要求你只使用一种信号。在发布工程中,最佳实践是同时启用 Traces 和 Metrics,并将 Logs 通过 Trace ID 关联到具体 Span,形成“信号关联”的立体观测视图。

3.2 Span 与 Trace:请求的旅程

Span 是链路追踪的基本工作单元。它代表一个具有开始时间和结束时间的操作,例如“拉取代码”、“执行构建”、“运行单元测试”。每个 Span 包含操作名称、时间戳、属性(Attributes)和事件(Events)。

Trace 是由一系列 Span 组成的树状结构,代表一个端到端的请求流。Trace 通过一个全局唯一的 Trace ID 标识,其内部的 Span 通过 Parent Span ID 形成父子关系。

发布流水线 Trace 示例:
Trace ID: abc123
├── Span: "用户触发发布" (Root Span)
│   ├── Span: "代码检出" (Child of Root)
│   │   └── Span: "Git Clone" (Child of 代码检出)
│   ├── Span: "单元测试" (Child of Root)
│   ├── Span: "构建镜像" (Child of Root)
│   │   └── Span: "Docker Build" (Child of 构建镜像)
│   └── Span: "部署到预发环境" (Child of Root)
│       └── Span: "K8s Apply" (Child of 部署到预发环境)
Trace 与 Span 层级结构 Trace ID: abc123 | Root Span: 用户触发发布 Span: 代码检出 Span: 构建镜像 Span: Git Clone Span: Docker Build Span: 部署到预发环境 Span: K8s Apply

3.3 Metric:聚合的量化视图

Metrics 用于聚合测量系统在时间维度上的状态。OpenTelemetry 支持三种主要的 Metric 工具:

  • Counter(计数器): 只增不减的值,如“构建总次数”、“部署失败次数”。
  • Histogram(直方图): 记录值的分布,如“构建耗时分布”、“部署延迟分布”。
  • Gauge(仪表盘): 可上下波动的瞬时值,如“当前排队构建数”、“环境 CPU 使用率”。
发布工程避坑:不要将 Metrics 用于记录高基数(High Cardinality)数据,例如每个构建的 Commit SHA 或用户 ID。高基数标签会导致指标存储爆炸。这类数据应放在 Span Attributes 或 Logs 中。

3.4 Log:带上下文的事件记录

OpenTelemetry 的 Logs 并非取代传统日志框架,而是通过标准化的日志记录 API 和关联机制,使日志成为可观测性的一部分。关键改进在于:

  • 结构化日志: 日志不再是纯文本字符串,而是包含键值对的结构化数据。
  • Trace 关联: 日志记录自动携带当前上下文的 Trace ID 和 Span ID,实现“日志即 Span 事件”。
// 结构化日志示例(伪代码)
logger.info("构建任务完成", {
  "trace_id": "abc123",
  "span_id": "def456",
  "build_id": "build-789",
  "duration_ms": 45230,
  "status": "success"
});

3.5 Context Propagation:跨服务传递状态

Context Propagation 是 OpenTelemetry 的“神经系统”。它负责将 Trace ID、Span ID 以及 Baggage(用户自定义上下文)在微服务、线程、消息队列之间透明传递。没有它,分布式链路就会断裂。

传播机制分为两部分:

组件 作用 发布工程场景
Propagator 定义如何序列化/反序列化上下文(如 W3C TraceContext) Jenkins 插件通过 HTTP Header 将 Trace ID 传递给后续的 K8s API 调用
Context 存储当前请求的活跃 Span 和 Baggage 的容器 在构建脚本中通过 Context API 获取当前 Trace ID,注入到子进程或 HTTP 请求

3.6 Resource:描述数据来源

Resource 是关联到所有信号(Traces、Metrics、Logs)的元数据,用于描述生成数据的实体。它通常包含基础设施信息、服务名称、版本号、环境标签等。Resource 是数据聚合与过滤的基础。

发布工程 Resource 示例:
Resource Attributes:
  service.name: "发布引擎"
  service.version: "2.1.0"
  deployment.environment: "production"
  host.name: "jenkins-master-01"
  cloud.provider: "aws"
  cloud.region: "us-east-1"
OpenTelemetry 核心概念关系图 Resource(资源描述:服务名、环境、主机) Traces Metrics Logs Context Propagation(上下文传播)

3.7 概念总结与发布工程映射

下表总结了所有核心概念在发布工程自助门户中的具体映射,帮助你快速建立认知关联:

核心概念 发布工程中的具体体现 关键属性/标签
Span “代码编译”、“镜像推送”、“Helm 部署”等每个原子操作 build.id, pipeline.stage, artifact.version
Trace 一次完整的“发布请求”从触发到完成的全过程 deployment.id, user.id, target.environment
Metric 构建队列深度、部署延迟 P99、环境错误率 service.name, status, region
Log 构建失败时的具体错误消息、配置变更审计日志 trace.id, severity, message
Context 在 Jenkins、Artifactory、K8s 之间传递的 Trace ID W3C TraceContext 头
Resource 标识数据来自“生产环境的 Jenkins Master” service.name, host.name, cloud.zone