ZIM-НИЙ SAAALEЗимние скидки: до −50% на старт и −20% на продление
до 31.01.2026 Подробнее
Выберите продукт

Grafana Tempo + Loki + Prometheus: корреляция traceID и быстрый triage инцидентов

Пошагово связываем Grafana Tempo, Loki и Prometheus в единую observability-схему: OpenTelemetry-трейсы, логи с traceID и метрики. Итог — быстрый triage: от алерта к логам и конкретному trace за минуты, с понятным runbook для дежурных смен.
Grafana Tempo + Loki + Prometheus: корреляция traceID и быстрый triage инцидентов

Когда «что-то тормозит» или «сыпятся 5xx», большинство команд по привычке прыгают между тремя мирами: метрики (Prometheus), логи (Loki) и трассировки (Grafana Tempo). Самое неприятное не в том, что инструментов много, а в том, что они живут отдельно: алерт показывает деградацию, логов слишком много, а трассировку нужного запроса ещё надо уметь найти.

Ниже — практичная схема корреляции: чтобы из алерта по метрикам переходить к логам, а из логов — к конкретному trace по trace_id. Это сильно ускоряет triage (первичную диагностику инцидента) и превращает observability в повторяемый runbook, а не в «красивые графики».

Что даёт Tempo в связке с Loki и Prometheus

Prometheus отвечает на вопрос «что сломалось и насколько»: рост латентности, всплеск ошибок, насыщение ресурсов. Но метрика редко говорит «почему» и «в каком запросе».

Loki отвечает на вопрос «что происходило по шагам»: сообщения приложения, stack trace, причины ошибок, контекст. Но при высокой нагрузке логов много, и поиск нужной цепочки событий может занять десятки минут.

Grafana Tempo отвечает на вопрос «как именно прошёл конкретный запрос»: какие сервисы участвовали, где была задержка, какой downstream дал ошибку. Это и есть distributed tracing.

Ключевой момент: ценность даёт не «наличие трейсинга», а быстрые переходы:

  • из алерта (метрики) к соответствующему сегменту логов (Loki);
  • из конкретной строки лога к trace (Tempo) по trace_id;
  • из trace обратно к метрикам и логам по атрибутам и времени.

Эта «склейка» и называется correlation. В результате triage превращается в короткий, повторяемый сценарий.

Целевая архитектура: минимальный набор компонентов

Есть два уровня: «минимально рабочий» и «продакшен-осмысленный». Для большинства небольших и средних проектов достаточно первого, но если хотите нормальный tail-sampling и аккуратную маршрутизацию телеметрии — лучше сразу предусмотреть коллектор.

Минимально рабочая схема

  • Prometheus собирает метрики сервисов.
  • Loki принимает логи (через promtail или другой агент).
  • Tempo принимает трассы.
  • Grafana подключена к трём источникам данных и умеет прыгать между ними.
  • Приложения инструментированы через OpenTelemetry (SDK или авто-инструментация).

Продакшен-осмысленная схема (рекомендация)

  • OpenTelemetry Collector как единая точка приёма телеметрии (трейсы/метрики/логи) и маршрутизации.
  • Отдельные политики sampling (в приложении и/или в коллекторе).
  • Единые поля корреляции: trace_id, span_id, service.name, deployment.environment.

Самая частая причина «Tempo есть, но толку мало» — отсутствие дисциплины в корреляционных полях. Если в логах нет traceID, быстрый путь от ошибки к trace не построится.

Если вы размещаете Grafana-стек рядом с приложением и хотите контролируемые ресурсы и сеть (особенно для Collector, Loki/Tempo и их дисков), удобнее поднимать всё на отдельной VDS и уже там централизовать телеметрию.

Схема потока телеметрии: OpenTelemetry Collector, Tempo, Loki и Prometheus

База корреляции: откуда берётся traceID и как его не потерять

trace_id рождается в момент начала трассировки (обычно на входе в систему: HTTP/gRPC gateway, ingress, edge-сервис). Дальше он должен пройти сквозь все компоненты запроса: прокси, приложение, очередь, downstream-сервисы.

Чтобы корреляция работала, обеспечьте три вещи:

  • Контекст трассировки корректно передаётся между сервисами (W3C Trace Context: заголовок traceparent и опционально tracestate).
  • Логи содержат trace_id (и желательно span_id) в отдельном поле или стабильно парсимом формате.
  • Метрики позволяют сузить поиск до нужного сервиса/эндпоинта/инстанса, чтобы не «прочёсывать» всю систему.

Практическое правило: лог «ошибка в обработчике платежей» почти бесполезен. Лог «ошибка в обработчике платежей, trace_id=…, request_id=…» превращает triage в быстрый, последовательный процесс.

Инструментирование: OpenTelemetry для distributed tracing

