MAATRIX / Блог / Проверка мониторинга на живучесть: кто сторожит сторожа

Проверка мониторинга на живучесть: кто сторожит сторожа

MAATRIX

Тишина в канале с алертами обычно читается как хорошая новость: раз никто не пишет, значит всё работает. Но у тишины есть и другая причина — мониторинг сам сломался и просто не может об этом сообщить. Он следит за вашими серверами, но за ним самим не следит никто, и это классическая проблема «quis custodiet ipsos custodes» — кто сторожит сторожей — в чистом виде эксплуатации.

Почему мониторинг — это тоже система, которая может упасть

Мониторинг в голове администратора часто занимает особое место: это инструмент проверки, а не объект проверки. Prometheus, Zabbix, Uptime Kuma или платный SaaS воспринимаются как нечто более надёжное, чем сервисы, за которыми они следят — иначе зачем на них полагаться. На практике это ничем не обоснованное допущение. Сервер мониторинга — точно такой же сервер, с тем же диском, который может заполниться, той же сетью, которая может лечь, тем же systemd-юнитом, который может упасть после apt upgrade и не подняться сам.

Разница в том, что отказ обычного сервиса вы увидите — по жалобам пользователей, по тому, что сайт не открывается. Отказ мониторинга не сигнализирует о себе никак. Метрики перестают собираться, дашборд показывает данные шестичасовой давности, но выглядит визуально почти так же, как и час назад, если не приглядываться к таймстампам. Алерты просто не приходят, и узнать об этом можно, либо случайно открыв дашборд, либо дождавшись реального инцидента, который никто не заметит вовремя.

Это не гипотетическая экзотика. Мы разбирали похожую ситуацию, когда мониторинг стоял на том же сервере, что и прод, и умер вместе с ним — сервер упал целиком, унеся с собой и то, что должно было об этом сообщить. Здесь же речь про более тонкий случай: сервер мониторинга живёт своей жизнью отдельно от продакшена, но его собственные внутренние отказы остаются такими же незаметными.

Три способа, которыми сторож перестаёт сторожить

На практике отказ системы мониторинга почти всегда сводится к одному из трёх сценариев. Они разные по причине, но одинаковые по последствию: система выглядит настроенной и работающей, а сигнал не доходит.

Упал сам сервер или процесс мониторинга. Хост с Prometheus/Grafana/Zabbix ушёл в перезагрузку после планового обновления ядра и не поднялся — забыли systemctl enable, или сервис упал по OOM и не перезапустился, потому что не настроен Restart=always в юните. Диск с базой временных рядов (TSDB у Prometheus, база Zabbix) заполнился под ноль, процесс лёг с ошибкой записи. Формально сервер мониторинга существует, отвечает на ping, но конкретный процесс, который что-то проверяет, не работает уже несколько дней.

Сломалась доставка уведомлений при живом мониторинге. Это более коварный случай: сама система жива, метрики собираются, правила алертов срабатывают правильно — но notifier, который должен превратить сработавшее правило в сообщение, не может его доставить. Классика — исходящий SMTP на порту 25 заблокирован у хостинг-провайдера (многие блокируют его по умолчанию для новых VPS), и алерты по почте улетают в никуда без единой ошибки в логе получателя. Или Alertmanager настроен на вебхук в чат, а сетевой ACL или файрвол на сервере мониторинга поменяли и забыли открыть исходящий 443 на нужный домен.

Истёк или был отозван токен интеграции с каналом оповещений. Токен Telegram-бота, webhook URL Slack, API-ключ PagerDuty или OpsGenie — все они рано или поздно протухают: бот заблокирован пользователем случайно, токен отозван при ротации секретов, у webhook закончился срок действия, интеграцию отключили при реорганизации workspace. Мониторинг честно пытается отправить сообщение, получает от API ответ вроде 401 Unauthorized или 403 Forbidden, но эта ошибка обычно летит в лог самого мониторинга — туда же, куда никто не смотрит, потому что раньше не было повода.

Из этих трёх сценариев третий — самый частый на практике, потому что не требует никакой поломки инфраструктуры: всё работает штатно, кроме одной интеграции, отвалившейся незаметно месяц назад. Разбор похожего случая, когда алерт технически ушёл, но в чат, который никто не открывал, показывает соседнюю грань той же проблемы — доставка формально состоялась, а сигнал всё равно не дошёл до человека.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Почему нельзя проверять мониторинг мониторингом

Первое, что приходит в голову, — настроить алерт «если мониторинг не отвечает, пришли алерт». Это не решает проблему: если сломалось само уведомление или сервер мониторинга, алерт о его поломке пойдёт по тому же сломанному пути. Prometheus не пришлёт сообщение о том, что Prometheus не работает, потому что для этого ему нужно работать. Это тот же тупик, что у охранной сигнализации, у которой кнопка проверки батарейки находится внутри самой сигнализации — если батарейка села полностью, кнопка ничего не покажет.

