Heartbeat-мониторинг cron-задач в indie SaaS
Cron и фоновые очереди ломаются тихо: веб остаётся зелёным, а ночной биллинг или синхронизация почты не работали три дня. Паттерн heartbeat: задача после успеха дергает HTTP endpoint; если тишина дольше окна — что-то сломалось.
StillOnline выполняет по расписанию HTTP GET по зарегистрированным URL — не пассивный «пропущенный ping», как у Healthchecks.io. Ниже — как адаптировать heartbeat через HTTP, чего хватит на Free (один URL, проверка раз в пять минут; тарифы) и когда добавить отдельный инструмент под cron.
Краткий ответ
В StillOnline нет нативного монитора «cron не прислал ping». Дайте HTTP URL, который задача вызывает после успеха — например GET /internal/cron-heartbeat с 200 и меткой времени — и зарегистрируйте его в StillOnline, либо включите успех cron в ответ /health. На Free интервал пять минут; две неудачные проверки подряд → DOWN и алерты владельцу. Для семантики «задача каждый час» с точностью до минуты добавьте специализированный heartbeat-SaaS или кодируйте время последнего запуска в URL, который StillOnline уже опрашивает.
Heartbeat, HTTP uptime и CI
| Паттерн | Что ломается | StillOnline |
|---|---|---|
| HTTP uptime | Недоступен веб/API | Основной сценарий — GET /health |
| Heartbeat | Задача не бежит, сервер жив | Косвенно — URL или JSON /health |
| Только CI | Сломался деплой; prod может отдавать 200 | Actions ≠ cron в production — проверки из CI |
Cron в Linux запускает по расписанию, но не гарантирует exit code 0. Heartbeat закрывает этот пробел.
Паттерн A — отдельный heartbeat URL
GET /internal/cron-heartbeat(защита на периметре или секрет в query — не светите в публичных docs).- После успеха задача пишет в БД/файл; маршрут отдаёт 200, только если
last_successв SLA (например 26 ч для суточного cron). - В StillOnline → HTTP-проверка → ожидаемый 200.
curl -sS https://api.yourproduct.com/internal/cron-heartbeat
При сбое задачи — 503 или устаревшие данные; StillOnline краснеет после двух неудачных проверок (~10 минут при интервале 5 мин).
Паттерн B — last-run в /health
На Free (один URL) часто добавляют "cron_last_ok": "2026-06-08T06:00:00Z" в JSON /health и возвращают 503, когда окно SLA прошло — StillOnline смотрит код ответа. Подробнее: дизайн health URL, API-only.
Паттерн C — worker без публичного порта
Внутренний worker без ingress не получит GET от StillOnline. Варианты: heartbeat в Redis/БД и чтение в публичном /health; отдельный component «Фоновые задачи» на странице статуса — workers и очереди.
Настройка StillOnline
- Старт → проект.
- HTTP-проверка на heartbeat или
/health. - Страница статуса + Telegram-алерты.
Pro ($9/мес) — до 10 URL на проект; можно разделить веб и cron. Тарифы.
Связанные материалы
- Мониторинг фоновых workers и очередей
- Дизайн health endpoint
- Чеклист мониторинга side-project
- Мониторинг API-only SaaS
FAQ
Есть ли в StillOnline пассивный heartbeat как у Healthchecks?
Нет. StillOnline активно GET-ит URL. Cron должен держать доступный HTTPS в успешном состоянии или /health должен уходить в non-200 при простое задач.
Заменяют ли GitHub Actions StillOnline для cron?
Actions доказывают прогон workflow в CI, но не заменяют внешние пробы production URL — Actions vs production.
Как быстро придёт алерт, если суточный cron не отработал?
При интервале 5 мин и двух неудачах подряд — порядка 10 минут после того, как URL останется unhealthy. Маршрут heartbeat должен отдавать 503, как только SLA окно истекло.