OpenTelemetry Collector:统一收集 trace / metric / log

起因

可观测性 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 速度极大提升。

踩过的坑

  1. OTLP gRPC vs HTTP:默认 4317 是 gRPC,4318 HTTP。client 配错
    端口报错。

  2. batch processor 太大:batch 太大 latency 高 + OOM 风险。
    send_batch_size: 8192 调。

  3. tail sampling 内存:高 QPS 时 buffer 几秒 trace → 几 GB RAM。
    gateway 单独 deployment,分配大内存。

  4. auto-instrument 性能:某些 framework 全部 instrument 后 P99
    涨。disable 不重要的(health check / metrics endpoint)。

  5. 多 env tag 漏:dev / staging / prod 数据混 → 难区分。
    resource_attributes: env=prod 强制加。

精确评价 共 0 人评价
可复现性
可复现 · 0 不可复现 · 0
文风
文风流畅 · 0 文风晦涩 · 0
立场
支持 · 0 反对 · 0

登录后即可对本帖作出评价。

评论区 0 条 · 所有人可在此交流

登录后参与评论。

还没有评论,来说两句。