OpenTelemetry: один стандарт вместо десятка SDK¶
В главе «Телеметрия» мы говорили про три типа данных — метрики, логи, трейсы. И про то, что в каждой компании исторически собирали их по-своему: Prometheus для метрик, ELK для логов, Jaeger для трейсов. Каждая система со своим агентом, своим протоколом, своим форматом.
OpenTelemetry (OTel) — это попытка индустрии договориться: один открытый стандарт вместо десятка проприетарных SDK. Как OpenAPI для REST или OpenSLO для SLO. Не продукт, не компания, не библиотека — стандарт, реализованный в виде SDK и инструментов, который к 2026 году стал де-факто выбором для новых проектов.
Зачем это нужно¶
До OpenTelemetry типичная интеграция выглядела так: ваш сервис на Python пишет метрики в Prometheus через prometheus_client, логи шлёт в Elasticsearch через Logstash, трейсы — в Jaeger через OpenTracing. Три разных SDK, три разных агента, три разных способа конфигурировать sampling и enrichment. И каждый SDK имеет свой API, свои best practices, свои баги.
Приходит момент, когда нужно сменить backend (Prometheus → VictoriaMetrics, Jaeger → Tempo). И вы переписываете половину кода, потому что SDK привязан к конкретному вендору. С OpenTelemetry такой проблемы нет: код пишется один раз, а backend меняется через конфигурацию Collector-а.
Что входит в OpenTelemetry¶
OpenTelemetry — это не один продукт, а семейство компонентов:
1. API и SDK¶
Единый API для метрик, логов и трейсов на разных языках: Java, Python, Go, Node.js, .NET, Rust, PHP, Ruby, C++, Erlang/Elixir, Swift. Каждый SDK поддерживает три сигнала (signals):
- Traces — распределённые трейсы (раньше OpenTracing + OpenCensus)
- Metrics — счётчики, гистограммы, gauge-значения
- Logs — структурированные логи с привязкой к трейсу
Главная фишка — resource attributes: контекст, который прикрепляется ко всем сигналам автоматически. Сервис, версия, окружение, регион, кластер Kubernetes. Один раз настроили — все метрики/трейсы/логи обогащаются одинаковыми метаданными.
2. Collector¶
OpenTelemetry Collector — это прокси между приложениями и бэкендами. Архитектурно похож на Vector, Fluentd, Logstash: принимает данные по одному протоколу, обрабатывает и отправляет в нужный backend.
[Приложение с OTel SDK]
↓ OTLP (gRPC/HTTP)
[OpenTelemetry Collector]
↓ приёмники → процессоры → экспортёры
[Prometheus, Jaeger, Tempo, Datadog, Sentry, ...]
Collector работает в трёх режимах: - Agent — рядом с приложением, форвардит данные - Gateway — центральный, агрегирует данные от нескольких агентов - Sidecar — в Kubernetes как sidecar к поду
3. Семантические конвенции¶
Стандартные имена для атрибутов: http.method, http.status_code, db.system, messaging.destination. Без этого каждый разработчик называет поля как попало, и потом аналитик тратит дни на маппинг. OTel конвенции решают эту проблему на корню.
4. Auto-instrumentation¶
Для популярных библиотек (HTTP-клиенты, SQL-ORM, gRPC, Redis, Kafka) есть готовые инструментации. Не надо вручную оборачивать вызовы — добавляется агент или пакет, и все вызовы автоматически трейсятся с правильными span-ами.
В Java это вообще магия: -javaagent:opentelemetry-javaagent.jar — и ваш Spring Boot пишет трейсы в OTLP без изменений в коде.
Как это выглядит на практике¶
Типичный pipeline в Kubernetes:
- Приложение запускается с OTel SDK (или Java/Python/.NET auto-instrumentation)
- SDK отправляет данные в OTel Collector через OTLP — стандартный бинарный протокол на gRPC или HTTP+JSON
- Collector запускается как DaemonSet на каждом узле (или как deployment с replicas)
- Collector обрабатывает данные: фильтрует, обогащает, батчит, сэмплит
- Collector экспортирует данные в нужные backend-ы параллельно: Prometheus, Jaeger, Loki, Datadog, New Relic — что угодно
Преимущество: поменять backend = поменять конфиг Collector-а. Код приложения не трогаем.
OpenTelemetry и «три столпа observability»¶
Старая школа учит: метрики + логи + трейсы = observability. OpenTelemetry технически поддерживает все три, но в комьюнити набирает силу мнение, что это устаревшая рамка. Подробнее — в главе «Wide Events и Observability 2.0».
Если коротко: вместо трёх разных типов данных с разными SDK лучше иметь одно широкое событие со всем контекстом. OpenTelemetry в новых релизах движется именно туда — концепция Log + Span объединяется.
Что делать с существующими инструментами¶
Если у вас уже есть Prometheus + Jaeger + Loki, переезжать на OpenTelemetry не обязательно. OTel Collector может работать как прослойка: принимать OTLP от новых сервисов, читать Prometheus exposition формат от старых, и экспортировать всё в существующие backend-ы.
Поэтому типичная стратегия миграции: - Новые сервисы — пишутся с OTel SDK с первого дня - Старые сервисы — продолжают работать как раньше (Prometheus pull, Jaeger SDK) - Collector — становится единой точкой, куда сходятся все потоки - Backend-ы — можно менять постепенно, не трогая код
Практический пример: Python-сервис¶
from opentelemetry import trace, metrics
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
from opentelemetry.sdk.resources import Resource
# Контекст, который прикрепится ко всем сигналам
resource = Resource.create({
"service.name": "payment-api",
"service.version": "1.4.2",
"deployment.environment": "production",
})
trace.set_tracer_provider(TracerProvider(resource=resource))
metrics.set_meter_provider(MeterProvider(resource=resource))
tracer = trace.get_tracer(__name__)
meter = metrics.get_meter(__name__)
# Метрика
request_counter = meter.create_counter(
"http.server.requests",
description="Количество HTTP-запросов"
)
# Трейс
with tracer.start_as_current_span("process_payment") as span:
span.set_attribute("payment.amount", 100)
span.set_attribute("payment.currency", "RUB")
# ... бизнес-логика ...
request_counter.add(1, {"http.method": "POST", "http.route": "/pay"})
Дальше эти сигналы уходят в OTel Collector → в Prometheus + Jaeger. Код ничего не знает про backend-ы.
Сравнение с альтернативами¶
| Инструмент | Что делает | Отличие от OTel |
|---|---|---|
| Prometheus client | Метрики | Вендор-специфичный, pull-модель |
| Jaeger SDK | Трейсы | Только трейсы, свой протокол |
| StatsD | Метрики | Устаревший, push-модель |
| Datadog APM | Метрики + трейсы | Проприетарный, vendor lock-in |
| OpenTelemetry | Все три сигнала | Открытый стандарт, vendor-agnostic |
OpenTelemetry не заменяет backend-ы — он заменяет SDK, через которые приложение отправляет данные в эти backend-ы.
Когда НЕ нужен OpenTelemetry¶
- Простой монорепо с одной командой — можно обойтись нативными инструментами фреймворка
- Legacy без миграций в планах — переписывать SDK ради переезда на стандарт нет смысла
- Если уже есть зрелая обвязка (Datadog APM, New Relic) — её SDK тоже неплохие, и менять ради стандарта нет причин
- Маркетинговая гонка за «современным стеком» — OTel не самоцель, а средство
Резюме¶
OpenTelemetry — это открытый стандарт для инструментации приложений: единый SDK для метрик, логов и трейсов, единый протокол (OTLP), единый агент (Collector), единые семантические конвенции. В 2026 это де-факто выбор для новых проектов и стратегия миграции для существующих.
Не нужно переписывать всё за выходные. Начните с того, что новые сервисы пишутся с OTel SDK, а Collector становится единой точкой сбора телеметрии. Старые сервисы продолжают работать как раньше — через Pull-модель Prometheus или свой SDK. Со временем доля OTel будет расти, и в какой-то момент смена backend-а станет делом конфигурации, а не переписывания.
См. также: «Телеметрия», «Wide Events и Observability 2.0», «SLO как код», «OpenSLO: декларативный стандарт для SLO».