Войти в платформу

Мониторинг PostgreSQL: почему алерт молчит, когда база упала

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

Ловушка 1. Остановленный контейнер исчезает из метрик

Классическая схема мониторинга Docker — cAdvisor плюс Prometheus-совместимое хранилище. Правило «контейнер не работает» обычно пишут через время последнего появления контейнера или через его CPU. Проблема в том, что cAdvisor отдаёт метрики только по работающим контейнерам. Контейнер остановился — и его ряды не обнулились, а исчезли.

На одном из серверов контейнер PostgreSQL стоял полтора дня. Дашборд был пустым, алерта не было: правилу не с чем было сравнивать. Пустая панель в Grafana выглядит как «тут ничего не настроено», а не как «база лежит», поэтому глазами это тоже легко пропустить.

Как решили. Агент раз в минуту снимает состояние всех контейнеров, включая остановленные (аналог docker ps -a), и отдаёт его отдельной метрикой со статусом: running, exited, dead, restarting, paused. Правило срабатывает, если контейнер с образом postgres (а также postgis, timescaledb, bitnami) пять минут находится не в running. Задачи Docker Swarm пропускаем: там остановленные копии — это история перезапусков, а не авария.

Ловушка 2. Служба остановлена, а база работает

Обратная ситуация — ложная тревога. На Windows-сервере служба PostgreSQL (сборка для 1С, тип запуска «Автоматически») числилась остановленной, а в системе работали два десятка процессов postgres. СУБД запустили не через службу — вручную или скриптом. Правило «служба с автозапуском не работает» сработало бы на живой базе.

Ложные критические алерты опасны не сами по себе: после двух-трёх таких сообщений дежурный перестаёт читать канал, и настоящая авария тонет в шуме.

Как решили. Правило «служба остановлена» теперь молчит, пока на сервере есть процессы postgres. На дашборде рядом с загрузкой CPU выведено число процессов PostgreSQL — расхождение «служба stopped, процессов 20» видно сразу.

Ловушка 3. Чужой экспортёр отвечает вместо вашего

Самый коварный случай. После перезагрузки сервера стандартный порт 9100 первым занял дистрибутивный prometheus-node-exporter, установленный кем-то ранее. Наш экспортёр упал с «address already in use», systemd перезапустил его пять раз за секунду, упёрся в лимит перезапусков и оставил юнит в failed навсегда.

Сборщик метрик при этом продолжал опрашивать порт 9100 и получал ответ — от чужого экспортёра. Метрики хоста шли, up был равен 1, всё зелёное. А дополнительные ряды, которые наш экспортёр собирал из файлов (доступность устройств, метрики 1С), исчезли молча.

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

Общий урок: алерт на значение не ловит отсутствие

Выражение вида probe_success == 0 или pg_up == 0 срабатывает, только когда ряд есть и равен нулю. Если ряда нет, результат запроса пустой, и правило считает, что всё в порядке. В PromQL для этого есть absent() и absent_over_time(), но их приходится писать на каждый ряд вручную, и при переносе сервиса на другой хост они дают ложные срабатывания. Надёжнее держать явный список «что должно быть» и сравнивать с ним фактические данные.

Что проверить у себя

— Остановите тестовый контейнер с базой: появится ли алерт, а не пустая панель?

— Есть ли у вас правило на отсутствие данных, а не только на нулевое значение — для каждого критичного экспортёра и пробы?

— Сверяет ли правило статуса службы фактические процессы СУБД? Запущенная вручную база не должна давать критический алерт.

— Кто на самом деле слушает порт вашего экспортёра: ss -ltnp | grep 9100 на Linux, netstat -ano | findstr 9100 на Windows. Совпадает ли процесс с ожидаемым?

— Сколько раз systemd перезапустит ваш агент: проверьте StartLimitIntervalSec, StartLimitBurst и RestartSec. По умолчанию после пяти неудач за 10 секунд юнит остаётся в failed.

— Различает ли дашборд «нет данных» и «всё в порядке»? Пустая панель должна выглядеть как проблема.

— Есть ли проверка, что сама база отвечает на запросы, а не только что жив процесс или контейнер?

Как это сделано в Voltir

Состояние служб PostgreSQL на Windows (включая сборки для 1С) и контейнеров Docker с образом postgres агент Voltir видит без настройки; алерты «служба остановлена» и «контейнер не работает» включены сразу. Для ICMP-устройств, SNMP и своих HTTP-целей работают правила «настроено, но данных нет».

← Все новости