Главная/Документация/Мониторинг
Контракт мониторинга
Мониторинг ставит ваше расширение под постоянное наблюдение: живой светофор на карточке в списке, базовый таб monitoring в Detail и отдельное Telegram статус-сообщение с edge-алертами. Он состоит из двух независимо включаемых компонентов: push-heartbeat (агент на стенде вашего сервиса репортит с заявленной периодичностью; молчание – само по себе сигнал) и uptime-пингов (панель сама проверяет доступность ваших публичных URL).
1. Как это работает (два компонента, один светофор)
- Push-heartbeat: cron-скрипт на вашем хосте (например,
адаптированный
monitor.sh) POST-ит панели отчёт метрик v2 с заявленным интервалом. Каждый отчёт обязан нести зарезервированный итогoverall. Пропуски отчётов эскалируют светофор (dead-man's switch): умер хост, сеть или cron – видно именно потому, что вызовы прекратились. - Uptime-пинги: панель сама периодически дергает публичные URL, которые вы настроили (site, api, docs), и проверяет только доступность, никогда не содержимое. Агент не нужен, достаточно URL.
Расширение «стоит на мониторинге», когда мониторинг включён и настроен хотя бы один компонент. Иначе на карточке – нейтральная серая точка.
1b. Heartbeats и пул слотов
Мониторинг живёт на уровне расширения как два независимых плоских списка, делящих
один пул слотов: heartbeats (push-продюсеры, ранее «стенды») и
uptime-пинги (pull-проверки). У расширения может быть несколько
heartbeat'ов – например, главный хост и платный воркер. Каждый heartbeat шлёт отчёты
под своим токеном и сам объявляет презентацию (табы, секции, строки
Telegram) через свой label. Uptime-пинги – отдельный плоский список на
уровне расширения, не вложенный ни в какой heartbeat. Панель мержит всё в один
агрегатный светофор (worst-of), один Detail и одно сводное Telegram-сообщение.
Heartbeats и пинги делят единый на расширение пул слотов (slots):
один heartbeat = один слот, один активный пинг = один слот, сумма ≤ тарифного
max_slots (Trial 3 · Studio 10 · Fleet 25). Превышение пула →
409 slot_limit; после даунгрейда излишек приостанавливается (сначала
пинги, heartbeats – в последнюю очередь). В ответе есть slots_used и
max_slots для отображения бюджета в UI.
2. Светофор
Агрегат: worst-of по всем включённым heartbeat-компонентам и всем
активным пингам, где severity упорядочены как ok < warn < crit.
Компонент heartbeat'а – max(reported, watchdog): reported
– severity метрики overall из последнего принятого отчёта;
watchdog – floor по свежести, считается по часам приёма панели
(clock skew агента не вредит).
| Состояние | Цвет | Когда |
|---|---|---|
off | ⚪ серый | Мониторинг не включён или не настроен ни один компонент. |
paused | ⚪ серый | Включён, но заморожен (тариф-гейт или ручная пауза). Отчёты продолжают сохраняться. |
green | 🟢 | Все компоненты ok. |
yellow | 🟡 | Худший компонент warn. |
red | 🔴 | Худший компонент crit. |
Severity каноничны: ok | warn | crit.
Дружелюбные алиасы нормализуются на приёме: warning становится
warn; error и critical становятся crit.
3. Watchdog (пропуски heartbeat)
Ожидаемый интервал отчётов (от 60s до 24h) вы заявляете при включении
heartbeat. Дальше watchdog floor-ит светофор по свежести, с допуском
grace = max(60s, 25% интервала) на джиттер cron и сети:
| Возраст последнего принятого отчёта | Floor watchdog |
|---|---|
| до interval + grace | ok (green) |
| пропущен 1 отчёт (до 2 × interval + grace) | warn (yellow) |
| пропущено 2 и более отчётов | crit (red) |
Отвергнутый отчёт (401 / 422 / 429) не обновляет watchdog, поэтому сломавшийся агент честно эскалирует; причина последнего отказа видна в настройках мониторинга. Восстановление мгновенно: первый же принятый отчёт немедленно пересчитывает светофор.
4. Uptime-пинги
Пинг – именованная проверка доступности одного публичного https-URL. Панель делает GET с таймаутом 10s, следует максимум за 5 редиректами, не читает тело сверх минимума и считает успехом финальный статус класса 2xx (204 и 206 тоже засчитываются). Финальный 3xx (цикл или лимит редиректов), 4xx, 5xx, таймаут или DNS/TLS/сетевая ошибка – провал. Провалившаяся проверка подтверждается одним повтором через ~15s, прежде чем засчитается: это гасит единичные сетевые блипы.
| Подтверждённых провалов подряд | Светофор пинга |
|---|---|
| 0 | ok |
| 1 | warn |
| 2 и более | crit |
Результаты пингов появляются first-party метриками ping:<name>
в секции pings (Uptime) базового таба
monitoring и в зарезервированной Telegram-строке
pings: 🟢 api 210ms · 🟢 site 90ms · 🔴 docs (timeout).
Число пингов на расширение и минимальный интервал зависят от тарифа:
| Тариф | Uptime-пингов на расширение | Min интервал пинга |
|---|---|---|
| Trial | 3 | 5 мин |
| Indie | 3 | 5 мин |
| Studio | 10 | 1 мин |
| Fleet | 25 | 1 мин |
Мониторинг целиком доступен только на Trial/Paid; минимальный интервал heartbeat – 60s на всех тарифах.
5. Как поставить расширение на мониторинг
В Settings расширения, блок мониторинга:
- Включите мониторинг (тарифы Trial/Paid).
- Heartbeat: включите и заявите интервал отчётов; панель выдаст bearer токен мониторинга, он показывается ровно один раз (ротация доступна в любой момент; старый токен сразу получает 401). Положите токен и URL эндпоинта в окружение вашего агента.
- Пинги: добавьте именованные публичные URL (например,
site,api,docs) с per-ping интервалом, до лимита тарифа. - Telegram: включите доставку мониторинга и опционально задайте отдельную группу/чат.
6. Формат отчёта
Отчёт – тот же metadata-driven payload v2, что и в
контракте кастом-метрик (табы, секции,
строки Telegram, метрики), пушится в
POST /api/v1/monitoring/report с заголовком
Authorization: Bearer <токен мониторинга>. Мониторинг
добавляет зарезервированные id:
| Зарезервированный id | Статус | Смысл |
|---|---|---|
overall | обязателен | Метрика kind status: итог тика, severity ok | warn | crit. Кормит агрегат. Отчёт без валидной overall отвергается (422). |
issues | рекомендуем | Метрика kind list: текущие проблемы. До 5 пунктов цитируются в тексте алертов. |
ping:* | запрещён | Namespace метрик-id наших собственных пингов; в push отвергается (422). |
pings | запрещён | Id Telegram-строки нашей строки пингов; в push отвергается (422). |
monitoring | таб панели | Id базового таба. Метрики могут адресоваться в него (dashboard.tab: "monitoring") без объявления в tabs; объявление игнорируется. |
Лимиты: payload не более 64 KB, не более 200 метрик, не более 2 отчётов в минуту на источник (излишки получают 429 и не засчитываются как heartbeat).
6.1. Пример отчёта
{
"schema_version": "2.0",
"generated_at": "2026-07-12T10:19:58Z",
"tabs": [ { "id": "stand", "title": "Stand", "order": 5, "icon": "server" } ],
"sections": [ { "tab": "stand", "id": "docker", "title": "Docker", "order": 0 },
{ "tab": "monitoring", "id": "host", "title": "Host", "order": 10 } ],
"telegram": { "header": "{sev} {name} monitoring",
"lines": [ { "id": "host", "order": 0, "prefix": "🖥 " },
{ "id": "docker", "order": 1, "prefix": "📦 " } ] },
"metrics": [
{ "id": "overall", "kind": "status", "state": "ok", "severity": "ok" },
{ "id": "issues", "kind": "list",
"value": { "items": [ { "text": "RAM 91% (7.1/7.8G)", "severity": "warn" } ] },
"dashboard": { "show": true, "tab": "monitoring", "section": "host", "order": 0,
"render": "list", "name": "Issues" },
"telegram": { "show": false } },
{ "id": "ram", "kind": "percent", "label": "RAM", "value": 91, "severity": "warn",
"dashboard": { "show": true, "tab": "monitoring", "section": "host", "order": 1,
"render": "kpi" },
"telegram": { "show": true, "line": "host", "pos": 10,
"format": "RAM {value}%", "sep": " · " } }
]
}Успешный ответ:
{ "accepted": true, "effective": "green", "next_expected_by": "2026-07-12T10:26:13Z" }7. Интеграция монитор-скрипта (в стиле monitor.sh)
Если у вас уже крутится cron-скрипт health-check'а, добавьте один best-effort POST в конец его тика. Сбой доставки не должен ронять тик: затянувшееся молчание всё равно поймает watchdog.
# monitor.env
EXTOPS_REPORT_URL="https://extops.dev/api/v1/monitoring/report"
EXTOPS_REPORT_TOKEN="<токен мониторинга из Settings>"
# конец тика: собираем payload через jq из уже посчитанных значений
# и шлём best-effort (доставка никогда не роняет сам тик)
payload="$(jq -n --arg sev "$SEVERITY" '{
schema_version: "2.0",
generated_at: (now | todate),
metrics: [ { id: "overall", kind: "status", state: $sev, severity: $sev } ]
}')"
curl -sS -m 10 -X POST "$EXTOPS_REPORT_URL" \
-H "Authorization: Bearer $EXTOPS_REPORT_TOKEN" \
-H "Content-Type: application/json" \
-d "$payload" || true
Смаппьте severity вашего скрипта на канонический набор (critical
принимается и нормализуется в crit) и отдайте существующий список
проблем в метрику issues. Заявленный интервал держите равным
периоду cron.
8. Telegram: отдельное статус-сообщение и алерты
- Данные мониторинга уходят в Telegram отдельным редактируемым
статус-сообщением, не смешиваясь со статусом кастом-метрик: header +
зарезервированная строка
pings+ строки, объявленные вашим отчётом. - Опционально мониторинг маршрутизируется в отдельную группу/чат; если не задана, используется чат канала расширения. Бот-транспорт общий с каналом расширения.
- Edge-алерты срабатывают на каждую смену агрегатного цвета, в обе стороны, включая recovery обратно в green (с длительностью инцидента). Пока цвет стабилен – тишина; правки конфига (пауза, редактирование пингов) не алертятся.
9. Машиночитаемый контракт
Формальное описание эндпоинта отчётов, схемы payload, зарезервированных id и семантики светофора – файл OpenAPI 3.1. Он несёт ту же версию контракта (2.0.0).