Настройка Grafana Tempo для распределённого трейсинга

Когда метрики показывают аномалию, а логи фиксируют ошибку, но связать их в единую картину не удаётся, на помощь приходит распределённый трейсинг. Мы настраиваем Grafana Tempo для вашего проекта — от аудита инструментирования до внедрения и обучения команды. Реализуем решение под ключ, обеспечивая стабильную работу и последующую поддержку.
Часто задаваемые вопросы

Метрики показывают аномалию латентности, логи фиксируют ошибку, но связать их в единую картину не удаётся. Мы часто сталкиваемся с такой ситуацией: RPS вырос, 99-й перцентиль упал до 800 мс, а причина — в одном запросе, который цепляет 10 микросервисов. Без трейсинга найти эту точку — иголка в стоге сена. Grafana Tempo — бэкенд распределённого трейсинга, который органично интегрируется с Prometheus и Loki в едином интерфейсе Grafana. Решение под ключ: от аудита инструментирования до настройки корреляций и обучения команды. Закажите аудит вашей системы — получите план внедрения за один день. Свяжитесь, чтобы обсудить детали внедрения.

Как настроить Grafana Tempo для распределённого трейсинга?

Tempo не строит индексы по содержимому трейсов. Он хранит данные прямо в объектном хранилище (S3, GCS), индексируя только Trace ID. Это даёт радикальное снижение стоимости хранения — до 70% экономии по сравнению с Jaeger, который требует Elasticsearch или Cassandra. На практике Tempo значительно дешевле: например, хранение 1 ТБ трейсов в S3 обходится в разы меньше. Для проекта с 20 микросервисами и нагрузкой 5000 спанов в секунду экономия на хранении превышает 2000 долларов в месяц. Минус — поиск по атрибутам без специального языка запросов невозможен. Однако модель работы «нашёл аномалию в метриках — перешёл к конкретному трейсу» покрывает 90% сценариев диагностики. Для ad-hoc поиска используйте TraceQL, доступный с Tempo 2.0.

Tempo vs Jaeger: стоимость хранения

Критерий Jaeger (с Elasticsearch) Tempo (S3)
Стоимость хранения (1 ТБ/мес) Высокая Низкая (до 90% экономии)
Индексация Полная по всем атрибутам Только Trace ID
Поиск по атрибутам Да Через TraceQL или корреляцию
Ретенция Ограничена объёмом кластера Практически безлимитна

Экономия достигается за счёт отказа от дорогого индекса. Мы используем tail sampling в OpenTelemetry Collector, чтобы отфильтровать шум: все ошибки и медленные запросы сохраняются, остальные — с вероятностью 10%. Это ещё вдвое снижает объём хранимых данных без потери диагностической ценности.

Сравнение методов сэмплирования

Параметр Head-based sampling Tail sampling
Решение о сэмплировании На стороне приложения (до отправки) В Collector (после сбора всех спанов)
Контроль ошибок Невозможно гарантировать сохранение всех ошибок Можно настроить политики (все ошибки сохраняются)
Ресурсы Низкая нагрузка на Collector Требуется OTLP-ресивер и буферизация
Гибкость Фиксированная вероятность Множество политик (latency, status_code)

Для production-окружений мы рекомендуем tail sampling — он даёт максимальную полноту критичных трейсов.

Инструментирование приложений с OpenTelemetry

Tempo принимает трейсы через OTLP (рекомендуем), Jaeger или Zipkin. Пример подключения Python:

from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

provider = TracerProvider()
exporter = OTLPSpanExporter(endpoint="http://otel-collector:4317", insecure=True)
provider.add_span_processor(BatchSpanProcessor(exporter))
trace.set_tracer_provider(provider)
tracer = trace.get_tracer(__name__)

with tracer.start_as_current_span("process_order") as span:
    span.set_attribute("order.id", order_id)
    result = process(order_id)

Трейсы отправляются в OpenTelemetry Collector, который выполняет сэмплирование и форвардит в Tempo. Мы рекомендуем использовать OpenTelemetry как стандарт для инструментирования.

