使用声明式 YAML 文件配置 SDK
在 SDK 支持的地方,用一个带 OTEL_CONFIG_FILE 的 YAML 文件取代几十个环境变量。
环境变量适合处理少量设置,但当你需要多个 exporter、自定义 processor 或采样规则时,它们就变得笨重了。声明式配置用一个 YAML 文件取而代之,描述整个 SDK:资源、propagator,以及 tracer、meter 和 logger provider。该 schema 在 2026 年达到了稳定版本,这意味着围绕它进行设计是安全的。各个 SDK 的支持仍然参差不齐,所以在采用之前请阅读状态一节。
开启它
保存一个文件,并用一个环境变量将 SDK 指向它:
export OTEL_CONFIG_FILE=/etc/otel/otel-config.yaml
当设置了 OTEL_CONFIG_FILE 时,支持声明式配置的 SDK 会根据该文件构建自己。除非文件引用了其他 OTEL_* 变量,否则这些变量随后都会被忽略,下面会介绍。
一个完整的示例
otel-config.yaml:
file_format: "1.2"
resource:
attributes_list: ${OTEL_RESOURCE_ATTRIBUTES}
detection/development:
detectors:
- service:
- host:
- process:
- container:
propagator:
composite:
- tracecontext:
- baggage:
tracer_provider:
sampler:
parent_based:
root:
always_on:
processors:
- batch:
exporter:
otlp_http:
endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318}/v1/traces
meter_provider:
readers:
- periodic:
exporter:
otlp_http:
endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318}/v1/metrics
logger_provider:
processors:
- batch:
exporter:
otlp_http:
endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318}/v1/logs
请使用你的 SDK 文档所指定的 file_format 值,因为各 SDK 采纳新 schema 版本的时间不同。如何阅读这个文件:
resource描述服务。attributes_list接受通常的key=value,key=value字符串,而detectors会自动添加主机、进程和容器信息。以/development结尾的属性仍是实验性的,可能并非每个 SDK 中都存在。propagator列出上下文 propagator,这里是 W3C trace context 和 baggage。tracer_provider包含采样器和 span processor。这里一个 batch processor 通过 OTLP HTTP exporter 发送 span。meter_provider包含指标 reader。periodicreader 按间隔导出。logger_provider对日志做同样的事。otlp_http与otlp_grpc:交换 exporter 名称和端点(gRPC 用http://localhost:4317)即可更换协议。
环境变量替换
在文件内部,${VAR} 读取环境变量,${VAR:-default} 在变量未设置时提供默认值。环境变量在其他情况下会被忽略,这正是关键所在:除非文件要求,否则没有任何东西会改变行为。这使得很容易看出每个环境下有哪些是可配置的:
resource:
attributes_list: ${OTEL_RESOURCE_ATTRIBUTES}
tracer_provider:
processors:
- batch:
exporter:
otlp_http:
endpoint: ${OTEL_EXPORTER_OTLP_TRACES_ENDPOINT:-http://localhost:4318/v1/traces}
这样同一个文件在开发环境(默认值)和生产环境(由平台设置变量)中都能工作。
按信号的目的地与更丰富的配置
声明式配置在环境变量难以很好表达的事情上大放异彩,比如把相同的 span 发送到两个地方,或调整某个 processor:
tracer_provider:
processors:
- batch:
schedule_delay: 2000
max_queue_size: 4096
exporter:
otlp_http:
endpoint: http://collector:4318/v1/traces
- simple:
exporter:
console:
这里 span 以批的方式发送到 Collector,同时也打印到控制台,这对本地调试很有用。请查看你的 SDK 文档,了解它所支持的确切属性名称,因为可用的 processor、采样器和 exporter 取决于具体实现。
哪些语言支持它
规范和 schema 是稳定的,但每种语言按自己的节奏实现它们:
- 可用: C++、Go、Java、JavaScript 和 PHP 有实现,Java agent 记录了它自己的设置。
- 开发中: .NET 和 Python。
- 文档仍将各实现中的支持描述为实验性的,所以请在依赖它之前,为你的语言测试这个功能。
- Collector 本身使用 Go 实现来配置它自己的内部遥测。
如果你的语言还没准备好,请继续使用环境变量。这两种模型被有意设计为相互兼容:替换示例中所示的变量名,与你不用文件时所使用的是同样的名称。
在两者之间选择
| 在以下情况使用环境变量 | 在以下情况使用声明式文件 |
|---|---|
| 你为每个服务设置少量选项 | 你需要多个 exporter 或 processor |
| 你的平台已经注入环境(Operator、Helm) | 你希望整个 SDK 设置在一个文件中得到审查 |
| 你的语言的声明式支持缺失或不成熟 | 你希望跨多种语言使用同一种配置格式 |
一种合理的混合方式是从 ConfigMap 挂载一个共享文件,并让环境变量通过 ${...} 替换只提供每个环境的值。
交付文件
Docker Compose:
services:
checkout:
image: myorg/checkout:1.4.2
environment:
OTEL_CONFIG_FILE: /etc/otel/otel-config.yaml
OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4318
OTEL_RESOURCE_ATTRIBUTES: service.version=1.4.2,deployment.environment.name=staging
volumes:
- ./otel-config.yaml:/etc/otel/otel-config.yaml:ro
Kubernetes:把文件放进 ConfigMap,挂载它,并在 Deployment 中设置 OTEL_CONFIG_FILE。Git 中对 ConfigMap 的修改随后会像任何其他变更一样推出,但 SDK 在启动时读取该文件,所以请重启 Pod 以使其生效。
陷阱
- 文件中的错误可能会阻止 SDK 启动它的 provider。请在预生产环境中测试,并在启动时观察 SDK 的日志输出(临时设置
OTEL_LOG_LEVEL=debug)。 - 不要把 secret 直接写在文件里。使用
${VAR},并从 Secret 注入该值。 - 运行时动态重新配置还不是此规范的一部分。更改文件需要重启。
- 计划弃用一些单独的环境变量,因为它们无法很好地互操作,不过被弃用并不意味着被移除。
完整的 schema 和各语言的说明,请参见声明式配置文档。
热门指南
-
OpenTelemetry 详解:SDK、OTLP 与 Collector 在编写任何 YAML 之前,先了解各个活动部件以及配置所在的三个位置。 -
Collector 配置模型:组件、管线与 Provider 了解 Collector YAML 的规则:命名、管线、connector、合并文件和环境变量。 -
使用 OTEL_* 环境变量配置 SDK 使用标准变量为任何语言设置服务名称、exporter、采样和限制。 -
无需修改代码即可为应用插桩:Java、Python 和 Node.js 仅通过环境变量和命令行参数附加 OpenTelemetry agent。 -
让 Collector 达到生产就绪:内存限制、批处理与重试 配置 processor、队列和持久化存储,使遥测数据在过载和故障中存活。 -
使用 Helm 在 Kubernetes 上部署 Collector 安装官方 chart,使用 preset 处理日志和指标,并通过 values 文件覆盖配置。 -
排查 Collector 与 SDK 的问题 当遥测数据没有到达时的系统化检查清单:debug exporter、健康检查、内部指标和常见错误。