Heartbeat-мониторы

Heartbeat-монитор принимает запросы на уникальный URL. Выберите, когда получать уведомления: если ожидаемый пинг не пришёл или, наоборот, при получении сигнала. Во втором режиме один монитор может принимать сообщения от всех узлов сети.

Режимы мониторинга

  • absence — «Отсутствие сигнала», режим по умолчанию. CronBox уведомляет, когда запрос не пришёл по расписанию. Подходит для cron-задач и бэкапов.
  • signal — «Получение сигнала». CronBox уведомляет при поступлении запроса, включая первый. Расписание не требуется, отсутствие запросов не вызывает тревог.

Контроль отсутствия сигнала

  1. 1

    Создайте монитор

    Выберите тип расписания: фиксированный интервал или cron-выражение. Укажите grace period.

  2. 2

    Получите URL для пинга

    Каждый монитор имеет уникальный URL вида https://api.cronbox.ru/ping/abc123

  3. 3

    Добавьте пинг в ваш cron

    В конце вашего скрипта отправьте GET-запрос на URL монитора

  4. 4

    Получайте уведомления

    CronBox уведомит вас, если пинг не получен в ожидаемое время

Получение сигнала: один монитор для всех узлов

Например, нужно обнаружить доступ к CronBox из закрытого контура с Astra Linux. Создайте один монитор в режиме «Получение сигнала» и включите нужные каналы уведомлений в настройках рабочего пространства. Через API монитор создаётся так:

curl -X POST https://api.cronbox.ru/v1/workspaces/{workspace_id}/heartbeats \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"Закрытый контур","mode":"signal","signal_cooldown":3600}'

Используйте выданный ping_url на всех станциях и передавайте имя узла в msg. Отдельные мониторы для новых станций не нужны:

https://api.cronbox.ru/ping/REPLACE_WITH_MONITOR_TOKEN?msg=arm1

Пример crontab для проверки каждую минуту. Замените URL на выданный монитором; --data-urlencode кодирует имя станции, включая пробелы и кириллицу. Ключ API на узлах не нужен — используется секретный токен в URL.

* * * * * /usr/bin/curl --fail --silent --show-error --connect-timeout 5 --max-time 10 -X POST --get --data-urlencode "msg=$(hostname)" 'https://api.cronbox.ru/ping/REPLACE_WITH_MONITOR_TOKEN' >/dev/null 2>&1

Здесь --get помещает параметр в URL, а -X POST сохраняет метод POST. Альтернатива — сообщение в JSON:

curl --fail --silent --show-error --connect-timeout 5 --max-time 10 \
  -X POST 'https://api.cronbox.ru/ping/REPLACE_WITH_MONITOR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"message":"arm1","payload":{"network":"closed"}}'
  • msg — необязательный текст до 255 символов, без нулевого символа. Имеет приоритет над JSON message, даже если передан пустым. Пробелы по краям удаляются; пустой текст считается отсутствием сообщения. Некорректное значение возвращает HTTP 422 без регистрации пинга.
  • signal_cooldown — минимальный интервал между попытками уведомления в секундах: по умолчанию 3600, от 60 до 2592000 (30 дней). Считается отдельно для каждой пары «монитор + сообщение»: arm1 не подавляет arm2. Запросы без сообщения используют общий интервал монитора.
  • Используйте стабильные уникальные имена: регистр учитывается, изменение текста означает новый источник, одинаковые имена разделяют интервал. При постоянном доступе уведомления повторяются с учётом этого интервала.
  • Имя узла включается в MAX, Email, Webhook и Push при включённых каналах, доступных на тарифе. Длинный Push-текст может сокращаться; полное сообщение доступно в истории пингов в поле status_message. История хранит последние 100 запросов, включая повторные сигналы без уведомления.
  • Пауза прекращает приём пингов и уведомления. Возобновление сохраняет интервалы, переключение режима сбрасывает их. Интервалы сохраняются при перезапуске API.

Webhook получает событие heartbeat.signal. Объект data содержит workspace_id, workspace_name, heartbeat_id, name, received_at (UTC), source_ip и message (строка или null).

Проверка подтверждает доступ именно к CronBox. Если другие внешние адреса доступны, а CronBox заблокирован, сигнала не будет. Этот режим не отслеживает исчезновение отдельных узлов. Проверьте поступление запроса в истории: HTTP 200 также возвращается для неизвестного токена и монитора на паузе.

Пинги start, fail и код выхода

URL монитора совместим с Healthchecks.io: помимо обычного пинга об успехе есть сигналы о начале работы и об ошибке. В режиме absence они позволяют отслеживать длительность задачи и сбои.

URL=https://api.cronbox.ru/ping/abc123

curl -fsS "$URL/start"       # задача началась, время фиксируется
./backup.sh
curl -fsS "$URL/$?"          # код выхода: 0 - успех, иначе - ошибка

# или явно
curl -fsS "$URL/fail"        # задача завершилась с ошибкой

Основной URL поддерживает GET, POST и HEAD; суффиксы — GET и POST. В режиме absence ненулевой код выхода и /fail сразу присылают уведомление о сбое, не дожидаясь дедлайна. В режиме signal любой из этих запросов считается входящим сигналом и поддерживает msg с отдельным интервалом уведомлений.

Эндпоинты

Управление мониторами требует авторизации. Пути ниже указаны относительно /v1/workspaces/{workspace_id}. PATCH поддерживает mode и signal_cooldown; при переключении в absence задайте корректное расписание.

