Files
mdm-ordinis/docs-internal/ops/slo.md
T
Zimin A.N. bcfb07f547 docs: split integrator guide (Diplodoc) vs internal docs + add build-docs CI
Чёткое разделение audiences:
- docs/ — consumer-facing only, Diplodoc-built. Public contract для
  интеграторов (Альтум, BI, third-party).
- docs-internal/ — operator runbooks, status snapshots, legacy tech pages.
  НЕ в Diplodoc build, НЕ публикуются.

Изменения:
- Move docs/{ops,status,tech} → docs-internal/{ops,status,tech}
- docs/toc.yaml: убраны секции Operations, Архитектура (legacy), Status
- docs/index.md: убран tab "оператор / on-call", focus на integrators
- docs/README.md: rewritten — scope только integrator guide, editorial
  guidelines (no leak internal architecture, stable API contract)
- .yfm: убран явный ignore status/* (теперь не нужно — папка переехала)
- docs-internal/README.md: index для внутренней документации с rationale
  разделения

Scrubbing implementation details из Diplodoc страниц:
- events.md: убраны Strimzi/cluster.142 references, OutboxPoller детали,
  internal alert names (OrdinisOutboxLagHigh, OrdinisOutboxDLQNonEmpty),
  metric names (nsi_outbox_*). Заменены на consumer-observable contract.
- webhooks.md: убраны metric names (nsi_webhook_ssrf_rejected_total),
  alert table (OrdinisWebhookHighFailureRate и т.д.). Retry policy
  переписана на user-side perspective.
- errors.md: убран alert name OrdinisReadApiErrorBudgetBurnFast, Tempo
  endpoint URL, internal connection details.
- x-references.md: OrphanReferenceScanner → general "Ordinis периодически
  детектирует". Убраны metric/alert names. Cascade roadmap без link на
  internal design doc.
- auth.md: убран file path ScopeContext.java.
- bundle-cuod.md: убран Maven module path.
- caching.md: cascade design link заменён на text reference.

CI:
- .gitlab-ci.yml: новый job build-docs (stage: build) — Node 20 alpine,
  pnpm install --frozen-lockfile + pnpm build, artifact docs/_dist на
  неделю. Triggers: auto на docs/**, либо manual web. Готов к follow-up
  pages-deploy job когда host решён.
- Новый pattern .docs-changes для rules.

Build verified clean: 13 HTML pages, 6.9M, no broken links/refs.
2026-05-07 23:27:03 +03:00

97 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SLO / SLI — Ordinis НСИ ЦУОД
Документ описывает Service Level Objectives для Ordinis на стадии v1.
Метрики и пороги — стартовая точка, корректируются по реальным данным
после 2-3 месяцев наблюдения.
**Source of truth для алертов:**
`ordinis-infra/charts/ordinis/templates/prometheus-rules.yaml` (отдельный repo).
## 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.
См. `docs/status/2026-05-05-state.md` в repo (status snapshots исключены из Diplodoc build).
## 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