Rollout distributed tracing
OpenTelemetry instrumentation, head vs tail sampling, что обязательно span'ить, как читать traces и не убить latency.
Действуй как Distributed Systems Engineer. Спроектируй rollout distributed tracing на {{services_count}} сервисов. Текущее состояние: {{current_tracing}}.
Что сделать
-
Стандарт: OpenTelemetry (OTel). Не вендорский SDK. OTel = lingua franca tracing, переключение бэкенда (Jaeger → Tempo → Datadog → Honeycomb) без переписывания инструментации.
- OTel SDK + OTel Collector (агент / sidecar / DaemonSet). Сервис отдаёт OTLP в Collector, Collector экспортирует туда, куда нужно.
- Auto-instrumentation для популярных libs (HTTP, gRPC, SQL, Redis, Kafka) — лови ~80% spans бесплатно.
- Manual instrumentation для бизнес-операций (
process_order,compute_recommendation) — без них trace не отражает доменную логику.
-
Sampling: head vs tail. Без сэмплинга tracing 1:1 = огромная стоимость + latency overhead. С сэмплингом — ловишь только то, что важно.
- Head-based sampling: решение в начале trace (по request_id), все spans в trace либо собираются, либо нет. Дёшево, predictable. Минус: можно потерять редкий, но важный slow request.
- Tail-based sampling: Collector копит N секунд spans в памяти, потом решает (slow → keep, error → keep, иначе drop 99%). Лучше signal, дороже compute, требует Collector с памятью под буфер.
- Гибрид: 1% head sampling baseline (для baseline metrics) + 100% tail-keep для (error || latency > p99 || feature_flag=verbose).
- Не сэмплируй один сервис из цепочки — получишь broken trace. Sampling решение распространяется через trace context (W3C traceparent).
-
Что обязательно span'ить. Принцип: каждая boundary = span. Внутри сервиса — span на «значимую» операцию.
- Network boundaries: входящий HTTP/gRPC, исходящий HTTP/gRPC, queue send/receive, DB query, cache get/set. Auto-instrumentation покрывает.
- Process boundaries: subprocess, async job dispatch / handle. Manual instrumentation + context propagation через очередь (trace_id в message headers).
- Доменные операции:
charge_card,apply_discount,render_pdf. Manual span с атрибутами (order.amount,discount.code). - Атрибуты на span: semantic conventions OTel (
http.method,db.statement,messaging.system). Не делай свои названия — ломает интеграции. - Без PII в атрибутах (email, токены). Redaction в Collector processor.
-
Как читать traces для диагностики. Trace без навыка чтения = просто красивая waterfall.
- Flame graph view: где длинный span? Critical path запроса.
- Service map: какие сервисы в trace, какие dependencies, error rate на ребро.
- Span attributes:
db.statement,http.status_code— фильтрация и группировка. - Pattern matching: «slow checkout = всегда span X > 500ms» → root cause в X.
- Trace + logs correlation: trace_id в каждом логе → from trace jump to logs by trace_id, не grep.
- Anomaly detection: диффинг между «нормальный» trace и «slow» trace — что добавилось / удлинилось.
-
Latency overhead — как не убить prod. Tracing не бесплатен.
- Budget: instrumentation overhead < 1% latency p95. Замерь до/после на canary.
- Async export: Collector batches и шлёт в background, не блокирует request.
BatchSpanProcessor, неSimpleSpanProcessor. - Span attributes count: ≤ 20 атрибутов на span. Иначе serialization overhead + drop в Collector.
- Cardinality: не клади high-cardinality (user_id) в attributes, которые потом группируются — взрывает backend index.
- Off-CPU работа: Collector в sidecar / DaemonSet, не in-process, чтобы не делить CPU с app.
- Network back-pressure: Collector с persistent queue (file-based) на случай, если backend timeout'ит.
Anti-patterns
- ❌ Custom format вместо OTel — каждые 2 года переписывать всё.
- ❌ 100% sampling «потому что нам нужны все traces» — миллион $/мес на storage, никто не читает 99% trace'ов.
- ❌ Один сервис без context propagation — все downstream trace'ы broken («missing parent span»).
- ❌
SimpleSpanProcessorв проде — sync export на критическом пути, +50ms latency. - ❌ Tracing без correlation с логами и метриками — три параллельные системы, switch cost при инциденте.
- ❌ Rollout «все сервисы сразу» — нет baseline, не понять, где регрессия.
Формат вывода
## Architecture
`App → OTel SDK → OTel Collector (sidecar/DaemonSet) → Backend`
(mermaid diagram)
## Sampling strategy
| Layer | Policy | Sample rate | Rationale |
| Head (SDK) | always-on | 100% (context only) | propagate context |
| Tail (Collector) | error || slow || baseline 1% | ... |
## Mandatory spans (per service)
| Span | Type | Attributes (semconv) | Notes |
## Instrumentation rollout plan
| Phase | Services | Type (auto/manual) | Owner | Done by |
| 1 (canary) | 1 service | auto + manual | ... | week 1 |
| 2 | top-5 by traffic | auto | ... | week 3 |
## Backend choice
| Tool | Pros | Cons | Cost estimate |
## Latency budget
| Phase | p95 before | p95 after | Δ |
## Trace-log-metric correlation
- trace_id в логах: ✓ / ✗
- exemplars в metrics: ✓ / ✗
Принцип: tracing — это «как связаны куски системы». Без него distributed system = чёрный ящик. Но плохо настроенный tracing = чёрный ящик + большой счёт.
Аудит производительности (Core Web Vitals)
Глубокая проверка LCP, INP, CLS с привязкой к коду и приоритизированным планом исправлений.
Мониторинг и алёрты
Что мерить, какие алёрты ставить, как не превратить on-call в ад.
Мастер-аудит сайта: 6 измерений за один проход
Orchestrator-аудит по 6 направлениям: UX, accessibility, performance, SEO, brand consistency, security. Quick scan + deep dive + приоритизированный план + композитная оценка + roadmap.