GET
/heartbeats

Список мониторов

POST
/heartbeats

Создание монитора

GET
/heartbeats/{id}

Получение монитора

PATCH
/heartbeats/{id}

Обновление монитора

DELETE
/heartbeats/{id}

Удаление монитора

POST
/heartbeats/{id}/pause

Приостановка монитора

POST
/heartbeats/{id}/resume

Возобновление монитора

GET
/heartbeats/{id}/pings

История пингов

Типы расписания

В режиме absence монитор поддерживает два типа расписания: фиксированный интервал и cron-выражение. Для signal расписание не требуется.

interval — Интервал

Следующий пинг ожидается через фиксированный промежуток после предыдущего. Подходит для задач с плавающим временем запуска.

Поля: expected_interval (обязательно)

cron — Cron-расписание

Следующий пинг ожидается в соответствии с cron-выражением. Точно соответствует расписанию вашей задачи — нет дрейфа времени.

Поля: cron_expression (обязательно)

Создание монитора (интервал)

curl -X POST https://api.cronbox.ru/v1/workspaces/{workspace_id}/heartbeats \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Воркер очереди",
    "schedule_type": "interval",
    "expected_interval": "5m",
    "grace_period": "2m",
    "notify_on_late": true,
    "notify_on_recovery": true
  }'

Создание монитора (cron)

curl -X POST https://api.cronbox.ru/v1/workspaces/{workspace_id}/heartbeats \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Ежедневный бэкап",
    "schedule_type": "cron",
    "cron_expression": "0 3 * * *",
    "timezone": "Europe/Moscow",
    "grace_period": "30m",
    "notify_on_late": true,
    "notify_on_recovery": true
  }'

Когда использовать cron-режим? Если ваша задача запускается по фиксированному расписанию (например, 0 3 * * *), cron-режим точнее определяет дедлайн для каждого пинга — без накопленного дрейфа. Выражение считается в часовом поясе монитора (timezone); если он не указан — в поясе рабочего пространства.

Формат интервалов

Для режима interval и поля grace_period:

  • 5m — 5 минут
  • 1h — 1 час
  • 24h — 24 часа
  • 7d — 7 дней

Примеры cron-выражений

  • 0 * * * * — каждый час
  • 0 3 * * * — каждый день в 03:00
  • 0 9 * * 1-5 — по будням в 09:00
  • */5 * * * * — каждые 5 минут
  • 0 0 1 * * — 1-го числа каждого месяца

Пинг монитора

Публичный эндпоинт не требует заголовка авторизации. Используйте хост https://api.cronbox.ru без префикса /v1. Основной URL принимает GET, POST и HEAD; все формы поддерживают ?msg=arm1.

GET
/ping/{token}

Отправка пинга (публичный)

POST
/ping/{token}

Отправка пинга с данными

GET
/ping/{token}/start

Задача началась

GET
/ping/{token}/fail

Задача упала

GET
/ping/{token}/{exit_code}

Пинг с кодом выхода

Healthchecks.io-совместимые URL

Скрипты, написанные для Healthchecks.io, работают в CronBox без изменений — достаточно поменять хост и токен. Все три формы принимают GET и POST и, как и обычный пинг, отвечают 200 OK и для неизвестного или приостановленного монитора. Ошибки валидации параметров возвращают HTTP 422. Следующее описание относится к режиму absence; в режиме signalвсе формы регистрируют входящий сигнал.

  • /ping/{token}/start — задача началась. Состояние монитора не меняется, но следующий обычный пинг сам посчитает длительность выполнения.
  • /ping/{token}/fail — задача упала. Монитор сразу переходит в late и отправляет уведомление, не дожидаясь дедлайна (если включено notify_on_late). Повторные сигналы только копят счётчик пропусков и не шлют уведомление второй раз.
  • /ping/{token}/{exit_code} — код 0 равен обычному пингу, любой другой работает как /fail, а сам код попадает в текст уведомления.

Тело запроса (лог выполнения, до 4 КБ) сохраняется вместе с успешным пингом: JSON — как есть, любой другой текст — в поле output.

Примеры cron для режима absence

# Crontab: бэкап каждый день в 3:00
0 3 * * * /opt/scripts/backup.sh && curl -fsS https://api.cronbox.ru/ping/abc123

# С сигналом старта: длительность посчитается автоматически
0 3 * * * curl -fsS https://api.cronbox.ru/ping/abc123/start && /opt/scripts/backup.sh && curl -fsS https://api.cronbox.ru/ping/abc123

# С кодом выхода: 0 — успех, всё остальное — падение
0 3 * * * /opt/scripts/backup.sh; curl -fsS https://api.cronbox.ru/ping/abc123/$?

# С логом выполнения в теле запроса
0 3 * * * /opt/scripts/backup.sh 2>&1 | curl -fsS --data-binary @- https://api.cronbox.ru/ping/abc123/0

Статусы монитора

В режиме signal монитор ожидает первый запрос (waiting), затем переходит в healthy. Отсутствие новых запросов не переводит его в late и не означает, что отдельные станции доступны или недоступны.

healthy

Пинг получен вовремя, всё работает нормально

waiting

Ожидание первого пинга или находится в grace period

late

Пинг не получен в ожидаемое время - возможна проблема

Совет для режима absence: Устанавливайте grace period с запасом. Если скрипт обычно выполняется 10 минут, grace period должен быть 15–20 минут. В cron-режиме дедлайн = следующий тик расписания + grace period.