GH GambleHub

Распределенные трассировки

Распределенные трассировки

1) Зачем и что это такое

Распределенная трассировка — это способ связать операции по всему пути запроса: фронт → API-шлюз → микросервисы → БД/кэши → брокеры → джобы/пайплайны.
Результат — трейс (trace) из спанов (span), где каждый спан фиксирует работу компонента с атрибутами, событиями и статусом. Это ускоряет RCA, помогает держать SLO и снижает MTTR.

Ключевые цели:
  • Видимость критического пути и «узких мест».
  • Корреляция симптомов (метрики) с причинами (спаны) и деталями (логи).
  • Аналитика ретраев, очередей, DLQ, фан-аутов, «пилы» латентности.

2) Модель данных трассировки

Trace — граф вызовов с `trace_id`.
Span — операция: `name`, `kind` (SERVER/CLIENT/PRODUCER/CONSUMER/INTERNAL), `start/end`, `status`, `attributes`, `events`, `links[]`.
Attributes — ключ-значение (route, db.system, messaging.system, cloud.region и т. п.).
Events — мгновенные метки внутри спана (например, `retry`, `cache_miss`).
Span Links — связи вне «родитель-ребенок» (батчи, ретраи, fan-in/out).
Resource — метаданные процесса/сервиса (`service.name`, версия, окружение).

3) Контекст и переносимость

3.1 W3C Trace Context

Заголовки:
  • `traceparent`: `version-traceid-spanid-flags` (флаги включают sampling).
  • `tracestate`: вендор-специфичное состояние (по минимуму).
  • Baggage — ключи для бизнес-контекста (ограниченно, без PII/секретов).

3.2 Прокидывание контекста

HTTP: `traceparent`/`tracestate`; gRPC: метаданные; WebSocket: при апгрейде и в сообщениях;

Сообщения: в headers (Kafka/NATS/RabbitMQ) — сохраняем изначальный контекст при PRODUCER и переносим при CONSUMER.
Базы: не «несут» контекст — логируем атрибуты в спан (query, rows, db.system), но не значения.

4) Семплирование: как не разориться

Head sampling (на входе): вероятностное/по правилам (route, tenant, endpoint).
Tail sampling (на коллекторе): сохраняем «интересные» трейсы — ошибки, долгие p95/p99, редкие пути.
Exemplars: метрики гистограммы хранят ссылки на конкретные `trace_id`.
Рекомендация: комбинировать — head 5–20% + tail-правила 100% для 5xx/timeout/p99.

5) Атрибуты и таксономия (минимум обязательного)

Общие:
  • `service.name`, `service.version`, `deployment.environment`, `cloud.region`, `http.route`, `http.method`, `http.status_code`, `db.system`, `db.statement` (укорочено/без данных), `messaging.system`, `messaging.operation`, `peer.service`, `net.peer.name`, `tenant.id`, `request.id`.

Бизнес-лейблы: аккуратно, без PII. Пример: `order.segment`, `plan.tier`.

6) Асинхронные сценарии, очереди и батчи

PRODUCER → CONSUMER: создаем спан PRODUCER с контекстом; в сообщении — headers (traceparent, baggage). CONSUMER стартует SERVER/CONSUMER-спан с link на PRODUCER (если нет строгой иерархии).
Fan-out: один вход — много аутпутов → дочерние спаны или links.
Batch: CONSUMER читает пачку N сообщений → один спан с `events` по каждому messageId или `links` на N отдельных контекстов.
DLQ: отдельный спан `messaging.dlq.publish` с reason и count.
Ретраи: `event: retry` + `retry.count` атрибут; желательно новый CHILD-спан на попытку.

7) Интеграция с логами и метриками

Логи пишем JSON с `trace_id`/`span_id` → из спана кликом уходим в логи.
Метрики RED/USE содержат exemplars → из пиков p99 идем в «плохие» спаны.
Трассы генерируют техсигналы (ошибки зависимостей) и бизнес-сигналы (конверсия) через события.

8) Производительность и стоимость

Семплирование и троттлинг событий.
Сокращение кардинальности атрибутов (никаких `user_id`/`session_id` как label!).
Сжатие/батчирование экспортером; границы таймаутов экспорта.
Хранение: горячие 1–7 дней, дальше — агрегаты/только «проблемные» трейсы.
Категории трат: коллекторы, индексы, хранилище, egress.

9) Безопасность и приватность

In Transit: TLS 1.3/mTLS коллектор↔агенты; At Rest: шифрование, собственные ключи (см. «Шифрование In Transit/At Rest»).
PII и секреты: не пишем в атрибуты/события; токенизация/маскирование на продьюсере.
Многоарендность: `tenant.id` как ресурс-лейбл и изоляция пространств, политики чтения; аудирование доступа к следам (см. «Аудит и неизменяемые журналы»).

10) Схемы внедрения (референс)

10.1 OpenTelemetry SDK (псевдокод)

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

provider = TracerProvider(resource=Resource. create({
"service. name":"checkout","service. version":"1. 12. 0","deployment. environment":"prod"
}))
provider. add_span_processor(BatchSpanProcessor(OTLPSpanExporter(endpoint="otel-collector:4317", insecure=True)))
trace. set_tracer_provider(provider)
tr = trace. get_tracer("checkout")

with tr. start_as_current_span("POST /pay", attributes={
"http. route":"/pay","http. method":"POST","tenant. id":"t-42"
}):
business logic, external API call and pass DB

