Мониторинг cron-задач: dead man's switch
Коротко. Cron-задача может тихо умереть — сервер перезагрузился, скрипт упал, диск переполнился — и вы узнаете об этом, только когда бизнес-процесс уже сломан. Dead man's switch (heartbeat-мониторинг сайтов) переворачивает логику: задача должна сама присылать Ping инструмент после успешного выполнения. Нет пинга в ожидаемом окне — система бьёт тревогу. Вы мониторите не доступность сайта, а сам факт того, что фоновая работа выполняется.
Почему обычный мониторинг не видит cron-задачи
Классический uptime-мониторинг проверяет HTTP-эндпоинт снаружи: запрос ушёл, ответ пришёл, статус 200 — всё хорошо. Но cron-задачи не слушают порт. Бэкап базы, очистка очереди, отправка отчётов, ротация логов — у них нет URL, который можно опросить. Они либо отработали, либо нет, и единственный, кто об этом знает, — сам сервер.
Проблема в том, что отсутствие ошибки — это не признак успеха. Если crontab вообще не запустился (демон cron остановлен, файл потерял право на исполнение, переменная окружения исчезла после миграции), то и письма с ошибкой не будет. Тишина выглядит как норма.
Самый опасный сбой — не тот, что кричит в логах, а тот, что молчит. Бэкап, который не делается уже три недели, обнаруживается ровно в тот момент, когда база легла и восстанавливать нечего.
Как работает dead man's switch
Идея в инверсии. Вместо «опроси меня и проверь, что я жив» задача говорит «я отмечусь сама, когда отработаю». Механика проста:
- Вы создаёте heartbeat-монитор и получаете уникальный URL с токеном.
- В конце скрипта, только после успешного выполнения, отправляется HTTP-пинг на этот URL.
- Монитор знает ожидаемый период (например, каждые 5 минут) и грейс-период (допуск на опоздание).
- Если пинг не пришёл в окно «период + грейс» — поднимается инцидент и летит алерт.
Ключевой нюанс: пинг ставится в самом конце и связывается с кодом возврата. Если задача упала на середине, пинг не уйдёт — и это правильно, монитор должен сработать.
Практика: добавляем heartbeat в crontab
Самый надёжный паттерн — выполнить работу, проверить успех логическим && и только потом пингануть. Так пинг физически не отправится, если предыдущая команда вернула ненулевой код:
*/5 * * * * /path/job.sh && curl -fsS https://enterno.io/api/heartbeat?token=XXX
Здесь флаги curl важны: -f молчит при HTTP-ошибке, -s убирает прогресс-бар, -S всё же покажет ошибку сети в почте от cron.
Если нужно отличать старт от завершения (для долгих джобов) и сообщать о провале явно, используйте обёртку в shell-скрипте:
#!/usr/bin/env bash
set -euo pipefail
PING="https://enterno.io/api/heartbeat?token=XXX"
# сигнал «начал работу» (опционально)
curl -fsS "${PING}/start" || true
if /path/to/backup.sh; then
curl -fsS "$PING" # успех
else
curl -fsS "${PING}/fail" # явный провал
exit 1
fi
Выбор периода и грейс-периода
Период — это как часто задача обязана отмечаться. Грейс — насколько ей позволено опоздать, прежде чем считать её мёртвой. Слишком узкий грейс даёт ложные тревоги (джоб иногда выполняется на 10 секунд дольше), слишком широкий — затягивает обнаружение реального сбоя.
| Тип задачи | Период | Рекомендуемый грейс |
|---|---|---|
| Очистка очереди, real-time | 5 мин | 2-3 мин |
| Синхронизация данных | 1 час | 15 мин |
| Ночной бэкап БД | 1 день | 2-4 часа |
| Еженедельный отчёт | 1 неделя | 1 день |
Эмпирическое правило: грейс ≈ обычное время выполнения задачи плюс запас на пиковую нагрузку. Если бэкап обычно идёт 40 минут, а в конце месяца раздувается до 90, ставьте грейс минимум на 2 часа.
Алерты: куда прилетит тишина
Heartbeat бесполезен, если уведомление о пропущенном пинге уходит в никуда. В enterno.io алерты дублируются по нескольким каналам, чтобы один сбойный канал не похоронил тревогу:
- Telegram — мгновенно, с кнопкой перехода в дашборд.
- Slack — в командный канал дежурных.
- webhook — для интеграции с вашим инцидент-менеджментом.
- Email — как резервный канал.
Подробнее о том, как выстроить разумную эскалацию и не утонуть в шуме, — в материале лучшие практики алертинга.
Типичные ошибки
- Пинг до выполнения работы. Если curl стоит в начале строки, монитор зелёный даже когда сама задача падает. Всегда
&&и конец скрипта. - Токен в публичном репозитории. URL с токеном — это секрет. Храните его в переменной окружения или vault, не коммитьте в git.
- Один монитор на пачку разных задач. Каждая cron-строка заслуживает своего heartbeat: иначе непонятно, какая именно умерла.
- Грейс впритык. Сетевые задержки и пиковая нагрузка — норма. Заложите запас.
Частые вопросы
Чем dead man's switch отличается от обычного uptime-мониторинга?
Uptime-мониторинг сам опрашивает ваш сервер снаружи. Dead man's switch ждёт, пока задача сама отметится изнутри. Первый подходит для сайтов и API документацию, второй — для фоновых джобов, у которых нет публичного эндпоинта. Подробное сравнение — в гайде по мониторингу cron-задач.
Сколько heartbeat-мониторов даёт бесплатный план?
На бесплатном плане enterno.io доступно 10 мониторов, и любой из них можно настроить как heartbeat. Этого хватает для типичного набора фоновых задач небольшого проекта.
Что если задача выполняется нерегулярно?
Для джобов с плавающим расписанием ставьте период по максимально редкому ожидаемому интервалу и щедрый грейс. Если задача может вообще не запуститься в какой-то день по дизайну — heartbeat ей не подходит, используйте логирование результата.
Можно ли пинговать из любого языка, а не только curl?
Да. Heartbeat-эндпоинт — это обычный HTTP-запрос. Подойдёт requests в Python, fetch в Node, HttpClient в .NET — что угодно, что умеет сделать GET с вашим токеном.
Как избежать ложных тревог при деплое?
На время плановых работ ставьте монитор на паузу. Это честнее, чем расширять грейс «на всякий случай» и потом проспать настоящий сбой.
Начните мониторить cron уже сейчас
Создайте свой первый dead man's switch за пару минут: откройте Heartbeat / Cron-монитор, получите токен и вставьте одну строку curl в crontab. Дальше — настройте период, грейс и каналы алертов, и тишина в фоновых задачах перестанет быть угрозой.
Если выстраиваете мониторинг с нуля, начните с общего руководства по мониторингу сайтов и гайда по uptime-мониторингу — heartbeat хорошо дополняет внешние проверки доступности.