Как я перенес мониторинг с Uptime Kuma на Cloudflare Workers
Мониторинг должен ответить на очень простой вопрос: жив ли сервис для человека за пределами моего сервера? Пока статус-страница и проверяющий процесс работают на той же машине, ответ получается ненадежным. Сервер может потерять сеть, зависнуть или полностью остановиться. В этот момент вместе с сервисами пропадает и сам наблюдатель.
У меня именно так был устроен Uptime Kuma. Он хорошо справлялся с интерфейсом и набором проверок, но находился в той же инфраструктуре, которую должен был проверять. Поэтому я перенес мониторинг на Cloudflare Workers и оставил серверу только роль цели проверки.
В чем была проблема
Самостоятельно развернутый мониторинг удобен, пока все работает. Он показывает зеленые карточки, хранит историю и выглядит убедительно. Сложность появляется в неприятном сценарии: недоступен сам хост.
Тогда нельзя быстро понять, что происходит. Упал конкретный сервис, недоступна сеть, сломался сервер или просто перестала открываться страница мониторинга? В последнем случае Uptime Kuma не может прислать сообщение о собственной недоступности, потому что он уже не выполняется.
Мне был нужен независимый наблюдатель, который продолжит делать запросы, даже если мой сервер полностью исчезнет из сети.
Новая схема
Теперь проверки запускает Cloudflare Worker по расписанию. Раз в минуту он обращается к HTTP-адресам сервисов из внешней сети Cloudflare. Конфигурация содержит список 37 проверок: публичные сайты, API, внутренние служебные точки и внешние зависимости.
Результаты не остаются только в логах. Worker записывает актуальное состояние и историю в Cloudflare D1. Отдельная страница на Cloudflare Pages читает эти данные и показывает общий статус, время последнего обновления и короткую историю для каждой проверки.
Схема стала заметно проще:
- Cloudflare Worker запускает проверки вне сервера.
- D1 хранит состояние и историю инцидентов.
- Status page показывает результат по проектам.
- Telegram получает сообщения о падении и восстановлении.
TL;DR: как запустить свой вариант
Я вынес пустую версию этой схемы в публичный Cloudflare Uptime Starter. В нем нет логотипа MarketMaker, списка наших мониторов и данных для уведомлений. В основе та же независимая проверка и D1, а статус-страница работает в отдельном Worker и готова к актуальному способу развертывания Next.js в Cloudflare.
Короткий путь такой:
- Создать репозиторий на основе шаблона и заменить
example-siteвconfig/public.tsна свой публичный адрес. - Выполнить
npm ciиnpm --prefix worker ci, затем создать D1 через Wrangler. - Вставить полученный D1 ID в оба файла Wrangler, инициализировать базу из
init.sqlи развернуть проверяющий Worker и статус-страницу. - При необходимости добавить URL уведомлений и JSON-тело как секреты Worker. Им не место в TypeScript-конфигурации или GitHub Actions YAML.
Точные команды есть в README шаблона. Это надежнее, чем копировать рабочую конфигурацию: в ней есть названия наших сервисов и рабочие детали, которые другому проекту не нужны.
Как теперь приходят уведомления
Один неудачный запрос не всегда означает аварию. Бывают короткие сетевые задержки, перезапуск приложения или временный ответ от прокси. Поэтому уведомление о проблеме отправляется после двух последовательных сбоев, а не после первого таймаута.
Когда проверка снова проходит, приходит отдельное сообщение о восстановлении. Это важная деталь: сообщение о падении без подтверждения восстановления заставляет потом вручную гадать, осталась ли проблема или сервис уже вернулся.
Перед переключением я проверил оба события на тестовом мониторе: уведомление о недоступности и уведомление о возвращении сервиса. Это не заменяет реальный инцидент, но подтверждает всю цепочку от планировщика до Telegram.
Статус-страница стала ближе к работе, а не к списку адресов
Мониторы сгруппированы по проектам: MarketMaker, торговые инструменты, ProfitMaker, Listing APIs, Warehouse, резервные копии, исследовательские сервисы, платформа и внешние зависимости. Так статус быстрее читается в момент инцидента. Вместо длинного технического списка видно, какой продукт и какая часть инфраструктуры затронуты.
На главной странице оставлена компактная история доступности. Детальная страница отдельного монитора по-прежнему показывает график с более коротким интервалом. Это хороший баланс: общий экран не перегружен, а данные для разбора инцидента остаются рядом.
Еще одна проверка появилась у самой системы мониторинга. Время последнего обновления данных не должно быть старше пяти минут. Если оно устарело, страница показывает предупреждение. Зеленый экран без свежих проверок ничем не лучше выключенного мониторинга.
Что важно проверять после изменения
После публикации я смотрю не только на зеленые статусы. Минимальный список такой:
- API статус-страницы возвращает свежий
updatedAt; - число мониторов совпадает с конфигурацией;
- расписание Worker активно;
- в D1 появляется новое состояние;
- тестовое уведомление доходит до Telegram;
- в логах нет URL, заголовков или тел уведомлений с секретами.
Последний пункт появился не случайно. Адрес Telegram webhook содержит токен бота, поэтому подробное логирование таких запросов превращает удобную диагностику в риск. В рабочем коде остались только безопасные сведения: тип уведомления и HTTP-статус ответа.
Что изменилось по сути
Uptime Kuma был полезным локальным инструментом, но для главной задачи он находился слишком близко к тому, что проверял. Cloudflare Workers вынесли саму проверку за пределы сервера, а Pages и D1 дали публичную страницу со свежим состоянием и историей.
Теперь, если сервер перестанет отвечать, проверка все равно выполнится из внешней сети, состояние станет красным, а уведомление придет в Telegram. Именно такой сигнал я и хотел получить: не “мониторинг на сервере считает, что все хорошо”, а независимое подтверждение, что сервис действительно доступен снаружи.