From bcedddef716b96180c34a566f1cc688e2c0bff83 Mon Sep 17 00:00:00 2001 From: "Zimin A.N." Date: Tue, 5 May 2026 20:32:37 +0300 Subject: [PATCH] docs(ops): SLO/SLI definitions + error budget framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 7 SLI с конкретными порогами и justification: - read-api availability (99.5% v1 target) - read-api p99 latency < 500ms target / 1s alert - writer 5xx error rate < 1% - outbox publish lag (≤ 50 normal, alert > 100) - outbox DLQ size = 0 strict - outbox publish error rate ~0 - postgres availability (99.9% v1 target) Error budget framework для 99.5% уровня (~216 мин/мес downtime). Burn rate alerts — TODO. Notification routing — TODO (Slack/Telegram per severity). Что не покрывает v1: Grafana dashboards, distributed tracing, log aggregation, capacity planning. См. observability stack roadmap для v2. --- docs/ops/slo.md | 96 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 docs/ops/slo.md diff --git a/docs/ops/slo.md b/docs/ops/slo.md new file mode 100644 index 0000000..e3fc6cb --- /dev/null +++ b/docs/ops/slo.md @@ -0,0 +1,96 @@ +# SLO / SLI — Ordinis НСИ ЦУОД + +Документ описывает Service Level Objectives для Ordinis на стадии v1. +Метрики и пороги — стартовая точка, корректируются по реальным данным +после 2-3 месяцев наблюдения. + +**Source of truth для алертов:** +[ordinis-infra/charts/ordinis/templates/prometheus-rules.yaml](../../code/ordinis-infra/charts/ordinis/templates/prometheus-rules.yaml). + +## 1. SLI (Service Level Indicators) + +### Read-api availability +- **Метрика:** `up{job="ordinis-read-api"}` +- **Что считаем:** доля времени когда хотя бы один read-api pod отвечает. +- **Цель v1:** 99.5% за месяц (allowance ~3.6 ч downtime). +- **Цель v2:** 99.9% (с HA postgres + 2+ replicas read-api). + +### Read-api latency +- **Метрика:** `histogram_quantile(0.99, http_server_requests_seconds_bucket{job="ordinis-read-api"})` +- **Цель:** p99 < 500ms для GET-запросов. +- **Текущий alert:** p99 > 1s for 10m → warning. +- **Justification:** Альтум-BFF имеет TTL 5 мин, latency на холодном кэше + не должна перекрывать UX (заказ съёмки UI ждёт справочник). + +### Write-api error rate (writer) +- **Метрика:** `5xx_rate / total_rate` over 5m +- **Цель:** < 1% за 30 дней. +- **Alert:** > 5% за 5 мин → warning. +- **Источники 5xx, которые надо исключить:** валидация (это 4xx), exclusion + constraint (409 friendly), IP type cast (баг 2026-05-05, fixed). Если + возрастает — ищем новый bug. + +### Outbox publish lag +- **Метрика:** `ordinis_outbox_pending_events` +- **Цель:** ≤ 50 в normal load, < 10 в average. +- **Alert:** > 100 for 5m → warning. +- **Семантика:** это batch lag между записью изменения в БД и публикацией + в Kafka. Большое значение = consumer'ы видят stale данные. + +### Outbox DLQ +- **Метрика:** `ordinis_outbox_dlq_size` +- **Цель:** = 0 всегда (любая запись в DLQ = bug). +- **Alert:** > 0 for 5m → critical. +- **Действие:** docs/ops/outbox-dlq.md. + +### Outbox publish error rate +- **Метрика:** `rate(ordinis_outbox_publish_errors_total[5m])` +- **Цель:** ~ 0. +- **Alert:** > 0.1/sec for 10m → warning. + +### Postgres availability +- **Метрика:** `cnpg_pg_postmaster_start_time_seconds{cluster="ordinis-postgres"}` +- **Цель:** 99.9% (CNPG single-instance на v1, на v2 — 99.99% с replica). +- **Alert:** absent or 0 for 2m → critical. + +## 2. Notification routing (TODO) + +Сейчас alerts пишутся в Prometheus AlertManager как обычные alerts. +Routing в Slack/Telegram/Email — отдельная задача: + +- [ ] AlertManager config с receiver per severity: + - **critical** → on-call channel (немедленный) + - **warning** → digest channel (раз в час summary) +- [ ] Эскалация: critical → engineer → tech lead через 15 мин если не acked. + +См. v1 closure backlog в [docs/status/2026-05-05-state.md](../status/2026-05-05-state.md). + +## 3. Error budget (v1 target) + +При 99.5% availability за месяц: +- Total минут: 30 * 24 * 60 = 43200 +- Allowed downtime: 0.5% × 43200 = ~216 мин (~3.6 ч) + +**Burn rate alert:** если за последний час потрачено >2% бюджета — +warning. >5% — critical (т.е. совокупно >2.16 ч за час). +Сейчас не настроен — TODO. + +## 4. Что НЕ покрывает v1 + +- Нет dashboards (Grafana). Видим только raw метрики через Prometheus UI. +- Нет distributed tracing (Tempo) на staging. Trace_id есть в логах, но + собрать timeline через сервисы — пока вручную. +- Нет logs aggregation (Loki). Поиск по логам — kubectl logs (привычно + но не масштабируется). +- Нет capacity planning (rate of change для скрытых ресурсов: PVC fill rate, + Kafka log retention). + +Roadmap до v2 — отдельный документ "observability stack". + +## 5. Связанные runbooks + +- [vault-unseal.md](vault-unseal.md) +- [kafka-restart.md](kafka-restart.md) +- [outbox-dlq.md](outbox-dlq.md) +- [db-migrations.md](db-migrations.md) +- [README.md](README.md) — index by symptom