Мониторинг настроен, а алерты уходят в никуда: чиним чужие уведомления
Открываете Zabbix или Grafana на унаследованном сервере — и видите, что мониторинг действительно настроен: метрики собираются, графики рисуются, правила алертов существуют и даже подсвечены зелёным как активные. Первое желание — выдохнуть и вычеркнуть мониторинг из списка проблем. Но «правило существует» и «уведомление реально дойдёт до живого человека» — это два разных факта, и разрыв между ними на унаследованном сервере обнаруживается обычно не при аудите, а в момент, когда сервис уже лежит, а телефон молчит. Ниже — как методично проверить всю цепочку доставки чужих алертов и починить то, что реально сломано, а не то, что выглядит подозрительно.
Содержание
- Почему на чужом сервере алерты чаще всего не доходят
- Устаревшие получатели: email и Telegram, которые никто не читает
- Истёкшие и отозванные токены: где искать протухшие ключи
- Забытые правила подавления: silence и mute, о которых никто не помнит
- Сквозная проверка: от события до реального уведомления
- Восстанавливаем доставку и наводим порядок в конфигурации
Почему на чужом сервере алерты чаще всего не доходят
Цепочка доставки алерта состоит из нескольких независимых звеньев: метрика собирается → правило её оценивает → срабатывает триггер → уведомление формируется → уходит получателю → получатель его видит. На сервере, который вы настраивали сами, все звенья менялись у вас на глазах, и вы бы заметили обрыв. На унаследованном сервере вы видите только текущее состояние конфига, а не историю его изменений — и не знаете, какое звено протухло без вашего участия.
Типичная картина: администратор полтора года назад настроил Zabbix с оповещением на личную почту и в общий чат в Telegram. За это время он сменил работу и вышел из чата, домен компании перестал существовать после ребрендинга, а бот был удалён из группы при очередной чистке участников — без единого сообщения об ошибке на стороне Zabbix, потому что отправка формально прошла успешно. Каждое событие по отдельности не выглядит катастрофой. Вместе они превращают «настроенный» мониторинг в систему, которая честно детектирует проблемы и так же честно отправляет их в пустоту.
Ключевое отличие унаследованной ситуации от собственной ошибки конфигурации: тут не один сломанный элемент, а произвольная комбинация из нескольких, и предположить, какая именно, нельзя — нужно проверять каждое звено отдельно, начиная с получателей.
Устаревшие получатели: email и Telegram, которые никто не читает
Первое, что стоит выписать — полный список получателей во всех каналах оповещений, а не полагаться на память или документацию, которой обычно не существует. В Zabbix это делается через Alerts → Media types и Users → Permissions: у каждого пользователя может быть привязано несколько способов оповещения (email, Telegram, SMS-шлюз), и часть из них может ссылаться на пользователей, которых давно нет в системе или которые деактивированы.
-- В MySQL/MariaDB Zabbix — список активных медиа с привязкой к пользователям
SELECT u.username, mt.name AS media_type, m.sendto, m.active
FROM media m
JOIN users u ON u.userid = m.userid
JOIN media_type mt ON mt.mediatypeid = m.mediatypeid
WHERE m.active = 0; -- active=0 значит канал включён в Zabbix (инвертированная логика в старых версиях)
Поле sendto — это фактический email или chat_id, на который уходит уведомление. Проверьте каждый адрес вручную: жив ли домен, существует ли ящик, отвечает ли он на письмо. Часто адрес вида alerts@company-old-domain.ru перестаёт принимать почту после смены хостинга, но в Zabbix об этом никто не узнает — SMTP-сервер может принять письмо на доставку (250 OK) и молча дропнуть его на стороне получателя или отправить в карантин.
Для Alertmanager (связка с Prometheus) получатели описаны в receivers секции конфига:
receivers:
- name: 'team-telegram'
telegram_configs:
- bot_token: '123456789:AAExampleTokenValueHere'
chat_id: -1001234567890
parse_mode: 'HTML'
- name: 'team-email'
email_configs:
- to: 'oncall@example.com'
from: 'alertmanager@example.com'
smarthost: 'smtp.example.com:587'
Проверьте chat_id через API самого бота — если бота выкинули из группы, запрос вернёт ошибку Forbidden: bot was kicked from the group chat, а не тихо провалится:
curl -s "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
-d chat_id="${CHAT_ID}" \
-d text="Тестовое сообщение: проверка живости чата"
Ответ {"ok":false,"error_code":403,...} — это именно та ситуация, которую годами никто не замечал: Zabbix или Alertmanager продолжают дёргать API, получают ошибку, но в интерфейсе мониторинга это выглядит как «уведомление отправлено», если никто не смотрит логи. Про саму настройку такого канала с нуля — в статье как установить и настроить алерты в Telegram на VPS.
Отдельная категория — оповещения, которые технически доходят, но в чат или ящик, который никто не открывает: общий канал с полусотней ботов или почта уволившегося сотрудника, которую не перенастроили на общую рассылку. Разбор такого случая — в статье про алерт, который ушёл в чат, который никто не открывал.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверИстёкшие и отозванные токены: где искать протухшие ключи
Если получатель верный, а уведомления всё равно не приходят — следующий подозреваемый: токен или ключ, через который система мониторинга авторизуется у канала доставки. У токенов Telegram-ботов формально нет срока действия, но их отзывают вручную через @BotFather при ротации секретов или компрометации, и старая копия токена в конфиге мониторинга просто перестаёт работать без предупреждения.
Проверить токен бота отдельно от chat_id можно одним запросом:
curl -s "https://api.telegram.org/bot${BOT_TOKEN}/getMe"
Валидный токен вернёт JSON с данными бота ("ok":true, имя, username). Отозванный или опечатанный токен даст {"ok":false,"error_code":401,"description":"Unauthorized"}. Это разделяет две проблемы: если токен рабочий, а сообщение не уходит — дело в chat_id или правах бота; если невалиден — берите в @BotFather актуальный токен и обновляйте его во всех местах, где он захардкожен (на унаследованном сервере это обычно сразу конфиг Zabbix, кастомный bash-скрипт и переменная окружения systemd-юнита).
Для webhook-интеграций (Slack, Discord, кастомные HTTP-приёмники) проблема немного другая: сам URL webhook содержит секретный токен прямо в пути, и такие ссылки протухают при регенерации со стороны получателя — например, если в Slack пересоздали интеграцию или сменили workspace. Проверка — прямой POST-запрос с тестовым телом:
curl -s -o /dev/null -w "%{http_code}\n" -X POST \
-H 'Content-Type: application/json' \
-d '{"text":"Тест доставки webhook от мониторинга"}' \
"https://hooks.slack.com/services/OLD/WEBHOOK/URL"
Код 404 или 410 Gone означает, что webhook отозван — конфиг мониторинга ссылается на несуществующий адрес. Код 200 с реальным сообщением в целевом канале подтверждает, что этот кусок цепочки жив.
Проверьте и SMTP-креды, если оповещения идут через почту: устаревший пароль ящика после плановой ротации приведёт к тому, что релей будет копить письма в очереди или отбрасывать их с кодом 535 Authentication failed — это видно в mail.log или /var/log/exim4/mainlog в зависимости от MTA.
Забытые правила подавления: silence и mute, о которых никто не помнит
Даже если получатель верный и токен живой, алерт может не дойти по третьей причине, которая специфична именно для унаследованных систем: кто-то давно поставил правило подавления (silence в Alertmanager, maintenance period в Zabbix, mute в Grafana) — и забыл его снять. В отличие от протухшего токена, silence не выдаёт никакой ошибки: с точки зрения системы всё работает штатно, просто конкретное правило сейчас намеренно не уведомляет.
Список активных silence в Alertmanager смотрится через amtool или напрямую через API:
amtool silence query --alertmanager.url=http://localhost:9093
ID Matchers Ends At Created By
a1b2c3d4-e5f6-7890-abcd-ef1234567890 service=~"legacy-.*" 2099-12-31 23:59:59 UTC admin@old-domain.ru
Обратите внимание на поле Ends At — дата в далёком будущем (частый результат API-запроса с некорректным TTL или скопированного не глядя шаблона) делает silence фактически бессрочным. Матчер service=~"legacy-.*" в примере выше — это regex, который может случайно захватывать больше сервисов, чем задумывалось, включая те, что появились уже после создания правила.
В Zabbix эквивалент — периоды обслуживания (Data collection → Maintenance), которые тоже иногда создаются «до отдельного уведомления» и остаются активными годами:
SELECT name, active_since, active_till, FROM_UNIXTIME(active_till)
FROM maintenances
WHERE active_till > UNIX_TIMESTAMP();
Если active_till указывает на дату на несколько лет вперёд — это почти гарантированно забытое правило, а не осознанное продление. Уберите его и пронаблюдайте, не начнут ли внезапно сыпаться исторические проблемы, которые всё это время маскировались.
В Grafana Alerting похожая механика называется Mute Timings и Silences, доступна в разделе Alerting → Silences. Проверьте там же вкладку с истёкшими правилами — Grafana хранит и завершённые silence, что удобно для восстановления истории: если алерт замолчал ровно в момент создания какого-то silence, это прямая улика.
Отдельная категория — подавление на уровне приложения, а не системы мониторинга: скрипт-обёртка вокруг curl-запроса к Telegram, в который кто-то добавил if [ "$MAINTENANCE_MODE" = "true" ] для планового окна работ и забыл снять флаг после. Такое не видно ни в одном интерфейсе мониторинга — искать нужно прямым чтением скриптов, вызываемых из cron или hook'ов алертменеджера, включая те, что запускаются по расписанию, о котором никто уже не помнит.
Сквозная проверка: от события до реального уведомления
Проверка каждого звена по отдельности снижает список подозреваемых, но не заменяет проверку цепочки целиком — комбинация формально исправных звеньев иногда всё равно не работает вместе (правильный chat_id, но у бота нет прав писать в конкретную тему форума внутри супергруппы). Надёжный способ убедиться — вызвать реальное событие и проследить его от начала до собственного телефона.
Самый честный тест — не отправка сообщения напрямую через API бота (это проверяет только канал доставки, а не цепочку детекции), а провокация настоящего срабатывания правила. Например, временно снизьте порог алерта на диске до заведомо ложного:
# Zabbix: временно меняем триггер через zabbix_sender с заведомо тревожным значением
zabbix_sender -z 127.0.0.1 -s "web-01" -k vfs.fs.size[/,pfree] -o 1
# Prometheus + Alertmanager: проверяем доставку без правки правил —
# отправляем тестовый алерт напрямую в Alertmanager API
curl -s -X POST http://localhost:9093/api/v2/alerts -H "Content-Type: application/json" -d '[{
"labels": {"alertname": "TestDeliveryCheck", "severity": "critical", "service": "test"},
"annotations": {"summary": "Ручная проверка доставки, можно игнорировать"},
"startsAt": "'$(date -u +%Y-%m-%dT%H:%M:%S.000Z)'"
}]'
Этот способ ценнее прямого теста бота именно потому, что проходит через реальный маршрут: Alertmanager сам решает, к какому receiver относится алерт по label'ам, проверяет, не попадает ли он под активный silence, и только потом пытается доставить. Если тестовый алерт не пришёл — смотрите логи самого Alertmanager (journalctl -u alertmanager -n 100), а не гадайте.
Зафиксируйте результат теста письменно: дата, кто проверял, сколько заняла доставка от триггера до появления сообщения. Это основа для следующего пункта — регулярной проверки, а не разовая справка для отчёта. Про то, как превратить разовый тест в системную привычку, — в статье учебная тревога раз в квартал, а про то, что мониторинг может замолчать целиком, включая сам факт своей поломки, — в статье проверка мониторинга на живучесть.
Восстанавливаем доставку и наводим порядок в конфигурации
После того как найдены обрывы, чинить нужно системно, а не по одному — иначе через полгода вы окажетесь в той же точке, только уже как автор проблемы:
- Актуализируйте список получателей. Замените личные email и Telegram-аккаунты на групповые: чат «Алерты» с несколькими администраторами вместо личных чатов, адрес вида
alerts@yourdomain.comс несколькими подписчиками вместо ящика конкретного человека. Личный получатель — гарантированная точка отказа при следующей смене кадров. - Вынесите секреты из кода в один источник правды. Если токен захардкожен в трёх скриптах, обновление одного из них после ротации снова создаст рассинхрон. Переменные окружения через systemd
EnvironmentFile=или отдельный секрет-файл с правами600— минимальный уровень гигиены:
# /etc/systemd/system/alert-forwarder.service
[Service]
EnvironmentFile=/etc/alert-forwarder/secrets.env
ExecStart=/usr/local/bin/alert-forwarder
- Снимите все бессрочные silence и maintenance-периоды без объяснимой причины. Если правило действительно нужно держать долго — задокументируйте причину прямо в комментарии к нему, а не полагайтесь на память.
- Добавьте резервный канал доставки. Один канал — одна точка отказа. Связка «основной канал — Telegram, резервный — email» снижает риск полной тишины при обрыве одного из них; в Alertmanager это решается через несколько
receiversсcontinue: trueв маршрутизации. - Настройте dead man's switch — внешний сервис (например, healthchecks.io или cron-скрипт на другом сервере), который ждёт heartbeat от мониторинга и сам поднимает тревогу, если тот не пришёл. Это единственный способ узнать о падении самого мониторинга, а не только сервисов под его наблюдением.
- Запланируйте повторную сквозную проверку через квартал, а не только сейчас после ремонта. Список получателей и токенов протухает снова тем же способом — через увольнения, ребрендинги и ротацию секретов, о которых команда мониторинга не узнаёт автоматически.
Если после ремонта конкретных каналов вы обнаружили, что старых, неактуальных или бесполезно шумных правил в системе накопилось много — это повод не просто починить доставку, а провести полную ревизию набора алертов: какие давно никого не касаются, а какие давно пора ужесточить.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Как быстро понять, что алерты вообще не доходят, не разбирая всю конфигурацию?
Отправьте тестовый алерт по каждому активному каналу и засеките факт получения. Это быстрее построчного вычитывания конфига и сразу показывает, какие каналы рабочие — дальше разбирать нужно только сломанные.
Стоит ли доверять логам мониторинга, если там написано «отправлено успешно»?
Не всегда. Zabbix и другие системы часто фиксируют успех на уровне «HTTP-запрос прошёл без сетевой ошибки», а не «получатель реально увидел сообщение». Ошибка 403 от Telegram из-за удалённого бота или 200 OK от релея, который потом уронит письмо в спам, в логе может не отличаться от настоящей доставки — проверяйте появление сообщения у получателя, а не статус в логе.
Можно ли автоматизировать поиск протухших получателей и токенов?
Частично: периодический скрипт, который раз в неделю дёргает getMe для ботов и делает пробный POST на webhook-адреса, ловит большинство протуханий раньше инцидента. Полностью убрать ручную проверку не выйдет — забытый silence или неверный chat_id внутри супергруппы такой скрипт не всегда заметит.
Несколько правил подавления, непонятно, какое актуально, а какое забыто — как разобраться?
Для каждого найдите автора или дату создания (в Alertmanager — поле createdBy, в Zabbix — аудит-лог Reports → Audit log) и свяжите с конкретным событием — работами, миграцией, тестовым стендом. Если связать не удаётся, а правило живёт больше пары недель без основания — это забытая настройка.
Пересобирать всю конфигурацию оповещений или точечно чинить обрывы?
Зависит от масштаба. Один сломанный канал из трёх — точечный ремонт. Протухший токен, забытый silence и адрес уволившегося сотрудника одновременно — признак того, что конфигурацию давно не пересматривали системно, и разумнее один раз навести порядок, чем чинить по симптому каждые пару месяцев.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →