bcfb07f547
Чёткое разделение 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.
97 lines
4.5 KiB
Markdown
97 lines
4.5 KiB
Markdown
# 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
|