diff --git a/README.md b/README.md index 0f288cf..fd67f7c 100644 --- a/README.md +++ b/README.md @@ -273,7 +273,8 @@ Формат health-эндпоинтов gnexus ещё не договорён — панель работает по прогрессивному минимуму: 2xx = ok; тело-JSON со строкой `status` учитывается (ok-набор → ok, degraded-набор → деградация, всё прочее → вниз); не-2xx/таймаут -= вниз. Полный контракт и рекомендации для сервисов: `docs/health-endpoint-spec.md`. += вниз. Полный контракт и рекомендации для сервисов — конвенция экосистемы в +handbook: [10-platform/health.md](https://git.gnexus.space/root/gnexus-handbook/raw/master/10-platform/health.md). ## Язык интерфейса diff --git a/docs/health-endpoint-spec.md b/docs/health-endpoint-spec.md index 12ad672..52f8c43 100644 --- a/docs/health-endpoint-spec.md +++ b/docs/health-endpoint-spec.md @@ -1,113 +1,6 @@ # Спека: health-эндпоинт gnexus-сервисов -Контракт, по которому hard-panel (и любой другой монитор gnexus) опрашивает -`/health` сервисов и интерпретирует отклик. Эндпоинты уже есть у всех сервисов, -но формата нет — эта спека фиксирует **минимальный** контракт, работающий «из -коробки» для любого уже существующего эндпоинта, и **рекомендуемое расширение**, -к которому можно двигаться постепенно. +→ Перенесена в handbook: **[10-platform/health.md](https://git.gnexus.space/root/gnexus-handbook/raw/master/10-platform/health.md)** (правила экосистемы живут в gnexus-handbook, сервисы ссылаются на него). -## 1. Минимальный контракт - -Монитор опрашивает эндпоинт методом **GET**. Достаточно: - -| Отклик | Интерпретация монитором | -|---|---| -| HTTP 2xx | сервис **в порядке (up)** | -| HTTP 2xx с телом-JSON, где `status` — из набора ok (см. §2) | **в порядке (up)** | -| HTTP 2xx с телом-JSON, где `status` — из набора degraded (см. §2) | **деградация (degraded)** | -| HTTP 2xx с телом-JSON, где `status` — любая другая строка | **вниз (down)** | -| HTTP 3xx–5xx | **вниз (down)** | -| таймаут, DNS, отказ соединения | **вниз (down)**, причина — текст ошибки | - -Тело **может вообще отсутствовать или быть любым** (текст, HTML, JSON без -поля `status`) — чистый 2xx в порядке. Монитор никогда не угадывает глубже: -неизвестный формат не превращается во «вниз» (кроме незнакомой строки `status`, -см. §2 — раз сервис явно ответил статусом, монитору его не угадать). - -## 2. Поле `status` - -Если тело — JSON-объект со строковым полем `status`, монитор опирается на него. -Значение сравнивается без учёта регистра. - -| Значение `status` | Монитор показывает | -|---|---| -| `ok`, `healthy`, `pass`, `passing`, `up` | в порядке | -| `degraded`, `warn`, `warning`, `partial`, `busy` | деградация | -| `down`, `error`, `fail`, `critical`, незнакомая строка | вниз | - -Незнакомая строка трактуется консервативно (**вниз**): сервис взялся ответить -статусом — монитор не может считать его здоровым. Если нужно только «в порядке / -не в порядке», используйте просто `ok`; остальное оставьте по минимуму. - -## 3. Рекомендуемое расширение - -То, к чему стоит прийти gnexus-сервисам со временем — одинаковая, машина-читаемая -детализация: - -```json -{ - "status": "ok", - "service": "gnexus-creds", - "version": "1.4.2", - "checks": { - "db": { "status": "ok", "ms": 3 }, - "redis": { "status": "degraded", "detail": "replica lag 15s" } - }, - "timestamp": "2026-10-04T12:00:00Z" -} -``` - -- `status` — агрегат по всем подчинённым: **худший** из `checks.*.status` - (порядок тяжести: down > degraded > ok → down). -- `checks.{name}.status` — те же значения, что в §2 (`ok`/`degraded`/`down`). -- `checks.{name}.ms` — необязательная длительность подчинённой проверки, ms. -- `checks.{name}.detail` — необязательная причина degraded/down (одной строкой). -- `service`, `version`, `timestamp` — необязательные, для журналов и - самодиагностики. - -Мониторы, написанные по §1–2, продолжают работать с таким телом без изменений: -агрегатный `status` уже говорит всё. - -## 4. Требования к эндпоинту - -- **Без авторизации.** `/health` не раскрывает данные; auth на нём превращает - мониторинг в «всегда вниз». -- **Дёшево.** Монитор опрашивается каждые ~30 с постоянно. Никаких тяжёлых - запросов на пинг: проверяйте только доступность (ping БД — `SELECT 1`, - не миграции). Кэшируйте результат, если проверка дороже ~100 ms, максимум - на 10 с. -- **Быстро.** Отвечайте за **< 500 ms**; таймаут монитора — 5 s. -- **Идемпотентно, без побочных эффектов.** Никаких счётчиков метрик, писем, - записей в БД. -- **Не логируйте каждый пинг.** Сотни записей в минуту — шум, заслоняющий - настоящие ошибки. -- **Ставить в /health или /healthz — на выбор сервиса**; монитор берёт - полный URL из настроек, редиректы следуются. - -## 5. Примеры - -```bash -# минимум — текстовый 200 -$ curl -i http://gnexus-creds.local/health -HTTP/1.1 200 OK -OK - -# со статусом деградации (монитор покажет «деградация», HTTP 200) -$ curl -i http://gnexus-auth.local/health -HTTP/1.1 200 OK -{"status": "degraded"} - -# рекомендуемое расширение -$ curl http://gnsynapse.local/health -{"status": "ok", "service": "gnsynapse", "version": "0.8.0", - "checks": {"db": {"status": "ok", "ms": 2}, "queue": {"status": "ok", "ms": 1}}} -``` - -Смена ответа монитору — не breaking change: добавление полей в тело безопасно, -монитор игнорирует неизвестное; удаление `status` (возвращаясь к минимуму) -— тоже. - -## Changelog - -- 2026-10-04 — первая версия: минимум (2xx + строка `status`), рекомендуемое - расширение `checks`, требования к эндпоинту. \ No newline at end of file +По этому контракту работает health-чекер hard-panel (референс-реализация: +`panel/backend/app/services_probe.py`, раздел «Сервисы»). \ No newline at end of file