起因
可观测性 3 大 pillar:
- metric:Prometheus + node_exporter / app exporter
- trace:Jaeger / Tempo / Zipkin
- log:Loki / ELK
每个数据类型一套 collector:promtail / vector / fluentd / filebeat /
otel-trace 等。
应用要装 N 个 SDK,运维要管 N 套 agent。
OpenTelemetry Collector 统一:一个 binary 收 3 类数据 + 转发给后端。
应用用一套 OTEL SDK,agent 收一套 protocol。
装
docker run -d -p 4317:4317 -p 4318:4318 \
-v $(pwd)/config.yaml:/etc/otelcol/config.yaml \
otel/opentelemetry-collector-contrib:latest
config.yaml:
receivers:
otlp:
protocols:
grpc: { endpoint: 0.0.0.0:4317 }
http: { endpoint: 0.0.0.0:4318 }
prometheus:
config:
scrape_configs:
- job_name: 'apps'
static_configs:
- targets: ['app:8080']
processors:
batch:
timeout: 10s
exporters:
otlphttp/jaeger:
endpoint: http://jaeger:4318
prometheusremotewrite:
endpoint: http://mimir:9009/api/v1/push
loki:
endpoint: http://loki:3100/loki/api/v1/push
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp/jaeger]
metrics:
receivers: [otlp, prometheus]
processors: [batch]
exporters: [prometheusremotewrite]
logs:
receivers: [otlp]
processors: [batch]
exporters: [loki]
receiver → processor → exporter 流水线。
应用接入 (Python)
pip install opentelemetry-distro opentelemetry-exporter-otlp
opentelemetry-bootstrap -a install # 自动装 instrumentation
# 启动应用
opentelemetry-instrument \
--traces_exporter otlp \
--metrics_exporter otlp \
--logs_exporter otlp \
--service_name myapp \
--exporter_otlp_endpoint http://otel-collector:4317 \
python app.py
或者代码内:
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
provider = TracerProvider()
provider.add_span_processor(
BatchSpanProcessor(OTLPSpanExporter(endpoint='otel-collector:4317'))
)
trace.set_tracer_provider(provider)
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span('process_order'):
# ...
pass
auto-instrumentation 自动 trace Django / requests / SQLAlchemy 等。
跨语言
JS / Java / Go / Ruby / .NET 都有 OTEL SDK。
全用 OTLP 发到同 collector → 后端汇总。
处理器 (processor)
processors:
attributes:
actions:
- key: env
value: production
action: insert
- key: password # 敏感字段
action: delete
filter:
traces:
span:
- 'attributes["http.url"] == "/health"' # 过滤健康检查 trace
tail_sampling:
decision_wait: 10s
policies:
- name: errors
type: status_code
status_code: { status_codes: [ERROR] }
- name: slow
type: latency
latency: { threshold_ms: 1000 }
- name: sample
type: probabilistic
probabilistic: { sampling_percentage: 1 }
- attributes 加 / 删 tag
- filter 丢弃噪音 span
- tail sampling: 1% 抽样 + 100% 错误 + 100% 慢请求 → 节省后端存储
tail vs head sampling
head sampling:trace 开始时决定要不要采集(应用端)。
tail sampling:trace 完成后看完整决定(collector 端)。
tail 优势:基于结果决定(错误 / 慢的全采,正常的 1%)。
缺点:collector 要 buffer 所有 trace 几秒。
deployment 模式
agent (DaemonSet, 每 node) → gateway (Deployment, 集群级) → 后端
- agent:每 node 一个,应用本地连,减少网络
- gateway:中央处理(采样 / batch / 多后端 fanout)
或者单层:应用 → collector → 后端(小集群)。
k8s 部署 (operator)
helm install opentelemetry-operator open-telemetry/opentelemetry-operator
apiVersion: opentelemetry.io/v1beta1
kind: OpenTelemetryCollector
metadata:
name: gateway
spec:
mode: deployment
replicas: 3
config: |
receivers: ...
processors: ...
exporters: ...
operator 管 deployment + 配置 reload。
自动 instrumentation (k8s)
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
name: python-instr
spec:
exporter:
endpoint: http://otel-gateway:4317
python:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-python
# pod annotation
metadata:
annotations:
instrumentation.opentelemetry.io/inject-python: "true"
operator 自动 inject sidecar / init container → 应用零改动获得 trace /
metric。
metric processing
processors:
metricstransform:
transforms:
- include: http.server.duration
action: update
new_name: http_request_duration_seconds
OTEL metric 名换成 Prometheus 风格 → 兼容 Grafana 老 dashboard。
与 vector 对比
vector (Datadog OSS) 是另一通用 telemetry pipeline:
| OTEL Collector | Vector | |
|---|---|---|
| 标准 | OTEL(CNCF) | Datadog 自家 |
| log | ✅ | ✅ 强 |
| metric | ✅ | ✅ |
| trace | ✅ 强 | 弱 |
| 配置 | YAML | TOML |
| 性能 | 中 | 极高(Rust) |
trace 重 → OTEL。
log / metric pipeline + 极致性能 → Vector。
我用 OTEL 因为标准化优势 + 跨多后端。
与 fluentd / fluent-bit
fluent-bit / fluentd 主要 log shipper,metric / trace 弱。
新项目用 OTEL 一栈。
老 ELK 项目可能仍 fluent。
真实 case
新项目从 0 设计 observability:
应用(Python / Go / TS) + OTEL SDK auto-instrument
↓ OTLP gRPC
otel-collector (DaemonSet, 每 node)
↓ OTLP
otel-collector (gateway, 3 replica)
↓
├─ trace → Tempo
├─ metric → Mimir
└─ log → Loki
↓
Grafana 统一查看
一套 SDK + 一套 collector → 3 类数据 → Grafana 一处看(trace ID
关联 log 和 metric)。
trace ID 关联是杀手:error 看 trace → 同 trace ID 拉 log → 看 metric
spike 时间窗口。debug 速度极大提升。
踩过的坑
-
OTLP gRPC vs HTTP:默认 4317 是 gRPC,4318 HTTP。client 配错
端口报错。 -
batch processor 太大:batch 太大 latency 高 + OOM 风险。
send_batch_size: 8192调。 -
tail sampling 内存:高 QPS 时 buffer 几秒 trace → 几 GB RAM。
gateway 单独 deployment,分配大内存。 -
auto-instrument 性能:某些 framework 全部 instrument 后 P99
涨。disable 不重要的(health check / metrics endpoint)。 -
多 env tag 漏:dev / staging / prod 数据混 → 难区分。
resource_attributes: env=prod强制加。
登录后参与评论。