Самый устойчивый путь — OpenTelemetry. Он задаёт стандарт на уровне SDK, протокола передачи (OTLP) и семантических атрибутов. В контексте Tempo это важно по двум причинам:

  • Tempo отлично принимает OTLP (HTTP/gRPC) напрямую или через OpenTelemetry Collector.
  • Вы получаете предсказуемые поля вроде service.name, которые удобно использовать в Grafana для фильтрации и навигации.

Рекомендуемая практика — задавать:

  • service.name — неизменное имя сервиса (например, billing-api);
  • service.version — версия/релиз (полезно при раскатках и сравнении регрессий);
  • deployment.environmentprod/stage (и далее как у вас принято).

Если у вас микросервисы, не экономьте время на унификацию: разнобой в названиях сервисов и окружений ломает фильтры и усложняет triage.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Логи: как связать Loki с Tempo через traceID

Loki — это система, где эффективность строится на лейблах и разумной структуре логов. Для корреляции с Tempo важнее всего, чтобы trace_id было:

  • либо отдельным полем в JSON-логе (идеально);
  • либо стабильным фрагментом строки, который можно вытащить парсером на стороне агента или запросом.

Практическая схема:

  • Приложение пишет structured logs (JSON) и добавляет поля trace_id, span_id.
  • Агент доставки (например, promtail) парсит JSON и поднимает часть полей в labels (очень аккуратно), а остальное оставляет в теле лога.
  • В Grafana настраивается извлечение trace_id из логов и переход в Tempo по найденному идентификатору.

Критически важно: не делайте trace_id лейблом Loki. У traceID огромная кардинальность, это быстро превратит Loki в дорогой и медленный индексатор. TraceID должен жить в теле лога и использоваться для точечного поиска и клика в Tempo.

Если хотите глубже разобраться с тем, какие поля действительно стоит поднимать в labels и как собирать пайплайны без взрыва кардинальности, держите отдельный разбор: лейблы и pipeline-обработка в Loki.

Какие поля логировать для эффективного triage

Минимальный набор для веб-сервисов:

  • timestamp, level, message
  • service или service.name
  • trace_id, span_id
  • http.method, http.route или понятный endpoint
  • status или http.status_code
  • duration_ms (если логируете окончания запросов)

Дополнительно по ситуации — request_id (если он уже есть в системе), идентификаторы джоб/очередей, и аккуратно — пользовательские идентификаторы (с учётом требований безопасности и приватности).

Метрики: как Prometheus помогает быстро сузить область поиска

Prometheus обычно остаётся «входной точкой» в инцидент: алерт срабатывает по latency/error rate. Чтобы следующий шаг был быстрым, метрики должны быть:

  • привязаны к сервису (job, instance, service);
  • иметь разрезы по ключевым маршрутам/операциям (route, handler) там, где кардинальность контролируема;
  • коррелироваться по времени с логами и trace (синхронизация времени на хостах обязательна).

На практике triage выглядит так: алерт показал рост p95 на /api/payments в billing-api. Вы фильтруете логи Loki по сервису и временному диапазону, находите ошибки/таймауты и берёте trace_id проблемного запроса. Дальше Tempo покажет, где именно потеряли время.

Настройка correlation в Grafana: быстрые переходы «метрики → логи → trace»

В Grafana корреляция складывается из двух частей:

  • связка источников данных Loki, Tempo и Prometheus в Explore;
  • правила извлечения trace_id из логов и переход в Tempo по найденному идентификатору.

Реализация зависит от формата логов. Если это JSON, обычно проще: trace_id — отдельное поле. Если это текст, договоритесь о формате (например, trace_id=), чтобы регулярка была надёжной.

Проверка работоспособности простая:

  1. Откройте Loki Explore и найдите строки с trace_id в нужном окне времени.
  2. Перейдите по trace_id в Tempo.
  3. В Tempo найдите проблемный span (БД, внешний API, очередь, DNS/TLS и т. п.).
  4. Вернитесь в Loki и посмотрите соседние логи этого сервиса вокруг времени проблемного участка.

Если переход из логов «работает», но trace не находится, чаще всего виноваты sampling/retention или смешанные окружения без явной маркировки (например, нет deployment.environment).

Экран Grafana Explore: переход из строки лога по traceID к трассировке в Tempo

Sampling и стоимость: как не утонуть в трассировках

Distributed tracing легко «съедает» ресурсы, если включить 100% sampling на высоконагруженном фронте. Для triage обычно не нужно хранить все trace: нужно хранить достаточно, чтобы быстро находить репрезентативные проблемные случаи.

Практичные подходы:

  • Head-based sampling (на входе): например, 1–10% запросов.
  • Tail-based sampling (после завершения trace): сохраняете 100% ошибочных и медленных, а остальное — по проценту.
  • Отдельные правила для эндпоинтов: health-check почти всегда можно исключить.

Чтобы tail-based sampling работал корректно, обычно нужен OpenTelemetry Collector или другой компонент, который видит trace целиком и может принять решение «сохранять/не сохранять».

Сценарий triage: от алерта до root cause за 5–10 минут

Ниже — алгоритм, который удобно закрепить как короткий runbook для дежурной смены.