OpenTelemetry Collector: центральная точка

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318
  jaeger:
    protocols:
      grpc:
        endpoint: 0.0.0.0:14250
processors:
  batch:
    timeout: 5s
    send_batch_size: 1024
  tail_sampling:
    decision_wait: 10s
    policies:
      - name: errors-policy
        type: status_code
        status_code: {status_codes: [ERROR]}
      - name: slow-policy
        type: latency
        latency: {threshold_ms: 1000}
      - name: probabilistic
        type: probabilistic
        probabilistic: {sampling_percentage: 10}
exporters:
  otlp/tempo:
    endpoint: http://tempo:4317
    tls:
      insecure: true
service:
  pipelines:
    traces:
      receivers: [otlp, jaeger]
      processors: [batch, tail_sampling]
      exporters: [otlp/tempo]

Деплой Tempo

Развертывание Tempo в Docker Compose
services:
  tempo:
    image: grafana/tempo:2.4.0
    command: ["-config.file=/etc/tempo.yaml"]
    volumes:
      - ./tempo.yaml:/etc/tempo.yaml
      - tempo-data:/tmp/tempo
    ports:
      - "3200:3200"
      - "4317:4317"
server:
  http_listen_port: 3200

distributor:
  receivers:
    otlp:
      protocols:
        grpc:
        http:

storage:
  trace:
    backend: local # для разработки; в production: s3
    local:
      path: /tmp/tempo/blocks

compactor:
  compaction:
    block_retention: 336h

metrics_generator:
  registry:
    external_labels:
      source: tempo
      cluster: docker-compose
  storage:
    path: /tmp/tempo/generator/wal
  remote_write:
    - url: http://prometheus:9090/api/v1/write
      send_exemplars: true

metrics_generator автоматически создаёт Prometheus-метрики из трейсов — service graphs и span metrics. Это избавляет от ручного инструментирования HTTP-запросов.

Интеграция Grafana Tempo с Prometheus и Loki

Настройка datasource в Grafana: укажите тип Tempo, URL http://tempo:3200 и в jsonData включите параметры tracesToLogsV2 (UID datasource Loki) и serviceMap (UID Prometheus). После этого в Explore при клике на метрику появляется кнопка «View related traces», а из трейса — переход в логи.

TraceQL: поиск трейсов по атрибутам

TraceQL — язык запросов для Tempo, аналогичный PromQL. Примеры: { span.http.status_code = 500 && duration > 2s } { resource.service.name = "order-service" && status = error }

{ .user.id = "12345" }

TraceQL закрывает главный недостаток Tempo — теперь можно искать трейсы не только по ID, но и по произвольным атрибутам. Официальная TraceQL содержит полное описание синтаксиса.

Как внедрить распределённый трейсинг с Grafana Tempo?

  1. Аудит инструментирования: проверяем, есть ли OTel SDK, Jaeger, Zipkin. Выбираем стратегию сэмплирования.
  2. Деплой Tempo + Collector: разворачиваем в вашем окружении, настраиваем object storage (S3, GCS).
  3. Настройка Grafana datasource: конфигурируем корреляции с Prometheus и Loki.
  4. Включение metrics_generator: получаем автоматические метрики и service graphs.
  5. Документация и обучение: передаём инструкции по добавлению трейсинга в новые сервисы.

Что входит в работу

  • Развёртывание Tempo и Collector с оптимальной конфигурацией сэмплирования.
  • Интеграция с существующим стеком мониторинга (Prometheus, Loki).
  • Настройка алертов на основе трейсов (например, падение SLO).
  • Документация и практическое обучение команды.
  • Гарантия корректной корреляции метрик, трейсов и логов.

Сроки: от 2 до 5 дней в зависимости от сложности инфраструктуры. Мы — команда с 5+ летним опытом в observability, внедрили distributed tracing на более чем 30 проектах. Оценим ваш проект за один рабочий день. Получите консультацию, чтобы обсудить детали. Свяжитесь с нами, и мы подберём оптимальное решение.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1394
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    815
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139