Стек наблюдаемости
1) Зачем нужен стек наблюдаемости
Быстрые RCA и снижение MTTR: от симптома к причине за минуты.
SLO-управление: измерение ошибок/латентности, алертинг по ошибочному бюджету.
Контроль релизов: канареечные выкладки, авто-rollback по метрикам.
Безопасность и аудит: трассы доступа, аномалии, Legal Hold.
ФинОпс-прозрачность: стоимость хранения/запросов, cost-per-SLO.
Методологии: Golden Signals (latency/traffic/errors/saturation), RED, USE.
2) Базовая архитектура стека
Компоненты по слоям
Сбор/агенты: Exporters, Promtail/Fluent Bit, OTel SDK/Auto-Instr, Blackbox-probes.
Шина/ingest: Prometheus remote_write → Mimir/Thanos, Loki distributors/ingesters, Tempo/Jaeger ingesters.
Хранилища: объектное S3/GCS/MinIO (длительный холод), SSD (горячие ряды).
Запросы/визуализация: Grafana (панели, SLO-виджеты), Kibana (если ELK).
Управление: Alertmanager/Графана-алерты, сервис-каталог, RBAC, секрет-менеджер.
Паттерны развертывания
Managed (Grafana Cloud/облачные сервисы) — быстро и дороже на объемах.
Self-hosted в K8s — полный контроль, нуждается в эксплуатации и FinOps.
3) Стандарты данных: единая «схема наблюдаемости»
3.1 Метрики (Prometheus/OpenMetrics)
Обязательные лейблы: `env`, `region`, `cluster`, `namespace`, `service`, `version`, `tenant` (если мульти-тенант), `endpoint`.
Именование: `snake_case`, суффиксы `_total`, `_seconds`, `_bytes`.
Гистограммы: фиксированные `buckets` (SLO-ориентированные).
Кардинальность: не включать `user_id`, `request_id` в лейблы.
3.2 Логи
Формат: JSON; обязательные поля `ts`, `level`, `service`, `env`, `trace_id`, `span_id`, `msg`.
PII: маскирование на агенте (PAN, токены, e-mail и т. п.).
Loki-лейблы: только низкая кардинальность (`app`, `namespace`, `level`, `tenant`).
3.3 Трассы
OTel семантика: `service.name`, `deployment.environment`, `db.system`, `http.`.
Сэмплинг: целевые пути p99 — `always_on`/tail-sampling, остальное — `parent/ratio`.
Встраивание ID: прокидывайте `trace_id/span_id` в логи и метрики (labels/fields).
4) Корреляция M-L-T (Metrics/Logs/Traces)
Из графика алерта (метрика) → фильтрованные логи по `trace_id` → конкретная трасса.
Из трассы (медленный спан) → запрос метрик конкретного бэкенда на интервале спана.
Кнопки Drilldown в панелях: «к логам» и «к трассам» с подстановкой переменных (`$env`, `$service`, `$trace_id`).
5) OpenTelemetry Collector: эталонный пайплайн
yaml receivers:
otlp:
protocols: { http: {}, grpc: {} }
prometheus:
config:
scrape_configs:
- job_name: kube-nodes static_configs: [{ targets: ['kubelet:9100'] }]
processors:
batch: {}
memory_limiter: { check_interval: 1s, limit_mib: 512 }
attributes:
actions:
- key: deployment. environment value: ${ENV}
action: insert tail_sampling:
decision_wait: 5s policies:
- name: errors type: status_code status_code: { status_codes: [ERROR] }
- name: important-routes type: string_attribute string_attribute: { key: http. target, values: ["/payments","/login"] }
- name: probabilistic type: probabilistic probabilistic: { sampling_percentage: 10 }
exporters:
otlphttp/mimir: { endpoint: "https://mimir/api/v1/push" }
otlphttp/tempo: { endpoint: "https://tempo/api/traces" }
loki:
endpoint: https://loki/loki/api/v1/push labels:
attributes:
env: "deployment. environment"
service: "service. name"
service:
pipelines:
metrics: { receivers: [prometheus, otlp], processors: [memory_limiter, batch], exporters: [otlphttp/mimir] }
logs: { receivers: [otlp], processors: [batch], exporters: [loki] }
traces: { receivers: [otlp], processors: [memory_limiter, attributes, tail_sampling, batch], exporters: [otlphttp/tempo] }
6) Алертинг: SLO и multi-burn
Идея: алертим не на уровне «CPU>80%», а на потреблении Error Budget.
PromQL-шаблоны:promql
5-minute error rate err_ratio_5m =
sum(rate(http_requests_total{status=~"5.."}[5m])) /
sum(rate(http_requests_total[5m]))
Quick burn (1m window)
(err_ratio_1m / (1 - SLO)) > 14. 4
Slow burn (30m)
(err_ratio_30m / (1 - SLO)) > 2
Латентность (гистограммы):
promql latency_p95 =
histogram_quantile(0. 95, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))
7) Дашборды: структура папок
00_Overview — платформа: SLO, p95, 5xx%, capacity, активные инциденты.
10_Services — по сервисам: RPS, p95/p99, ошибки, релизы (аннотации).
20_Infra — K8s/ноды/сторидж/сеть, etcd, контроллеры.
30_DB/Queues — PostgreSQL/Redis/Kafka/RabbitMQ.
40_Edge/DNS/CDN/WAF — ingress, LB, правила WAF.
50_Synthetic — аптайм и headless-сценарии.
60_Cost/FinOps — хранение, запросы, горячее/холодное, прогноз.
Каждая панель: описание, единицы, владелец, runbook-ссылка, drilldown.
8) Логи: LogQL практикум
logql
API errors
{app="api", level="error"} = "Exception"
Nginx 5xx in 5 minutes
{app="nginx"} json status=~"5.." count_over_time([5m])
Extract Fields
{app="payments"} json code!="" unwrap duration avg()
9) Трассы: TraceQL и фокусы
Найти самые медленные спаны:
{ service. name = "api" } duration > 500ms
Сэндвич «медленный SQL в медленном запросе»:
{ name = "HTTP GET /order" } child. span. name = "SELECT" & child. duration > 50ms
10) Синтетика и аптайм
Blackbox-exporter: HTTP/TCP/TLS/DNS-пробы из ≥3 регионов/ASN.
Headless: login/deposit сценарии по расписанию.
Quorum-алерты: срабатывание, если ≥2 регионов видят отказ.
Статус-страница: автоматические апдейты + ручные комментарии.
11) Хранение и ретеншн
Метрики: горячее 7–30 дней (быстрые ряды), downsampling/recording rules, холодное — объектное хранилище (месяцы).
Логи: горячее 3–7 дней, затем — S3/GCS с индексом (Loki chunk store/ELK ILM).
Трассы: 3–7 дней `always_on` + длительное хранение для выборок (tail-sampled/отбраковка).
- Ролловер по размеру и времени; бюджет на запросы (квоты/лимиты).
- Отдельные политики для prod/stage и данных безопасности.
12) Мульти-тенантность и доступы
Разделяйте по `tenant`/`namespace`/Spaces, индекс-паттерны и разрешения.
Тэгируйте ресурсы для биллинга: `tenant`, `service`, `team`.
Импортные дашборды/алерты — в пространствах конкретных команд.
13) Безопасность и комплаенс
TLS/mTLS от агентов до бекендов, HMAC для приватных health.
RBAC на чтение/запись, аудит всех запросов и алертов.
PII-редакция на краю; запрет секретов в логах; DSAR/Legal Hold.
Изоляция: отдельные кластера/неймспейсы для чувствительных доменов.
14) ФинОпс: стоимость наблюдаемости
Снижаем кардинальность лейблов и логику в ingest (а не в запросах).
Сэмплинг трасс + целевое always-on для критичных путей.
Downsampling/recording rules для тяжелых агрегаций.
Архивация редкого доступа в холодное объектное.
Метрики: `storage_cost_gb_day`, `query_cost_hour`, `cost_per_rps`, `cost_per_9`.
15) CI/CD и тесты наблюдаемости
Линтинг метрик/логов в CI: запрет «взрыва» кардинальности, проверка гистограмм/единиц.
Contract-тесты наблюдаемости: обязательные метрики/поля логов, `trace_id` в middleware.
Canary: аннотации релизов на графах, SLO-авто-rollback.
16) Примеры: быстрые запросы
Топ-эндпоинты по ошибкам:promql topk(10, sum by (route) (rate(http_requests_total{status=~"5.."}[5m])))
CPU throttling:
promql sum by (namespace, pod) (rate(container_cpu_cfs_throttled_seconds_total[5m])) > 0
Kafka lag:
promql max by (topic, group) (kafka_consumergroup_lag)
От логов к трассам (Loki → Tempo): передавайте `trace_id` как линку на Tempo UI/дэшборд.
17) Качество стека: чек-лист
- Согласованные схемы метрик/логов/трасс и единицы измерения.
- `trace_id` в логах и метриках, drilldown из панелей.
- Multi-burn SLO-алерты без флаппинга (quorum/multi-window).
- Downsampling, квоты запросов, лимиты на шаг/диапазон.
- Ретеншн и классы хранения задокументированы и применяются.
- RBAC/аудит/PII-редакция включены.
- Дашборды: владелец, runbooks, ≤2–3 экрана, быстрый ответ.
- ФинОпс-дашборд (объемы, стоимость, топ-говоруны).
18) План внедрения (3 итерации)
1. MVP (2 недели): Prometheus→Mimir, Loki, Tempo; OTel Collector; базовые дашборды и SLO-алерты; blackbox-пробы.
2. Scale (3–4 недели): tail-sampling, downsampling, мульти-регион ingest, RBAC/Spaces, FinOps-дашборды.
3. Pro (4+ недели): auto-rollback по SLO, headless-синтетика ключевых путей, Legal Hold, портфель SLO и отчетность.
19) Анти-паттерны
«Красивые графики без SLO» — нет действия → нет пользы.
Лейблы с высокой кардинальностью (`user_id`, `request_id`) — взрыв памяти и стоимости.
Логи без JSON и без `trace_id` — нет корреляции.
Алерты по ресурсам вместо симптомов — шум и выгорание on-call.
Отсутствие ретеншн-политик — бесконтрольный рост затрат.
20) Мини-FAQ
Что выбрать: Loki или ELK?
ELK для сложного поиска/фасетов; Loki — дешевле и быстрее для grep-подобных сценариев. Часто используют гибрид.
Нужны ли трассы всем?
Да, хотя бы на ключевых путях (login, checkout, payments) с tail-sampling — это резко ускоряет RCA.
Как начать с нуля?
OTel Collector → Mimir/Loki/Tempo → базовые SLO и blackbox-пробы → затем дашборды и burn-алерты.
Итог
Стек наблюдаемости — это не набор разрозненных инструментов, а согласованная система: единые стандарты данных → корреляция M-L-T → SLO-алертинг и синтетика → безопасность и FinOps. Зафиксируйте схемы, дисциплину лейблов и ретеншн, подключите OTel, добавьте drilldown и auto-rollback — и вы получите управляемую надежность с понятной стоимостью.