3. OpenTelemetry 核心概念:Trace、Span、Context 传播与 Resource/Attribute
在构建可观测性体系时,OpenTelemetry(OTel)已成为链路数据采集的事实标准。要理解如何将 Loki 日志标签与链路关联,必须先掌握 OTel 的四大核心抽象:Trace、Span、Context 传播机制,以及 Resource 与 Attribute 的作用。本节将逐一拆解这些概念,并说明它们在日志-链路关联中的位置。
3.1 Trace 与 Span:链路的基本单元
Trace 代表一次完整的请求生命周期,从入口到所有下游依赖返回。它由一组具有相同 Trace ID 的 Span 组成。Span 是链路中的最小工作单元,记录一个操作(如 HTTP 请求、数据库查询、函数调用)的开始、结束、状态和元数据。
| 概念 | 定义 | 关键字段 | 在关联中的角色 |
|---|---|---|---|
| Trace | 端到端请求的完整路径 | TraceID(全局唯一) | 作为日志与链路的关联键 |
| Span | 单个操作的时间片 | SpanID、ParentSpanID、StartTime、EndTime | 提供操作级上下文与耗时 |
| SpanContext | Span 的可传播标识 | TraceID、SpanID、TraceFlags、TraceState | 跨进程传递关联信息 |
关键认知:TraceID 是连接日志与链路的“万能钥匙”。在日志中注入 TraceID,即可在 Loki 中通过标签快速跳转到对应的链路详情页。
3.2 Context 传播机制:跨进程的“隐形线”
Context 传播是 OTel 最核心的机制之一。它确保 TraceID 和 SpanID 能在微服务之间、线程之间、异步回调之间无缝传递,从而将分散的 Span 串联成完整的 Trace。
传播分为两个层面:
- 进程内传播:通过语言运行时上下文(如 Go 的
context.Context、Java 的ThreadLocal)传递 SpanContext。 - 进程间传播:通过协议头(如 HTTP 的
traceparent、tracestate)或消息队列元数据传递 SpanContext。
实战要点:在日志采集时,必须从当前 Context 中提取 TraceID。如果 Context 传播链路断裂(例如异步任务未正确传递 Context),日志将丢失 TraceID,导致关联失败。
下图展示了 Context 如何在三个微服务之间传播,并最终将 TraceID 注入日志:
3.3 Resource 与 Attribute:元数据的结构化承载
在 OTel 中,Resource 和 Attribute 是附加在 Trace、Span、Metrics 和 Logs 上的元数据。它们为可观测性数据提供上下文,是后续过滤、聚合和关联的基础。
3.3.1 Resource(资源)
Resource 描述产生数据的实体,通常是基础设施或服务实例。它属于静态元数据,在进程生命周期内保持不变。
- 常见字段:
service.name、service.version、host.name、cloud.region、deployment.environment - 在 Loki 关联中的作用:Resource 中的
service.name和deployment.environment可直接映射为 Loki 的日志标签,实现服务级和环境的快速筛选。
3.3.2 Attribute(属性)
Attribute 描述 Span 或 Log Record 的动态细节,每个 Span/Log 可以携带不同的 Attribute 集合。
- 常见字段:
http.method、http.status_code、db.system、user.id、error.message - 在 Loki 关联中的作用:Attribute 中的高基数字段(如
user.id、order.id)不适合直接作为 Loki 标签,但可以存储在日志正文中,通过 TraceID 关联后按需查询。
| 维度 | Resource | Attribute |
|---|---|---|
| 生命周期 | 进程级,静态 | Span/Log 级,动态 |
| 基数 | 低(服务名、环境等) | 高(用户 ID、订单 ID 等) |
| Loki 标签适用性 | 非常适合 | 仅低基数属性适合 |
| 关联用途 | 服务级过滤与分组 | 操作级细节补充 |
避坑指南:不要将高基数 Attribute(如 requestId、sessionId)直接设置为 Loki 标签。这会导致标签爆炸,严重降低 Loki 的查询性能。正确做法是将它们保留在日志行内,通过 TraceID 关联后从链路系统获取。
3.4 三者协同:从 Trace 到日志的元数据流动
下图展示了 Resource、Attribute 和 Context 如何在一次请求中协同工作,最终形成可关联的日志与链路数据:
3.5 本节小结
- Trace / Span 提供请求的完整拓扑与时间线,TraceID 是关联的核心键。
- Context 传播 确保 TraceID 跨服务、跨线程传递,是日志注入 TraceID 的前提。
- Resource 提供低基数、静态的服务元数据,适合直接映射为 Loki 标签。
- Attribute 提供高基数、动态的操作细节,应保留在日志正文中,通过 TraceID 按需查询。
下一阶段准备:在掌握 OTel 核心概念后,第 4 章将深入讲解如何通过 OTel SDK 在日志中自动注入 TraceID,并配置 Loki 标签提取规则,实现日志与链路的实时关联。