объединить трейсы, метрики и логи через масштабируемый уровень Collector
OpenTelemetry Collector промышленного уровня: единый конвейер для трейсов, метрик и логов
14 минут
Три отдельных стека — Jaeger, Prometheus и Fluentd — утраивают операционную нагрузку и мешают корреляции сигналов. В материале — агент и шлюз Collector с лимитами памяти, отложенной выборкой трейсов, очередями экспорта и развёртыванием через Helm в Kubernetes.
Почему три стека агентов ломают корреляцию и растут вместе с нагрузкой
Во многих средах за трейсы отвечают Jaeger или Zipkin, за метрики — Prometheus или StatsD, за логи — Fluentd или Vector. У каждого стека свой жизненный цикл конфигурации, профиль ресурсов и характерный сбой. Когда трафик удваивается, операционная работа часто утраивается. Связать медленный трейс со всплеском задержки и записью об ошибке в логе по-прежнему значит вручную переключаться между панелями мониторинга — сигналы не получают общий контекст уже на этапе приёма. Архитектурный выход — вендорно-нейтральный канал телеметрии: приложения отправляют OTLP, коллекторы обрабатывают и маршрутизируют данные централизованно, а системы хранения становятся взаимозаменяемыми.
Модель конвейера Collector: приёмники, процессоры, экспортёры и соединители
OpenTelemetry Collector — один исполняемый модуль со составным конвейером для каждого типа сигнала. Приёмники принимают OTLP, сбор Prometheus, filelog или устаревшие форматы. Процессоры изменяют, фильтруют, прореживают или пакетируют данные. Экспортёры отправляют их в Tempo, Prometheus remote write, Loki или сторонние системы. Соединители связывают конвейеры между собой: например, spanmetrics превращает трейсы в метрики без отдельного пути инструментирования. Типичная схема для продакшена: агент на каждом узле для локального приёма и лёгкого пакетирования плюс центральный шлюз для отложенной выборки трейсов, обогащения атрибутов и рассылки в несколько хранилищ. Используйте дистрибутив contrib, если не уверены, что базовых OTLP-компонентов будет достаточно.
Уровень агента: локальный приём, лимиты памяти, пересылка на шлюз
Разворачивайте агент как DaemonSet Kubernetes или сайдкар рядом с приложением. Он принимает OTLP от SDK приложения или автоинструментирования, первым ставит процессор memory_limiter, затем batch и пересылает данные на шлюз по TLS. Агент не является долговременным буфером: очереди по умолчанию живут в памяти, а при перегрузке экспортёров обратное давление распространяется к источникам выше по цепочке. Держите поды агента скромными по ресурсам и не размещайте на этом уровне тяжёлые процессоры.
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
memory_limiter:
check_interval: 1s
limit_mib: 400
spike_limit_mib: 100
batch:
timeout: 5s
send_batch_size: 8192
resource:
attributes:
- key: collector.tier
value: agent
action: upsert
exporters:
otlp/gateway:
endpoint: otel-gateway.observability.svc:4317
tls:
insecure: false
sending_queue:
enabled: true
queue_size: 4096
retry_on_failure:
enabled: true
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, resource, batch]
exporters: [otlp/gateway]
metrics:
receivers: [otlp]
processors: [memory_limiter, resource, batch]
exporters: [otlp/gateway]
logs:
receivers: [otlp]
processors: [memory_limiter, resource, batch]
exporters: [otlp/gateway]Уровень шлюза: отложенная выборка, обогащение и экспорт в несколько систем
Коллекторы-шлюзы работают как Deployment с большим объёмом памяти и CPU. Отложенная выборка трейсов (tail sampling) размещается здесь, чтобы решения принимались по полным цепочкам между сервисами. Перечисленные политики срабатывают по логике «или»: сохраняются ошибки, медленные запросы и небольшая случайная доля остального трафика. Процессор memory_limiter ставьте до выборки, обогащайте атрибуты окружения и команды, затем рассылайте сигналы в хранилища трейсов, метрик и логов. Для отладки во время инцидента включайте расширения health_check и zpages.
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
memory_limiter:
check_interval: 1s
limit_mib: 2048
spike_limit_mib: 512
tail_sampling:
decision_wait: 10s
num_traces: 100000
expected_new_traces_per_sec: 2000
policies:
- name: errors
type: status_code
status_code: { status_codes: [ERROR] }
- name: slow-requests
type: latency
latency: { threshold_ms: 1000 }
- name: sample-remainder
type: probabilistic
probabilistic: { sampling_percentage: 5 }
attributes:
actions:
- key: deployment.environment
action: upsert
value: production
- key: team
action: upsert
value: platform
batch:
timeout: 10s
send_batch_size: 16384
exporters:
otlp/tempo:
endpoint: tempo.observability.svc:4317
tls:
insecure: true
sending_queue:
enabled: true
queue_size: 8192
retry_on_failure:
enabled: true
prometheusremotewrite:
endpoint: https://mimir.example.com/api/v1/push
loki:
endpoint: http://loki.observability.svc:3100/loki/api/v1/push
extensions:
health_check:
endpoint: 0.0.0.0:13133
zpages:
endpoint: 0.0.0.0:55679
service:
extensions: [health_check, zpages]
telemetry:
metrics:
level: detailed
readers:
- pull:
exporter:
prometheus:
host: 0.0.0.0
port: 8888
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, tail_sampling, attributes, batch]
exporters: [otlp/tempo]
metrics:
receivers: [otlp]
processors: [memory_limiter, attributes, batch]
exporters: [prometheusremotewrite]
logs:
receivers: [otlp]
processors: [memory_limiter, attributes, batch]
exporters: [loki]Развёртывание в Kubernetes через Helm-чарт OpenTelemetry
Устанавливайте релизы агента и шлюза из официального Helm-чарта. Фиксируйте тег образа contrib и проверяйте конфигурацию командой otelcol validate в CI. Конфигурацию шлюза монтируйте из ConfigMap или задавайте через values-файл чарта. Масштабируйте шлюз горизонтально; при росте числа агентов добавьте балансировщик нагрузки или экспортёр loadbalancing для OTLP.
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm repo update
helm upgrade --install otel-agent open-telemetry/opentelemetry-collector \
--namespace observability --create-namespace \
--set mode=daemonset \
--set image.repository=otel/opentelemetry-collector-contrib \
--set image.tag=0.106.1 \
-f values/agent.yaml
helm upgrade --install otel-gateway open-telemetry/opentelemetry-collector \
--namespace observability \
--set mode=deployment \
--set replicaCount=3 \
--set image.repository=otel/opentelemetry-collector-contrib \
--set image.tag=0.106.1 \
-f values/gateway.yamlЭталонный шлюз: самомониторинг, конвейер логов и защита экспорта
Конфигурация ниже показывает полный путь для трейсов и метрик: самосбор метрик коллектора, обогащение ресурсов из входящих атрибутов и очереди у экспортёров. Конвейер для логов добавляйте по той же схеме, когда приложения шлют OTLP-логи. Инструментируйте код через OpenTelemetry SDK, чтобы trace_id и span_id попадали в структурированные логи — именно корреляция делает единую телеметрию полезной, а не просто сокращение числа демонов.
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
prometheus:
config:
scrape_configs:
- job_name: otelcol-self
scrape_interval: 15s
static_configs:
- targets: ['127.0.0.1:8888']
processors:
memory_limiter:
check_interval: 1s
limit_mib: 2048
spike_limit_mib: 512
tail_sampling:
decision_wait: 10s
num_traces: 200000
policies:
- name: error-policy
type: status_code
status_code: { status_codes: [ERROR] }
- name: slow-requests
type: latency
latency: { threshold_ms: 2000 }
- name: sample-5pct
type: probabilistic
probabilistic: { sampling_percentage: 5 }
resource:
attributes:
- key: deployment.region
value: eu-west-1
action: upsert
- key: service.version
from_attribute: git.commit.sha
action: upsert
batch:
timeout: 10s
send_batch_size: 16384
exporters:
otlp/tempo:
endpoint: tempo.observability.svc:4317
tls:
insecure: true
sending_queue:
enabled: true
retry_on_failure:
enabled: true
prometheusremotewrite:
endpoint: https://mimir.observability.svc/api/v1/push
debug:
verbosity: basic
extensions:
health_check:
endpoint: 0.0.0.0:13133
zpages:
endpoint: 0.0.0.0:55679
pprof:
endpoint: 0.0.0.0:1777
service:
extensions: [health_check, zpages, pprof]
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, tail_sampling, resource, batch]
exporters: [otlp/tempo, debug]
metrics:
receivers: [otlp, prometheus]
processors: [memory_limiter, resource, batch]
exporters: [prometheusremotewrite]Операционные практики для промышленного парка коллекторов
Ставьте memory_limiter первым в каждом конвейере и задавайте limit_mib примерно на семьдесят–восемьдесят процентов лимита памяти пода. Отложенную выборку и переписывание атрибутов оставляйте на шлюзе, не на агенте. Следите за метриками otelcol_exporter_send_failed_spans, otelcol_exporter_queue_size и otelcol_processor_refused_spans — потери на коллекторе означают слепые зоны ниже по цепочке. Фиксируйте тег образа, прогоняйте otelcol validate при изменении конфигурации и тестируйте обновления на staging: схема конфигурации меняется между минорными версиями. Разделяйте запросы ресурсов: агент остаётся лёгким, шлюзу нужен запас под буферы выборки. Подключайте процессоры resourcedetection и k8sattributes, когда на каждом сигнале нужны метаданные узла, пода и пространства имён. Единый уровень Collector сокращает зоопарк агентов и делает корреляцию трейсов, логов и метрик достижимой, если в коде приложения настроена передача контекста через SDK.
Начните с полезных сигналов и гигиены алертов из базового гайда по наблюдаемости для небольших платформенных команд.
Решения по выборке и хранению данных должны учитывать бюджет надёжности из практик SLO, SLI и error budget для платформенных команд.