10.2 OTel Collector — tail sampling (фрагмент)

yaml processors:
tailsampling:
decision_wait: 2s policies:
- type: status_code status_codes: [ERROR]
- type: latency threshold_ms: 900
- type: probabilistic sampling_percentage: 10 exporters:
otlphttp: { endpoint: http://trace-backend:4318 }
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch, tailsampling]
exporters: [otlphttp]

10.3 Kafka — перенос контекста (концепция)

PRODUCER: добавляем headers `traceparent`, `baggage`.
CONSUMER: если сообщение инициирует новый поток — новый SERVER/CONSUMER-спан c link на контекст из headers.

11) Data/ETL и ML

Для батч-пайплайнов: спан на батч/partition с `dataset.urn`, `run.id`, `rows.in/out`, `freshness.lag`.
Для ML: спаны тренировки/инференса, версия модели, latency, feature store.
Связка с Lineage: `run.id` и `dataset.urn` позволяют от трейса перейти к графу происхождения данных.

12) SLO платформы трассировок

Доступность ingestion: ≥ 99.9%

Задержка до индексации: ≤ 60 с p95

Покрытие head-sample: ≥ 5–10% ключевых маршрутов

100% сохранения трейсов со статусом ERROR и с latency > порога по каталогу «критичных путей»

Алерты платформы: рост дропов, таймауты экспорта, лаг индексатора, перегрев кардинальности.

13) Тестирование и верификация

Контракт трассировки в CI: наличие спанов на ключевых эндпоинтах, обязательные атрибуты, корректный `traceparent` пролетает через шлюз/прокси.
Synthetic/rum-пробы: собирают трейсы с внешней стороны.
Chaos/инциденты: отключение зависимостей, проверка, что tail-семплер «подбирает» ошибки.
Smoke в проде: после релиза — «есть ли спаны» и exemplar → трейс.

14) Чек-листы

Перед продом

  • Везде прокинут W3C Trace Context; для сообщений — headers.
  • Базовое head-семплирование включено; tail-правила для 5xx/p99 настроены.
  • Обязательные атрибуты: route, method, status, service.version, tenant.id.
  • Логи JSON с `trace_id`/`span_id`, метрики с exemplars.
  • Санитайзеры PII; шифрование в пути/на покое; политики доступа.
  • Дашборды: «критический путь», «ошибки зависимостей», «ретраи/таймауты».

Эксплуатация

  • Ежемесячный обзор кардинальности атрибутов; квоты.
  • Тюнинг tail-семплинга по SLO (меньше шума, все «горячее» — в выборке).
  • Учебные RCA с переходом метрика → exemplar → трейс → логи.
  • Проверка покрытий для очередей, DLQ, ETL-джобов.

15) Runbook’и

RCA: рост p99 на /pay

1. Открыть RED-дашборд; из бина p99 перейти по exemplar в трейс.
2. Найти «узкий» CLIENT-спан (например, `gateway.call`), проверить `retry.count`, таймауты.
3. Сравнить версии сервиса/зависимости, регион/зону.
4. Включить деградацию (кэширующий ответ/лимит RPS), уведомить владельцев зависимости.
5. После фикса — RCA и тикеты на оптимизацию.

DLQ всплеск

1. Фильтр трасс по `messaging.dlq.publish`.
2. Проверить причины (events), коррелировать с релизом.
3. Запустить reprocess, временно увеличить таймаут у CONSUMER, уведомить владельцев downstream.

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

Нет прокидки контекста через шлюзы/брокеры. Решение: middleware/интерсепторы, единые библиотеки.
Все трейсы 100%. Дорого и бессмысленно — используйте tail-семплинг.
Логи без `trace_id`. Теряется корреляция → MTTR ↑.
PII в атрибутах. Маскируйте/токенизируйте; храните только технический контекст.
«Немые» фоновые джобы. Добавьте спаны на батч/partition и `run.id`.
Разнобой именования. Введите словарь имен спанов и ключей атрибутов.

17) FAQ

В: Head или tail семплинг лучше?
О: Комбинация. Head дает базовый слой, tail гарантирует сохранение аномалий/ошибок.

В: Как трассировать через Kafka без жесткой иерархии?
О: Используйте span links между PRODUCER и CONSUMER; контекст — в headers.

В: Что делать с чувствительными SQL?
О: `db.statement` укороченный/нормализованный (без значений), либо `db.operation` + размеры/время.

В: Как связать с бизнес-метриками?
О: Добавляйте атрибуты домена без PII (plan/segment), используйте события «бизнес-этапов» внутри спана и переходите из конверсионных метрик по exemplar.

Связанные материалы:
  • «Наблюдаемость: логи, метрики, трассировки»
  • «Аудит и неизменяемые журналы»
  • «Шифрование In Transit / At Rest»
  • «Происхождение данных (Lineage)»
  • «Privacy by Design (GDPR)»
  • «Менеджмент секретов»
Contact

Свяжитесь с нами

Обращайтесь по любым вопросам или за поддержкой.Мы всегда готовы помочь!

Начать интеграцию

Email — обязателен. Telegram или WhatsApp — по желанию.

Ваше имя необязательно
Email необязательно
Тема необязательно
Сообщение необязательно
Telegram необязательно
@
Если укажете Telegram — мы ответим и там, в дополнение к Email.
WhatsApp необязательно
Формат: +код страны и номер (например, +380XXXXXXXXX).

Нажимая кнопку, вы соглашаетесь на обработку данных.