Отсюда единственный рабочий принцип: проверка живости мониторинга должна идти по независимому каналу — на трёх уровнях одновременно: другой сервер (физически не тот же хост и желательно не тот же провайдер), другой канал доставки (не тот же бот, не тот же SMTP-релей) и другая логика проверки (не «сработало правило», а «получен ли вообще регулярный сигнал жизни»).

Внешний независимый способ проверки: dead man's switch

Правильная модель здесь — не «спросить систему, всё ли у неё хорошо», а «дождаться регулярного подтверждения от неё и поднять тревогу при его отсутствии». Это принцип dead man's switch, тот же, что используется в железнодорожной автоматике: если машинист перестаёт нажимать на педаль бдительности, состав останавливают, не дожидаясь объяснений почему.

Практически это реализуется через внешний сервис, который ничего не знает о вашей инфраструктуре и не зависит от неё — например Healthchecks.io (облачный SaaS или self-hosted на третьем, отдельном сервере). Мы разбирали механику таких проверок в статье про мониторинг cron-задач через Healthchecks.io — здесь та же идея применяется не к бэкапу, а к самому мониторингу.

Настройка выглядит так: на сервере мониторинга ставится cron-задача, которая раз в 5-10 минут отправляет пинг на внешний URL:

*/5 * * * * curl -fsS -m 10 --retry 3 https://hc-ping.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx > /dev/null

На стороне Healthchecks.io задаётся период (Period) и допустимый запас (Grace) — например «жду пинг каждые 10 минут, даю 5 минут форы». Если пинг не пришёл вовремя — Healthchecks.io сам, по своей независимой инфраструктуре, отправляет вам уведомление о том, что «сторож замолчал». Критично, что канал оповещения здесь стоит настроить отдельно от основного: например, если у вас Alertmanager шлёт всё в один Telegram-бот, для Healthchecks.io заведите второй бот или вообще email на отдельный ящик — чтобы отказ токена основного бота не убил и этот канал тоже.

Тот же принцип можно реализовать без стороннего сервиса — на втором, независимом сервере (в идеале у другого провайдера, чтобы не ловить общий инцидент дата-центра):

#!/bin/bash
# сторожевой скрипт на втором сервере, cron раз в 10 минут
URL="https://prometheus.example.com/api/v1/query?query=up"
RESP=$(curl -fsS -m 10 "$URL")
if [ $? -ne 0 ] || ! echo "$RESP" | grep -q '"status":"success"'; then
  curl -s -X POST "https://api.telegram.org/bot<ЗАПАСНОЙ_ТОКЕН>/sendMessage" \
    -d chat_id=<ID> \
    -d text="ВНИМАНИЕ: основной Prometheus не отвечает на запрос уже 10+ минут"
fi

Здесь принципиально важны две вещи: скрипт стоит на другом сервере, и токен бота — отдельный от основного. Если оба используют один и тот же Telegram-бот, отзыв токена убьёт обе цепочки оповещения одновременно, и вся конструкция теряет смысл независимой проверки.

Периодическая тестовая тревога: убедиться, что уведомление реально доходит

Дважды доверять сигналу без проверки — ошибка. Мониторинг может быть технически жив, но конкретный маршрут доставки (этот чат, этот email, этот номер в PagerDuty) может быть мёртв уже месяцами именно потому, что настоящих инцидентов давно не было и маршрут никогда не тестировался в бою. Регулярная тестовая тревога закрывает именно этот пробел — она не проверяет «жив ли Prometheus», она проверяет «дойдёт ли реальное сообщение до реального человека прямо сейчас».

Практический подход — намеренно вызывать синтетическое условие срабатывания алерта на регулярной основе, а не полагаться на то, что рано или поздно случится настоящий инцидент. Варианты, от простого к более полному:

  • Синтетический алерт-правило, которое всегда активно. В Prometheus Alertmanager для этого есть встроенный паттерн — правило Watchdog, которое всегда в состоянии firing, и это специально настроенное «всегда включено» превращается в проверку живости всей цепочки через маршрутизацию с repeat_interval в Alertmanager и внешний контроль, что уведомление действительно приходит с этим интервалом.
  • Ручная или скриптовая инъекция тестового события. Раз в месяц (см. ниже про регламент) вручную временно опустить порог алерта или искусственно создать условие срабатывания — например stress-ng --cpu 4 --timeout 60s на тестовом хосте, чтобы реально пробить порог по CPU, или временно остановить тестовый сервис командой systemctl stop nginx на некритичном стенде.
  • Отправка тестового сообщения напрямую через API канала, в обход логики мониторинга — просто чтобы проверить, что токен бота или webhook ещё действителен:
curl -s -X POST "https://api.telegram.org/bot<ТОКЕН>/sendMessage" \
  -d chat_id=<ID> \
  -d text="Тестовая тревога $(date '+%Y-%m-%d %H:%M'): проверка доставки, реагировать не нужно"

