OpenTelemetry(OTel)正式成为 CNCF 毕业项目,与 Kubernetes、Prometheus 等成熟开源项目处于同一项目阶段。对开发团队而言,这不只是一个社区里程碑,也意味着一个更实际的问题:既然遥测标准已经趋于成熟,我们是否应该把分散的日志、指标和追踪接入方式收拢到 OpenTelemetry?
答案通常不是“立刻替换全部监控系统”,而是把 OTel 作为统一的遥测采集层,逐步降低应用代码与具体可观测性厂商之间的耦合。
“毕业”意味着什么,又不意味着什么
CNCF 毕业状态通常反映项目在治理、社区、采用情况和工程成熟度等方面已经经过检验。它能降低团队评估基础设施项目时的不确定性,但并不意味着接入工作会自动完成,也不代表所有语言 SDK、自动插桩组件和后端组合都具有完全一致的能力。
在架构层面,OpenTelemetry解决的是遥测数据的生成、处理和传输问题。它并不等同于完整的可观测性后端:
- 应用通过 SDK 或自动插桩产生 traces、metrics 和 logs。
- OpenTelemetry Collector 接收、过滤、批处理并转发数据。
- Prometheus、Jaeger、Tempo 或商业平台负责存储、查询、告警和展示。
这层边界很重要。采用 OTel 后,团队仍然需要决定数据保留周期、采样策略、告警规则、敏感字段处理方式和后端容量。
Collector 应成为稳定的接入边界
直接让每个服务连接某个厂商的后端,短期看起来最省事,长期却会让认证参数、重试策略和导出协议散落在应用配置中。一个更容易治理的方式,是让应用只使用 OTLP 协议发送数据,再由 Collector 负责后续路由。
可以这样实践:先在本地启动一个 Collector,把接收到的遥测数据输出到控制台。下面的配置启用 OTLP gRPC 和 HTTP 接收端,加入批处理器,并通过 debug exporter 查看数据。
将以下内容保存为 otel-collector-config.yaml:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 1s
exporters:
debug:
verbosity: detailed
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [debug]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [debug]
然后运行 Collector:
docker run --rm \
-p 4317:4317 \
-p 4318:4318 \
-v "$PWD/otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml:ro" \
otel/opentelemetry-collector-contrib:latest
生产环境不应长期使用浮动的 latest 标签,应锁定经过验证的镜像版本。debug exporter 也只适合本地验证;正式部署时,应将它替换为目标后端支持的 exporter 或 OTLP 出口。
用一个最小 Python 服务验证链路
下面的示例主动创建一个 span,并通过 OTLP HTTP 将其发送到 Collector。运行前需要保证 Collector 正在监听本机的 4318 端口。
安装依赖:
python -m venv .venv
. .venv/bin/activate
pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp-proto-http
创建 app.py:
import time
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
resource = Resource.create(
{
"service.name": "checkout-demo",
"service.version": "1.0.0",
"deployment.environment.name": "local",
}
)
provider = TracerProvider(resource=resource)
provider.add_span_processor(
BatchSpanProcessor(
OTLPSpanExporter(endpoint="http://localhost:4318/v1/traces")
)
)
trace.set_tracer_provider(provider)
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("calculate-order-total") as span:
span.set_attribute("order.item_count", 3)
span.set_attribute("order.currency", "CNY")
time.sleep(0.1)
provider.shutdown()
执行:
python app.py
Collector 控制台中应该出现服务名、span 名称和属性。这个小测试能同时验证 SDK、OTLP 网络连接和 Collector pipeline,适合作为正式接入前的冒烟测试。
示例里没有记录用户姓名、邮箱或支付信息,这是有意为之。Span 属性会被导出并存储,不能把它当作无约束的调试日志。团队应建立属性白名单,并在 Collector 中增加过滤或脱敏处理。
从试点走向平台能力
OTel 已经毕业,不代表团队需要发动一次全量迁移。更稳妥的方式是选择一个依赖关系清晰、流量可控的服务作为试点,并提前定义验收标准:能否沿 trace 定位一次失败请求,关键指标是否与现有监控一致,Collector 故障是否会影响业务请求,以及数据量是否符合成本预算。
推广前可以检查以下事项:
- 统一
service.name、部署环境、版本和区域等资源属性。 - 明确哪些字段禁止进入遥测系统,在哪一层完成脱敏。
- 为 Collector 设置内存限制、批处理、队列、重试和自身监控。
- 根据流量与故障分析需求制定采样策略,而不是默认收集全部 trace。
- 固定 Collector、SDK 和插桩组件版本,并通过预发布环境升级。
- 保留后端导出失败、队列积压和丢弃数据量的告警。
OpenTelemetry 的毕业让“采用一个长期维护的开放遥测标准”成为风险更低的选择。真正产生价值的部分仍在团队内部:统一语义、控制数据质量、建设可靠的 Collector 层,并让遥测数据能够回答具体的生产问题。