1) Старт: алерт Prometheus

Смотрим: какой сервис, какой маршрут/операция, какой тип деградации (p95/p99, error rate, saturation). Ограничиваем окно времени, например последние 15 минут.

2) Переход в Loki: подтверждаем симптом

Фильтруем логи по сервису и времени, ищем ошибки и маркеры деградации:

  • 5xx/exception;
  • timeouts upstream/downstream;
  • признаки деградации БД/очередей;
  • ошибки подключения (DNS, TLS, pool exhausted).

Берём 1–3 характерных примера и выписываем их trace_id.

3) Переход в Tempo: где «пропало время»

Открываем trace по trace_id и смотрим критический путь:

  • какой span самый долгий;
  • какой downstream вызов вернул ошибку;
  • есть ли ретраи, fan-out, очереди;
  • корректны ли таймауты на уровне клиента.

4) Возврат к метрикам: проверяем гипотезу

Если Tempo показывает задержку в БД — возвращаемся к метрикам БД/пула соединений. Если проблема во внешнем API — смотрим метрики ретраев, таймаутов и rate limit. Связка полезна тем, что каждый шаг подтверждает предыдущий: метрика дала направление, лог дал конкретный случай, trace показал структуру и «узкое место», метрика закрыла гипотезу системно.

Типовые ошибки внедрения и как их избежать

TraceID не попадает в логи

Это проблема №0. Решение: настроить логгер на добавление полей из контекста трассировки. Обычно это делается через middleware/handler, который кладёт trace/span в MDC/контекст и сериализует их в JSON.

Слишком высокая кардинальность в Loki

Нельзя превращать в labels то, что уникально почти для каждого запроса: trace_id, userID, requestID. Лейблы должны быть «грубыми»: сервис, окружение, уровень, кластер, namespace. Остальное — в теле лога.

Нет единых имён сервисов и окружений

Если один и тот же сервис где-то называется billing, где-то billing-api, а где-то payments, то фильтры и дашборды будут «дырявыми». Договоритесь о naming convention сразу и зафиксируйте в шаблонах деплоя.

Sampling отрезает именно то, что нужно

При чисто процентном head-based sampling можно не сохранить редкую, но критичную ошибку. Для triage хорошо работает правило: ошибки и сильно медленные запросы сохраняем чаще (tail-based или отдельные правила).

Мини-чеклист готовности: «можно дежурить по этой системе»

  • В каждом сервисе включён OpenTelemetry и задан service.name.
  • В логах есть trace_id (и желательно span_id).
  • Grafana умеет переходить из Loki в Tempo по traceID.
  • Есть базовые RED-метрики в Prometheus (rate, errors, duration) по ключевым сервисам.
  • Настроены retention и sampling так, чтобы проблемные trace не исчезали слишком быстро.
  • Время синхронизировано на хостах, иначе корреляция по таймлайну ломается.
Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Итог

Связка Grafana Tempo, Loki и Prometheus — это про скорость и воспроизводимость triage. Prometheus даёт сигнал и масштаб проблемы, Loki даёт контекст и конкретную ошибку, Tempo показывает структуру запроса и место деградации. А correlation по trace_id превращает это в единый маршрут расследования, который реально экономит часы во время инцидента.

Если внедряете observability поэтапно, начинайте с дисциплины: единые имена сервисов, trace_id в логах, базовые метрики. Дальше добавляйте Tempo и правила sampling — и вы получите «APM-эффект» без монолитного APM-вендора, на открытых компонентах.

Для отдельных задач мониторинга (проверки доступности HTTP/TCP/ICMP, сертификатов, внешних зависимостей) удобно дополнять схему синтетическими проверками; см. разбор: настройка blackbox-exporter для Prometheus.

Поделиться статьей

Вам будет интересно

Kubernetes DNS: таймауты, MTU и conntrack — диагностика через CoreDNS, tcpdump и PMTUD OpenAI Статья написана AI (GPT 5)

Kubernetes DNS: таймауты, MTU и conntrack — диагностика через CoreDNS, tcpdump и PMTUD

Если в Kubernetes периодически не резолвится DNS или внешние API отвечают timeout, причина часто в MTU/PMTUD, conntrack и настройк ...
Kubernetes CrashLoopBackOff: события, пробы, exit codes и backoff — практический разбор OpenAI Статья написана AI (GPT 5)

Kubernetes CrashLoopBackOff: события, пробы, exit codes и backoff — практический разбор

CrashLoopBackOff в Kubernetes — не «ошибка», а симптом: контейнер быстро завершается, kubelet перезапускает его и увеличивает пауз ...
Apache 403 Forbidden: права, Require, DocumentRoot, suEXEC и SELinux — практическая диагностика OpenAI Статья написана AI (GPT 5)

Apache 403 Forbidden: права, Require, DocumentRoot, suEXEC и SELinux — практическая диагностика

403 Forbidden в Apache почти всегда означает явный запрет: правило Require/Directory, несоответствие DocumentRoot/Alias, права на ...