Контракт, по которому любые мониторы экосистемы (hard-panel, скрипты агентов) опрашивают /health сервисов и интерпретируют отклик. Эндпоинты уже есть у всех сервисов, формата нет — фиксируется минимальный контракт, работающий «из коробки» с любым уже существующим эндпоинтом, и рекомендуемое расширение, к которому сервисы приходят постепенно.
Референсная реализация интерпретации: hard-panel (panel/backend/app/services_probe.py).
Монитор опрашивает эндпоинт методом 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 (если сервис взялся ответить статусом, монитору его не угадать).
statusЕсли тело — JSON-объект со строковым полем status, монитор опирается на него. Сравнение без учёта регистра.
Значение status |
Монитор показывает |
|---|---|
ok, healthy, pass, passing, up |
в порядке |
degraded, warn, warning, partial, busy |
деградация |
down, error, fail, critical, незнакомая строка |
вниз |
Незнакомая строка — консервативно вниз: сервис ответил статусом, монитор не имеет права считать его здоровым. Если нужна только дихотомия «в порядке / не в порядке» — просто возвращайте ok.
Одинаковая, машину-читаемая детализация — к ней gnexus-сервисы приходят со временем:
{
"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).checks.{name}.status — те же значения, что в §2.checks.{name}.ms — необязательная длительность подчинённой проверки, ms.checks.{name}.detail — необязательная причина degraded/down, одной строкой.service, version, timestamp — необязательные, для журналов.Мониторы, написанные по §1–2, работают с таким телом без изменений. Полный набор слоёв самосвидетельства — §5.
/health не раскрывает данных; auth превращает мониторинг в «всегда вниз».SELECT 1, не миграции); дороже ~100 ms — кэшируйте максимум на 10 с./health или /healthz, на выбор сервиса; монитор берёт полный URL из настроек.Ответ health может нести не только лайвность, но и самосвидетельство — необязательные слои информации о себе. Всё ниже необязательно; монитор по минимуму (§1–2) обязан незнакомые поля игнорировать, сервис с богатым телом ничего не ломает.
Identity — кто я. service (самоназвание), version, build (git sha), environment (production/…), uptime (секунды) или since (ISO — момент старта). Монитор сверяет service с настройкой (защита от перепутанного URL), показывает версию и аптайм в карточке; сброс uptime между опросами — сигнал «сервис перезапустился».
Mode — сознательные состояния. "mode": "maintenance" | "readonly" | "draining" — сервис жив, это делается намеренно (миграция, бэкап). Монитор показывает нейтральный бейдж «обслуживание»: не degraded и не падение доступности.
Gauges — рабочие показатели. "gauges": {"queue_depth": 42, "db_pool_in_use": 7, "cache_hit_ratio": 0.87} — числа без интерпретаций. Пороги и суждения остаются монитору: "cpu": 62 — хорошо, "cpu_warn": true — плохо. Очереди, пулы, кэш, счётчики — всё, что сервис считает полезным для стороннего взгляда.