Важная деталь: тестовая тревога должна явно помечаться как тестовая прямо в тексте сообщения. Иначе вы рискуете либо породить ложную панику у дежурного, либо, что хуже, приучить команду игнорировать реальные алерты, потому что «в последний раз это тоже была проверка» — тот самый эффект, который мы разбирали в статье про мониторинг, за которым никто уже не следит: поток шумных или непонятных сообщений методично убивает доверие к каналу.

Регламент проверки: кто, когда и что именно смотрит

Одноразовая настройка внешнего дозора не работает сама по себе годами без пересмотра — токены протухают, серверы переезжают, интеграции меняются. Нужен минимальный, но обязательный регламент, который не зависит от памяти конкретного человека.

Что проверяемЧастотаКакКто отвечает
Внешний dead man's switch (Healthchecks.io или второй сервер) получает пингиПостоянно, автоматическиGrace-период в самом сервисеАвтоматика, без участия человека
Токены/webhook интеграций каналов (Telegram, Slack, email) действительныРаз в месяцТестовое сообщение через API канала напрямуюДежурный инженер
Реальная тестовая тревога доходит до дежурного и он подтверждает получениеРаз в кварталСинтетический алерт + подтверждение в ответном сообщенииОтветственный за эксплуатацию
Дашборд мониторинга показывает свежие данные, а не «зависшие» на старой отметкеПри каждом дежурствеВизуальная проверка таймстампа последней точкиДежурный инженер
Диск и память сервера мониторинга не близки к исчерпаниюРаз в неделюdf -h, free -m на сервере мониторингаАвтоматический алерт + ручная сверка раз в месяц

Ключевой момент квартальной тестовой тревоги — обязательное подтверждение получения от живого человека, а не просто факт отправки. Сообщение без подтверждения доставки и прочтения — только половина проверки; вторая половина — убедиться, что дежурный реально увидел его и среагировал, а не что оно тихо легло в закреплённый, но никем не читаемый чат.

Сам регламент стоит держать вне мониторинга — в обычном календаре или таск-трекере, а не в виде задачи внутри Zabbix. Если регламент проверки живёт внутри проверяемой системы, он унаследует её уязвимость: сломается мониторинг — сломается и напоминание о том, что его пора проверить.

Что делать, если проверка нашла проблему

Найденный разрыв в цепочке оповещения — не повод для паники, а ровно то, ради чего проверка и делалась. Порядок действий простой: зафиксировать, с какого момента канал перестал работать (по логам Alertmanager, по истории Healthchecks.io, по коду ошибки от Telegram Bot API — его стоит явно смотреть в логах, а не игнорировать), восстановить конкретный элемент — перевыпустить токен, открыть порт, поднять упавший сервис, — и только затем повторно прогнать тестовую тревогу, чтобы убедиться, что починка действительно сработала.

Находку стоит зафиксировать в истории инцидентов, даже если внешне ничего не сломалось: «токен бота истёк, оповещения не приходили около 12 дней, обнаружено плановой проверкой». Если сбой у одной и той же интеграции повторяется регулярно, есть смысл увеличить частоту проверки именно для неё или сменить канал на более стабильный.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Достаточно ли одного Healthchecks.io, или нужен ещё и второй сервер с отдельным скриптом?

Для большинства небольших и средних инфраструктур внешнего SaaS-сервиса вроде Healthchecks.io достаточно — он сам по себе уже независим от вашего сервера мониторинга. Второй собственный сервер имеет смысл добавлять, если критично не зависеть ни от какого стороннего провайдера вообще или требования комплаенса запрещают отправлять даже минимальные метаданные о живости инфраструктуры наружу.

Как часто на самом деле нужна тестовая тревога — раз в месяц мало или много?

Ориентируйтесь на частоту реальных боевых алертов. Если инциденты редкие (реже раза в месяц), квартальной тестовой тревоги обычно достаточно, чтобы канал не успевал «протухнуть» между настоящими срабатываниями. При активной эксплуатации с частыми алертами отдельная тестовая тревога может быть и не нужна — каждый реальный алерт уже выполняет ту же проверочную функцию.

Стоит ли отправлять тестовое сообщение без пометки «тест», чтобы проверить реакцию дежурного по-честному?

Иногда это оправдано как разовое учение с предупреждением команды в общем виде («на этой неделе будет незапланированная тестовая тревога, дата не разглашается»), но регулярно так делать не стоит — риск ложной эскалации или ночного звонка дежурному обычно перевешивает пользу от более честной проверки.

Нужно ли проверять сам внешний сервис, который следит за мониторингом — получается бесконечная матрёшка?

Нет смысла уходить в рекурсию. Возьмите за правило, что внешний независимый сервис — последний уровень доверия; раз в квартал вручную проверяйте, что аккаунт в нём активен, оплачен и что отсутствие пинга действительно генерирует уведомление на резервный email.

Стоит ли дублировать один и тот же алерт сразу в несколько каналов — Telegram и email одновременно?

Да, это разумная и недорогая страховка именно от сценария «истёк токен одной конкретной интеграции». Два независимых канала с разными точками отказа кратно снижают шанс, что оба откажут одновременно, и почти не усложняют конфигурацию.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →