Урок по треку Наблюдаемость и SRE 7 мин

Трейсы и OpenTelemetry за 7 минут

Span и trace, распространение контекста, сэмплирование, OpenTelemetry SDK и Collector, Jaeger и Tempo, exemplars.

Распределённый трейс показывает путь одного запроса через все сервисы: кто кого вызвал, сколько длился каждый шаг, где случилась ошибка. Метрика скажет «p99 оформления заказа вырос до 3 секунд», трейс покажет «2.6 секунды из них ждали ответа от сервиса скидок».

Модель

  • Trace: всё дерево работы по одному запросу, у него trace_id (16 байт, 32 hex-символа).
  • Span: одна операция внутри трейса: входящий HTTP-запрос, запрос в базу, вызов другого сервиса. У спана свой span_id (8 байт), ссылка на родителя, начало и конец, имя, статус, атрибуты (http.request.method, db.system), события (например, исключение).
  • Kind: SERVER (обработка входящего), CLIENT (исходящий вызов), PRODUCER и CONSUMER (сообщения), INTERNAL.
  • Resource: кто прислал данные: service.name, версия, окружение, под. service.name обязателен, без него все спаны окажутся в «unknown_service».

Распространение контекста

Чтобы спаны разных сервисов собрались в одно дерево, контекст передаётся вместе с вызовом. Стандарт W3C Trace Context, заголовок:

traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
             версия-trace_id (32 hex)-родительский span_id (16 hex)-флаги

Флаг 01 означает «трейс сэмплирован, записывайте». Рядом бывают tracestate (данные конкретных вендоров) и baggage (пары ключ-значение, которые едут через всю цепочку, например tenant). В очередях контекст кладут в заголовки сообщения. Если хотя бы один сервис в цепочке не пробрасывает заголовок, трейс рвётся на две части.

OpenTelemetry

OpenTelemetry (OTel) открытый стандарт CNCF для сбора трейсов, метрик и логов, не привязанный к вендору.

  • API и SDK для языков: создать спан, добавить атрибуты, настроить экспорт.
  • Авто-инструментирование: Java-агент, opentelemetry-instrument для Python, пакеты для Node.js и .NET оборачивают HTTP-клиенты, серверы, драйверы баз без правки кода. Есть и инструментирование через eBPF без изменения процесса.
  • Semantic conventions: единые имена атрибутов (http.response.status_code, db.system, server.address), чтобы бэкенды понимали данные одинаково.
  • OTLP: протокол передачи, по умолчанию порт 4317 для gRPC и 4318 для HTTP.
  • Collector: отдельный процесс-конвейер: receivers (OTLP, Jaeger, Prometheus) → processors (batch, memory_limiter, фильтрация, добавление атрибутов, сэмплирование) → exporters (Tempo, Jaeger, вендоры). Ставится агентом на узел и шлюзом перед хранилищем.
receivers:
  otlp:
    protocols: { grpc: {}, http: {} }
processors:
  memory_limiter: { check_interval: 1s, limit_percentage: 80 }
  batch: {}
exporters:
  otlp/tempo:
    endpoint: tempo:4317
    tls: { insecure: true }
service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlp/tempo]

Сэмплирование

Хранить все трейсы высоконагруженного сервиса дорого. Варианты:

  • Head-based: решение принимается в начале трейса (например, 5% по trace_id) и передаётся флагом дальше, все сервисы согласны. Дёшево, но решение принимается до того, как известно, был ли запрос медленным или ошибочным.
  • Tail-based: Collector ждёт окончания трейса и решает по его содержимому: сохранить все ошибки, все медленнее 2 секунд и 1% остальных. Точнее, но все спаны одного трейса должны попасть в один экземпляр Collector (балансировка по trace_id), и нужно держать трейсы в памяти.

Стандартный сэмплер SDK ParentBased(TraceIdRatioBased): уважает решение родителя, а корневые спаны сэмплирует по доле.

Бэкенды

  • Jaeger: классический открытый бэкенд, вторая версия построена на OpenTelemetry Collector.
  • Grafana Tempo: хранит трейсы в объектном хранилище, ищет по TraceQL, дешёв на больших объёмах.
  • Zipkin, коммерческие APM.

Связь с метриками и логами

  • Exemplars: к точке гистограммы задержки прикрепляется trace_id конкретного запроса. На графике p99 видно точку, клик ведёт в трейс.
  • trace_id в логах: из спана открываются логи именно этого запроса.
  • Метрики из спанов: Collector или Tempo могут строить RED-метрики по спанам (span metrics, service graph).

Частые ошибки

  • Не пробрасывают контекст через очередь или самописный HTTP-клиент: трейсы рвутся.
  • Нет service.name.
  • Атрибуты с персональными данными и токенами.
  • Сэмплирование 100% в проде без оценки стоимости, или 0.1% без tail-sampling, и нужных трейсов ошибок нет.
  • Имена спанов с ID (GET /users/123): высокая кардинальность в бэкенде. Нужен шаблон маршрута.

Что спросят на собесе

  • Что такое trace и span, как связываются спаны разных сервисов.
  • Что в заголовке traceparent.
  • Head-based против tail-based сэмплирования.
  • Из чего состоит OpenTelemetry и зачем Collector.
  • Как связать трейсы с метриками и логами.

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.