Программа курса

Модуль 03 / Урок 11 из 27

OpenTelemetry Collector: пайплайны телеметрии

Теория и практика

Collector — швейцарский нож телеметрии: единая точка приёма, обработки и маршрутизации. Большинство прод-фич трассировки (tail sampling, фильтрация PII, резервные маршруты) живут именно здесь.

Модель: receivers → processors → exporters

# otel-collector-config.yaml
receivers:
  otlp:
    protocols:
      grpc: { endpoint: 0.0.0.0:4317 }
      http: { endpoint: 0.0.0.0:4318 }

processors:
  memory_limiter:
    check_interval: 1s
    limit_percentage: 75
    spike_limit_percentage: 15
  tail_sampling:                  # подробно — урок 5.2
    decision_wait: 10s
    num_traces: 50000
    policies:
      - name: errors
        type: status_code
        status_code: { status_codes: [ERROR] }
      - name: slow
        type: latency
        latency: { threshold_ms: 1000 }
      - name: base
        type: probabilistic
        probabilistic: { sampling_percentage: 5 }
  batch:
    send_batch_size: 1024
    timeout: 5s

exporters:
  otlp/jaeger:
    endpoint: jaeger:4317
    tls: { insecure: true }
  debug: {}                       # печатает в лог (для отладки)

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, tail_sampling, batch]
      exporters: [otlp/jaeger]

Ключевые процессоры

ПроцессорЗачем
batchагрегация в батчи — экономия сети и записи; почти всегда последний в цепочке
memory_limiterзащита самого Collector от OOM; первым в цепочке
tail_samplingрешение по завершённому трейсу (урок 5.2)
attributes / resourceдобавить/удалить/переписать атрибуты: PII, нормализация имён сервисов
transformOTTL-скрипты: маскирование значений, вычисления
filterвыбросить шумные спаны (healthchecks, роботы)
k8sattributesобогащение спанов pod/namespace/owner из Kubernetes

Как деплоят Collector

  • Agent (sidecar/daemonset) — рядом с приложением: приём по localhost, кэш, отправка дальше. Разрывает связку «приложение ↔ бэкенд»;
  • Gateway (deployment/service) — централизованный пул: tail sampling, обогащение, маршрутизация. Масштабируется независимо;
  • Классическая прод-схема: agent (легкий: приём+batch) → gateway (тяжёлый: sampling, enrichment, routing) → Jaeger.
💡 Collector даёт главную развязку: смена хранилища трейсов не требует изменения ни одного приложения. Все смотрят на gateway, а он перенастраивается на новый бэкенд.

Надёжность и потери

  • Очередь отправки и retry_on_failure у экспортёров: переживают краткие паузы бэкенда;
  • При полном отказе приёмника данные теряются (in-memory) — для гарантированной доставки ставят exporter → Kafka (урок 3.4);
  • Лимиты: memory_limiter + лимиты входа; полезно мониторить otelcol_exporter_send_failed_* — счётчик потерь.

Практика

  1. Поднимите Collector между SDK и Jaeger (docker-compose): приложение шлёт в Collector, Collector — в Jaeger. Проверьте полный путь в UI.
  2. Добавьте filter: выкинуть спаны healthcheck-ов (/health) — убедитесь, что они исчезли из UI.
  3. Добавьте attributes-процессор: удалите атрибут db.statement (имитация PII-политики) и проверьте в UI.
  4. Сломайте экспорт (неверный endpoint) — посмотрите метрики Collector и поведение очереди.
Мини-квиз

1. Почему memory_limiter стоит первым, а batch — последним? — Сначала защититься от всплесков входа; батчить — уже обработанное перед отправкой.

2. Зачем два уровня Collector? — Agent — близко к приложениям (надёжный приём), gateway — централизованные тяжёлые операции и маршрутизация.

3. Что произойдёт с трейсами при падении Collector? — SDK примет отказ, не блокируя приложение; данные потеряются, если нет Kafka-буфера.