ADG Оставить заявку
Блог DevOps 5 мин чтения

Grafana 8 + Tempo: разворачиваем distributed tracing и связываем его с метриками и логами

Grafana 8.0 GA объединила метрики, логи и трейсы в одном UI. Разбираем как поднять Tempo и получить корреляцию между Prometheus, Loki и трейсами в продакшне.

Контекст момента

Grafana 8.0 выходит в GA с единым UI для метрик (Prometheus), логов (Loki) и трейсов (Tempo) - unified observability stack в одном интерфейсе

Grafana 8.0 вышла в GA в начале июня, и мы с тех пор аккуратно смотрели на неё в нескольких клиентских окружениях. На этой неделе наконец развернули полный стек в одном из production-проектов - с Tempo для трейсов и корреляцией между тремя источниками данных. Поделимся что там внутри и где пришлось поработать руками.

Что изменилось в Grafana 8

Главное изменение не в отдельных datasource, а в концепции: теперь в одном UI можно переходить от метрики к логам к трейсу и обратно без смены инструмента. Prometheus показывает всплеск latency - кликаешь в точку на графике, видишь LogQL-запрос с тем же timerange в Loki, оттуда Trace ID из лога открывает конкретный span в Tempo. На бумаге это звучит как маркетинг, на практике - это существенное изменение того, как выглядит troubleshooting.

Ещё из заметных изменений в 8.0:

  • Unified alerting - алертинг переработан, теперь он не привязан к отдельной datasource а работает как отдельный движок поверх любого источника данных. Alertmanager интегрируется как routing layer.
  • Live streaming - дашборды могут обновляться в реальном времени через WebSocket без страничного refresh, интересно для операционных экранов.
  • Новый UI панелей - panel editor переписан, и сначала это сбивает с толку, потому что всё поменяло место.

Но нас интересует именно трейсинг и корреляция, об этом подробнее.

Tempo: что это и зачем

Grafana Tempo - относительно новый бэкенд для distributed tracing, первый релиз был в конце 2020-го. Концепция отличается от Jaeger и Zipkin: Tempo не индексирует span-атрибуты для поиска, хранит трейсы в объектном хранилище (S3, GCS, Azure Blob, локально), а искать трейсы предполагается по Trace ID, который пришёл из другого места - из лога или метрики. Это делает хранение дешёвым, но поиск «найди мне все медленные запросы» через UI Tempo не работает - нужен Loki или Prometheus как точка входа.

Для нашего сценария это хорошо: у нас уже есть Loki с логами сервисов, которые пишут Trace ID в structured fields. Значит, мы не теряем ничего существенного.

Как разворачивали

У клиента Kubernetes-кластер, Prometheus + Grafana 7.x уже стоит, Loki подняли несколько месяцев назад. Задача - добавить Tempo и обновить Grafana до 8.

Tempo развернули через Helm-чарт в минимальной конфигурации: один pod, локальный volume для хранения трейсов. Для production рекомендуют объектное хранилище, у нас пока S3-совместимое через MinIO - это не идеальное решение для серьёзной нагрузки, но для начала работает.

Конфигурация Tempo выглядит достаточно лаконично: указываешь бэкенд хранилища, порты для приёма трейсов (Tempo поддерживает OpenTelemetry, Jaeger, Zipkin протоколы через единый receiver), и базовые параметры compactor и querier.

Инструментирование приложений - это отдельная история. У клиента несколько Python и Go сервисов. OpenTelemetry SDK для обоих языков в целом зрелый. Основная работа - пробросить Trace ID через контекст запросов между сервисами, настроить exporter на Tempo endpoint.

Выяснилось, что часть сервисов уже использует что-то похожее на Jaeger через старые SDK - миграция потребовала замены клиентской библиотеки и изменения endpoint. Не трагедия, но несколько часов работы.

Корреляция логов и трейсов в Loki настраивается через derived fields в конфигурации datasource в Grafana. Указываешь регулярное выражение для извлечения Trace ID из лог-строки и URL для перехода в Tempo:

derivedFields:
  - name: TraceID
    matcherRegex: "trace_id=(\\w+)"
    url: "$${__value.raw}"
    datasourceUid: tempo-uid

После этого в Explore при просмотре логов появляется кликабельная ссылка на трейс. Это и есть та самая correlation, ради которой весь разговор.

Где пришлось повозиться

Grafana 8 и старые дашборды. При обновлении с 7.x часть дашбордов поломалась в плане UI - панели не пропали, данные сохранились, но panel editor изменился настолько, что некоторые кастомные настройки оказались перемещены в другие места. Особенно это коснулось overrides в таблицах. Потратили несколько часов на ревизию критичных дашбордов.

Unified alerting мы пока не переключали. В Grafana 8 есть legacy alerting mode, мы оставили его включённым - у клиента несколько десятков настроенных алертов, и одновременная миграция выглядит рискованно. Переход планируем отдельно, не совмещая с обновлением стека.

Tempo и retention. По умолчанию Tempo хранит всё. Retention настраивается через compactor, но документация на момент нашего развёртывания местами неполная - пришлось смотреть в исходники и issues GitHub. Настроили 7 дней через compactor block retention.

Sampling. Писать 100% трейсов в продакшне с нагруженным сервисом - не лучшая идея. Настроили probabilistic sampling на стороне приложения через OpenTelemetry SDK, 10% трейсов. Для нашего объёма запросов это даёт достаточно данных для анализа.

Что получили в итоге

Рабочая цепочка: всплеск на графике Prometheus - переход в Loki с тем же timerange - в логах видны ошибки с Trace ID - открываем трейс в Tempo и видим где именно в цепочке сервисов потерялось время. До этого каждый источник данных был отдельным инструментом, и correlation делалась вручную через timestamp.

Это не означает что все проблемы теперь диагностируются за секунды - трейс показывает что медленно, но не всегда объясняет почему. Но устранить одно ненужное переключение контекста между инструментами - это уже ощутимо.

Для клиентов на managed-сопровождении мы смотрим на этот стек как на стандартный набор для проектов с микросервисной архитектурой. Prometheus + Loki уже были частью базовой обвязки, Tempo и обновление до Grafana 8 логично закрывают трейсинг как третий столп observability.

Tempo молодой проект - Jaeger у него уже несколько лет форы. Но интеграция с Grafana здесь нативная, и если Prometheus + Loki уже стоят, добавление Tempo выглядит проще, чем разворачивать Jaeger с его UI отдельно.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.