OpenTelemetry 深度解析:可观测性终极标准如何重塑云原生监控——从三大支柱到 AI 根因分析的全链路实战
引言:为什么每个后端程序员都需要懂 OpenTelemetry?
2026 年 3 月,一家名不见经传的德国初创公司 Dash0 宣布完成 1.1 亿美元 B 轮融资,估值达到 10 亿美元。它的核心武器不是什么黑科技,而是 OpenTelemetry——CNCF 的第二活跃项目(仅次于 Kubernetes)。
为什么一个"遥测数据采集框架"能让一家初创公司估值 10 亿美元?因为 可观测性(Observability) 已经成为云原生时代的基础设施刚需,而 OpenTelemetry 正在成为这个领域的统一标准。
为什么你应该关注?
- Datadog 年营收超 30 亿美元,但供应商锁定让企业苦不堪言——OpenTelemetry 是打破锁定的利器
- 微服务链路追踪没有 OpenTelemetry,你根本不知道一个请求经过了哪些服务
- AI 时代的新需求:大模型调用的 Token 消耗、延迟、错误率都需要可观测性
- CI/CD 也可观测了:语义约定 v1.27.0 正式纳入 CI/CD 属性
本文将从零开始,深入解析 OpenTelemetry 的架构、原理和实战,覆盖 Traces / Metrics / Logs 三大支柱、Collector 管道架构、语义约定、AI 根因分析,并给出 Go + Python + Java 三语言的代码实战。
一、可观测性 vs 监控:根本性的思维转变
1.1 监控的局限
传统监控回答的是 "出了什么问题":
# Prometheus 告警规则:CPU 超过 80%
- alert: HighCPU
expr: process_cpu_usage > 0.8
for: 5m
labels:
severity: warning
问题:告警告诉你 CPU 高了,但 为什么 高了?是哪个接口导致的?是哪个数据库查询拖慢了响应?监控无法回答。
1.2 可观测性回答"为什么"
可观测性通过 三大支柱 关联数据,让你能够从现象追溯到根因:
| 支柱 | 回答的问题 | 数据示例 |
|---|---|---|
| Traces(追踪) | 请求经过了哪些服务?哪个服务最慢? | Span: order-service → payment-service → db-query (1.2s) |
| Metrics(指标) | 系统当前的运行状态如何? | http_request_duration_seconds{method="POST"} 0.85 |
| Logs(日志) | 具体发生了什么事?错误详情是什么? | 2026-05-11 ERROR PaymentService: Connection timeout |
关键洞察:Traces 是连接 Metrics 和 Logs 的纽带。一个 Trace ID 可以把"CPU 高(Metrics)"和"数据库连接超时(Logs)"关联到同一个请求链路。
1.3 OpenTelemetry 的定位
OpenTelemetry 不做存储、不做可视化、不做告警。它只做一件事:标准化地采集和传输遥测数据。
应用服务 → [OTel SDK 采集] → [OTLP 协议传输] → [Collector 处理] → [后端存储]
↓
Jaeger / Prometheus / Datadog / Grafana
核心价值:
- 避免供应商锁定:换后端只需修改 Collector 的 Exporter 配置,应用代码零改动
- 统一标准:一套 SDK 同时采集 Traces、Metrics、Logs,无需三套系统
- 零侵入自动埋点:Java Agent 一挂,Spring Boot / JDBC / Redis 全自动追踪
二、架构全解析:OpenTelemetry 的组件如何协作?
2.1 整体架构
应用层: Go OTel SDK | Python OTel SDK | Java OTel SDK
↓ OTLP (gRPC/HTTP)
Collector: Receiver → Processor → Exporter
↓ ↓ ↓
Jaeger Prometheus Datadog
(Trace) (Metric) (All)
2.2 三大核心组件
1. API(接口层):定义遥测数据的抽象接口,不包含实现
// Go: OpenTelemetry API — 只定义接口
import "go.opentelemetry.io/otel/trace"
func businessLogic(ctx context.Context) {
ctx, span := tracer.Start(ctx, "businessLogic")
defer span.End()
span.SetAttributes(attribute.String("user.id", "12345"))
span.AddEvent("cache_miss", trace.WithAttributes(
attribute.String("cache.key", "user:12345"),
))
}
2. SDK(实现层):API 的具体实现,负责采集、批量处理和导出
func initTracer() (*sdktrace.TracerProvider, error) {
exporter, err := otlptracegrpc.New(context.Background(),
otlptracegrpc.WithEndpoint("localhost:4317"),
otlptracegrpc.WithInsecure(),
)
if err != nil {
return nil, err
}
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter,
sdktrace.WithBatchTimeout(5*time.Second),
sdktrace.WithMaxExportBatchSize(512),
),
sdktrace.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String("order-service"),
)),
)
otel.SetTracerProvider(tp)
return tp, nil
}
3. Collector(收集器):独立部署的数据管道
# otel-collector-config.yaml
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 5s
send_batch_size: 1024
filter:
error_mode: ignore
traces:
span:
- 'attributes["http.route"] == "/healthz"'
memory_limiter:
check_interval: 1s
limit_mib: 512
exporters:
otlp/jaeger:
endpoint: jaeger:4317
tls:
insecure: true
prometheusremotewrite:
endpoint: http://prometheus:9090/api/v1/write
elasticsearch:
endpoints:
- http://elasticsearch:9200
logs_index: otel-logs
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch, filter]
exporters: [otlp/jaeger]
metrics:
receivers: [otlp]
processors: [batch, memory_limiter]
exporters: [prometheusremotewrite]
logs:
receivers: [otlp]
processors: [batch]
exporters: [elasticsearch]
三、Traces 深度实战:从零构建分布式追踪
3.1 Trace 的数据模型
Trace (一次完整请求)
├── Span A (order-service: POST /api/orders, 2.5s)
│ ├── Span B (payment-service: processPayment, 1.8s)
│ │ ├── Span C (stripe-api: createCharge, 1.2s)
│ │ └── Span D (db: INSERT payment, 0.3s)
│ ├── Span E (inventory-service: reduceStock, 0.5s)
│ └── Span F (notification-service: sendEmail, 0.2s)
| 概念 | 说明 | 示例 |
|---|---|---|
| Trace | 一次完整的请求链路 | trace_id: abc123 |
| Span | 链路中的一个操作 | span_id: def456, parent_span_id: abc123 |
| Context | 传播链路上下文的载体 | traceparent: 00-abc123-def456-01 |
| Attribute | Span 的键值对属性 | http.method: POST |
| Event | Span 内的时间点事件 | cache_miss at 2026-05-11 |
| Link | 关联其他 Trace 的 Span | 批处理关联原始请求 |
3.2 Go 服务:完整链路追踪
package main
import (
"context"
"fmt"
"log"
"net/http"
"time"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/propagation"
semconv "go.opentelemetry.io/otel/semconv/v1.27.0"
"go.opentelemetry.io/otel/trace"
)
var tracer trace.Tracer
func createOrder(w http.ResponseWriter, r *http.Request) {
// 从请求头提取链路上下文
ctx := otel.GetTextMapPropagator().Extract(
r.Context(), propagation.HeaderCarrier(r.Header),
)
// 创建 Span
ctx, span := tracer.Start(ctx, "createOrder",
trace.WithAttributes(
semconv.HTTPRequestMethodKey.String("POST"),
semconv.URLPathKey.String("/api/orders"),
attribute.String("order.user_id", r.URL.Query().Get("user_id")),
),
)
defer span.End()
// 验证订单
if err := validateOrder(ctx); err != nil {
span.SetStatus(codes.Error, "order validation failed")
span.RecordError(err)
http.Error(w, err.Error(), 400)
return
}
// 调用支付服务(带上下文传播)
if err := callPaymentService(ctx); err != nil {
span.SetStatus(codes.Error, "payment failed")
span.RecordError(err)
http.Error(w, err.Error(), 500)
return
}
span.SetStatus(codes.Ok, "")
fmt.Fprintf(w, `{"status": "created"}`)
}
func callPaymentService(ctx context.Context) error {
ctx, span := tracer.Start(ctx, "callPaymentService")
defer span.End()
req, _ := http.NewRequestWithContext(ctx, "POST",
"http://payment-service:8081/api/payments", nil)
// 注入链路上下文到请求头
otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(req.Header))
client := &http.Client{Timeout: 5 * time.Second}
resp, err := client.Do(req)
if err != nil {
span.RecordError(err)
return err
}
defer resp.Body.Close()
return nil
}
3.3 Python 服务:自动埋点 + 手动埋点
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.flask import FlaskInstrumentor
from opentelemetry.instrumentation.requests import RequestsInstrumentor
from opentelemetry.instrumentation.psycopg2 import Psycopg2Instrumentor
from flask import Flask, request
# 初始化
provider = TracerProvider()
provider.add_span_processor(
BatchSpanProcessor(OTLPSpanExporter(endpoint="http://otel-collector:4317"))
)
trace.set_tracer_provider(provider)
# 自动埋点:Flask / Requests / Psycopg2
FlaskInstrumentor().instrument()
RequestsInstrumentor().instrument()
Psycopg2Instrumentor().instrument()
app = Flask(__name__)
tracer = trace.get_tracer("payment-service")
@app.route("/api/payments", methods=["POST"])
def process_payment():
with tracer.start_as_current_span("process_payment") as span:
span.set_attribute("payment.user_id", request.args.get("user_id"))
span.set_attribute("payment.amount", "99.99")
# 数据库操作(自动创建子 Span)
import psycopg2
conn = psycopg2.connect(host="db-master", database="payments")
cursor = conn.cursor()
cursor.execute("INSERT INTO payments VALUES (%s, %s, %s) RETURNING id",
("user123", 99.99, "pending"))
payment_id = cursor.fetchone()[0]
conn.commit()
span.set_status(trace.StatusCode.OK)
return {"status": "processed", "payment_id": payment_id}
3.4 Java 服务:零代码 Agent 自动埋点
# 启动 Spring Boot 应用(零代码修改!)
java -javaagent:opentelemetry-javaagent.jar \
-Dotel.service.name=inventory-service \
-Dotel.exporter.otlp.endpoint=http://otel-collector:4317 \
-Dotel.exporter.otlp.protocol=grpc \
-Dotel.traces.sampler=parentbased_traceidratio \
-Dotel.traces.sampler.arg=0.5 \
-jar inventory-service.jar
Java Agent 自动埋点覆盖:Spring MVC、JDBC、Redis、Kafka、gRPC、OkHttp、Logback
日志自动关联 Trace ID:
<!-- logback-spring.xml -->
<pattern>%d [%X{trace_id},%X{span_id}] %-5level %logger - %msg%n</pattern>
输出:2026-05-11 [abc123,def456] ERROR PaymentService - Connection timeout
四、Metrics 深度实战:用 OpenTelemetry 替代 Prometheus Client
4.1 OTel Metrics vs Prometheus Client
| 特性 | Prometheus Client | OTel Metrics |
|---|---|---|
| 数据模型 | 只支持 Prometheus 格式 | OTLP 统一格式 |
| 与 Traces 关联 | 需手动配置 Exemplar | 原生支持 Exemplar |
| 语义约定 | 无标准化 | 语义约定 v1.27.0 |
| 多后端导出 | 只能到 Prometheus | 同时到多个后端 |
4.2 Go 服务:Metrics 采集
meter = otel.Meter("order-service")
// Counter: 订单总数
orderCounter, _ := meter.Int64Counter("orders_total",
metric.WithDescription("Total number of orders"),
metric.WithUnit("{order}"),
)
// Histogram: 订单处理时间
orderDuration, _ := meter.Float64Histogram("order_duration_seconds",
metric.WithDescription("Order processing duration"),
metric.WithUnit("s"),
)
// UpDownCounter: 当前活跃连接数
activeConns, _ := meter.Int64UpDownCounter("active_connections",
metric.WithDescription("Number of active connections"),
)
// 记录指标
orderCounter.Add(ctx, 1,
metric.WithAttributes(semconv.HTTPRequestMethodKey.String("POST")),
)
orderDuration.Record(ctx, time.Since(start).Seconds())
4.3 Exemplar:Metrics 与 Traces 的桥梁
Exemplar 让每个 Metrics 数据点都能追溯到具体的 Trace:
order_duration_seconds_bucket{le="0.5"} 42 # {trace_id="abc123"} 0.23
在 Grafana 仪表盘上,点击柱状图数据点可直接跳转到 Jaeger 查看对应 Trace。
五、语义约定 v1.27.0:标准化如何拯救可观测性
5.1 为什么需要语义约定?
没有语义约定的世界:
服务A: http.request.method = "POST"
服务B: http_method = "POST"
服务C: requestType = "POST"
服务D: method = "post"
结果:在 Jaeger 中搜索 http.method=POST,只能搜到服务 A 的 Trace。
5.2 语义约定 v1.27.0 的关键更新
| 语义约定 | 标准属性名 | 说明 |
|---|---|---|
| HTTP | http.request.method | HTTP 请求方法 |
| Database | db.system, db.statement | 数据库系统和 SQL 语句 |
| Messaging | messaging.system, messaging.destination | 消息队列 |
| CI/CD(新增) | ci.pipeline.name, ci.pipeline.run.id | CI/CD 管道 |
| AI/LLM | gen_ai.system, gen_ai.request.model | 大模型调用 |
5.3 CI/CD 可观测性实战
# 语义约定 v1.27.0 — CI/CD 属性
attributes:
ci.pipeline.name: "build-and-deploy"
ci.pipeline.run.id: "12345"
ci.pipeline.run.url: "https://github.com/org/repo/actions/runs/12345"
ci.pipeline.task.name: "unit-tests"
ci.pipeline.task.run.id: "67890"
ci.pipeline.task.run.url: "https://github.com/org/repo/actions/runs/12345/jobs/67890"
意义:现在你可以追踪一个 CI/CD Pipeline 的执行链路——从代码提交到部署上线,每一步的耗时和状态都可视化。
六、AI 根因分析:Dash0 如何用 AI 代理颠覆传统运维
6.1 传统运维的痛点
凌晨 3 点被 PagerDuty 叫醒,你看到的告警:
ALERT: http_request_duration_seconds{service="payment",path="/api/payments"} > 2s
你需要手动:
- 打开 Jaeger,搜索慢请求的 Trace
- 在 Trace 中找到最慢的 Span
- 打开 Kibana,用 Trace ID 搜索相关日志
- 分析日志,找到错误原因
- 联系 DBA,确认数据库是否有问题
平均耗时:30-60 分钟
6.2 AI 代理如何工作
Dash0 的 AI 代理自动完成以上所有步骤:
1. 接收告警 → 自动搜索相关 Trace
2. 分析 Trace → 识别最慢的 Span(db-query, 1.8s)
3. 关联日志 → 找到错误:Connection timeout to db-master:5432
4. 查询 Metrics → 发现 db-master 的 CPU 在同一时间飙升至 95%
5. 生成根因报告:
"根因:db-master 实例 CPU 飙升导致连接超时。
建议操作:1) 扩容 db-master 2) 检查是否有慢查询"
平均耗时:30 秒
6.3 用 OpenTelemetry 数据构建 AI 代理
import openai
from opentelemetry import trace
tracer = trace.get_tracer("ai-root-cause-analyzer")
def analyze_root_cause(alert: dict) -> dict:
with tracer.start_as_current_span("analyze_root_cause") as span:
span.set_attribute("alert.service", alert["service"])
span.set_attribute("alert.metric", alert["metric"])
# 1. 搜索相关 Trace
traces = search_traces(
service=alert["service"],
min_duration=alert["threshold"],
time_range="5m"
)
# 2. 分析最慢的 Span
slow_spans = []
for t in traces:
for s in t.spans:
if s.duration > 1.0: # 超过 1 秒
slow_spans.append(s)
# 3. 关联日志
logs = search_logs(
trace_ids=[t.trace_id for t in traces],
level="ERROR"
)
# 4. 构建上下文,调用 LLM
context = f"""
告警: {alert}
慢 Span: {slow_spans}
错误日志: {logs}
"""
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[
{"role": "system", "content": "你是一个专业的运维 AI 代理,负责分析告警根因。"},
{"role": "user", "content": f"请分析以下告警的根因:\n{context}"}
]
)
return {
"root_cause": response.choices[0].message.content,
"trace_count": len(traces),
"slow_span_count": len(slow_spans),
"error_log_count": len(logs),
}
七、性能优化:OpenTelemetry 在生产环境的最佳实践
7.1 采样策略
生产环境不可能 100% 采集所有 Trace。OpenTelemetry 提供多种采样策略:
// Head Sampling:在请求入口决定是否采样
tailSampler := sdktrace.NewTracerProvider(
sdktrace.WithSampler(sdktrace.TraceIDRatioBased(0.1)), // 采样 10%
)
// Tail Sampling:在请求结束后决定是否采样(更精确)
// 只采样错误请求和慢请求
tailSampler := tailsampling.NewConfig(
tailsampling.WithPolicy(
tailsampling.WithName("errors-and-slow"),
tailsampling.WithCompositePolicy(
tailsampling.WithRateLimitedPolicy(10), // 每秒最多 10 条
tailsampling.WithAndPolicy(
tailsampling.WithStatusCodePolicy(codes.Error),
),
tailsampling.WithLatencyPolicy(2 * time.Second),
),
),
)
7.2 Collector 性能调优
processors:
batch:
timeout: 5s # 每 5 秒发送一次
send_batch_size: 1024 # 每批最多 1024 条
send_batch_max_size: 2048 # 绝对上限
memory_limiter:
check_interval: 1s
limit_mib: 512 # 内存限制 512MB
spike_limit_mib: 128 # 突增限制 128MB
基准测试(单 Collector 实例):
| 数据类型 | 吞吐量 | CPU | 内存 |
|---|---|---|---|
| Traces | 50K spans/s | 200m | 256MB |
| Metrics | 100K data points/s | 150m | 128MB |
| Logs | 30K records/s | 300m | 512MB |
7.3 资源属性优化
// 最小化资源属性(减少每个 Span 的开销)
res := resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String("order-service"), // 必须
semconv.ServiceVersionKey.String("1.0.0"), // 推荐
attribute.String("deployment.environment", "prod"), // 推荐
// ❌ 不要添加高基数属性(如 pod.id、container.id)
// 这些会导致 Cardinality Explode
)
八、OpenTelemetry 在 AI 时代的扩展
8.1 LLM 调用的可观测性
OpenTelemetry 语义约定已经定义了 AI/LLM 的标准属性:
from opentelemetry import trace
tracer = trace.get_tracer("llm-service")
@tracer.start_as_current_span("llm.chat_completion")
def chat_completion(prompt: str, model: str = "gpt-4"):
span = trace.get_current_span()
span.set_attribute("gen_ai.system", "openai")
span.set_attribute("gen_ai.request.model", model)
span.set_attribute("gen_ai.request.max_tokens", 4096)
span.set_attribute("gen_ai.request.temperature", 0.7)
response = openai.ChatCompletion.create(
model=model,
messages=[{"role": "user", "content": prompt}],
max_tokens=4096,
temperature=0.7,
)
# 记录 Token 消耗
usage = response.usage
span.set_attribute("gen_ai.usage.prompt_tokens", usage.prompt_tokens)
span.set_attribute("gen_ai.usage.completion_tokens", usage.completion_tokens)
span.set_attribute("gen_ai.usage.total_tokens", usage.total_tokens)
# 记录响应
span.set_attribute("gen_ai.response.finish_reason", response.choices[0].finish_reason)
return response.choices[0].message.content
效果:你可以在 Grafana 中看到每个 LLM 调用的延迟、Token 消耗和错误率,与业务请求链路关联。
8.2 Spring AI 的 OpenTelemetry 集成
Spring AI 1.1 已经内置了 OpenTelemetry 支持:
# application.yml
spring:
ai:
chat:
client:
observations:
include-input: true # 记录输入 Prompt
include-output: true # 记录输出 Completion
observations:
include-completion-tokens: true
include-prompt-tokens: true
management:
observations:
export:
otlp:
enabled: true
endpoint: http://otel-collector:4317
九、从零搭建 OpenTelemetry 全链路可观测性平台
9.1 Docker Compose 一键部署
# docker-compose.yml
version: '3.8'
services:
# OpenTelemetry Collector
otel-collector:
image: otel/opentelemetry-collector-contrib:0.96.0
command: ["--config=/etc/otelcol-contrib/config.yaml"]
volumes:
- ./otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml
ports:
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
- "8889:8889" # Prometheus exporter
# Jaeger (Trace 后端)
jaeger:
image: jaegertracing/all-in-one:1.54
environment:
- COLLECTOR_OTLP_ENABLED=true
ports:
- "16686:16686" # Jaeger UI
- "4317" # OTLP gRPC
# Prometheus (Metric 后端)
prometheus:
image: prom/prometheus:v2.51.0
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
# Grafana (可视化)
grafana:
image: grafana/grafana:10.4.0
environment:
- GF_AUTH_ANONYMOUS_ENABLED=true
ports:
- "3000:3000"
9.2 五分钟验证
# 1. 启动所有服务
docker compose up -d
# 2. 发送测试 Trace
curl -X POST http://localhost:4318/v1/traces \
-H "Content-Type: application/json" \
-d '{
"resourceSpans": [{
"resource": {
"attributes": [{"key": "service.name", "value": {"stringValue": "test-service"}}]
},
"scopeSpans": [{
"spans": [{
"traceId": "0123456789abcdef0123456789abcdef",
"spanId": "0123456789abcdef",
"name": "test-span",
"kind": 1,
"startTimeUnixNano": "1715399862000000000",
"endTimeUnixNano": "1715399863000000000"
}]
}]
}]
}'
# 3. 打开 Jaeger UI 查看
open http://localhost:16686
# 4. 打开 Grafana 仪表盘
open http://localhost:3000
十、OpenTelemetry vs 竞品:为什么它是终极标准?
| 维度 | Datadog APM | Jaeger + Prometheus | OpenTelemetry |
|---|---|---|---|
| 供应商锁定 | 严重(私有 Agent + 协议) | 无(开源) | 无(CNCF 标准) |
| 数据模型 | 私有格式 | 分散格式 | 统一 OTLP 格式 |
| Traces + Metrics + Logs | 一体化但锁定 | 需要三套系统 | 一套 SDK 三种数据 |
| 自动埋点 | 仅 Datadog 库 | 无 | Java Agent 零代码 |
| 价格 | $23/月/主机 | 免费 | 免费 |
| 生态 | 大(但锁定) | 中 | 最大(CNCF 标准) |
结论:OpenTelemetry 不是 Datadog 的替代品,而是 Datadog 的解药——它让你能在 Datadog、Grafana、New Relic 之间自由切换,不再被任何供应商绑架。
总结:OpenTelemetry 的 2026 年路线图
已完成
- ✅ Traces 稳定(GA)
- ✅ Metrics 稳定(GA)
- ✅ Logs 稳定(GA)
- ✅ OTLP 协议稳定(GA)
- ✅ 语义约定 v1.27.0(含 CI/CD)
- ✅ 11 种语言的 SDK
进行中
- 🔄 AI/LLM 语义约定(gen_ai.*)
- 🔄 Continuous Profiling 集成
- 🔄 OpenTelemetry Operator for Kubernetes 增强
- 🔄 Collector 性能优化(WASM Processor)
未来展望
- 📋 eBPF 自动无侵入采集
- 📋 Client-side(浏览器)可观测性
- 📋 OpenTelemetry + FinOps(成本可观测性)
如果你还没有开始使用 OpenTelemetry,现在就是最好的时机。
参考资源:
- OpenTelemetry 官方文档:https://opentelemetry.io/docs
- OTLP 协议规范:https://github.com/open-telemetry/opentelemetry-specification
- 语义约定 v1.27.0:https://opentelemetry.io/docs/specs/semconv/
- Dash0 官网:https://dash0.com
- OpenTelemetry Demo:https://github.com/open-telemetry/opentelemetry-demo
- Java Agent 自动埋点:https://github.com/open-telemetry/opentelemetry-java-instrumentation
结语:
OpenTelemetry 不是又一个监控工具——它是 可观测性的 HTTP。就像 HTTP 统一了 Web 的通信协议,OpenTelemetry 正在统一可观测性的数据采集和传输标准。
Dash0 用它挑战 Datadog 的 30 亿美元帝国,腾讯云用它增强 Java 探针,Spring AI 用它追踪 LLM 调用——OpenTelemetry 正在成为云原生可观测性的基础设施。
不掌握 OpenTelemetry,就像 2010 年不懂 HTTP 一样——你可能还能写代码,但你无法理解你的系统在做什么。