Найти в Дзене
Rebrain

Разбираем «дребезг» триггеров

Это классическая проблема flappy alerts. Давайте разбираться. Zabbix увидел значение выше порога — создал проблему. Через минуту значение упало — закрыл. Еще через 30 секунд снова выше — открыл. Со стороны мониторинга это выглядит как бессмысленная нагрузка на базу и нервы. Проблема: триггер срабатывает на каждый чих, потому что у него нет «буферной зоны». Гистерезис — это разные условия для открытия и закрытия проблемы. Простой пример: Между 70% и 90% — серая зона. Там ничего не происходит. Сервер может спокойно дышать, а админ — спать. {Template OS Linux:system.cpu.util[,idle].last()} < 10 {Template OS Linux:system.cpu.util[,idle].last()} < 10 and {Template OS Linux:system.cpu.util[,idle].prev()} < 15 Zabbix не тупит — он помнит предыдущее значение. Мы используем `.prev()` как триггер восстановления. Допустим, у вас высоконагруженная система, и кратковременные пики до 95% — норма. Но если CPU валится в пол на 5 минут — это уже беда. min({Template OS Linux:system.cpu.util[,idle].avg
Оглавление
Кейс: 2:43 ночи. Телефон вибрирует. Открываю — «CRIT: CPU на веб-сервере 92%». Пока тер глаза, пришло еще 3 сообщения. «OK: CPU 48%», снова «CRIT: 89%», «OK: 51%». Утром смотришь историю — сервер даже не крякнул. Просто процесс сбора метрик совпал с пиком.
Кейс: 2:43 ночи. Телефон вибрирует. Открываю — «CRIT: CPU на веб-сервере 92%». Пока тер глаза, пришло еще 3 сообщения. «OK: CPU 48%», снова «CRIT: 89%», «OK: 51%». Утром смотришь историю — сервер даже не крякнул. Просто процесс сбора метрик совпал с пиком.

Это классическая проблема flappy alerts. Давайте разбираться.

Почему это вообще происходит? 🤔

Zabbix увидел значение выше порога — создал проблему. Через минуту значение упало — закрыл. Еще через 30 секунд снова выше — открыл. Со стороны мониторинга это выглядит как бессмысленная нагрузка на базу и нервы.

Проблема: триггер срабатывает на каждый чих, потому что у него нет «буферной зоны».

Решение: добавляем гистерезис / hysteresis

Гистерезис — это разные условия для открытия и закрытия проблемы.

Простой пример:

  • Открываем проблему: CPU > 90%
  • Закрываем проблему: CPU < 70%

Между 70% и 90% — серая зона. Там ничего не происходит. Сервер может спокойно дышать, а админ — спать.

Как это выглядит в Zabbix (код)

  • Триггер без гистерезиса (боль):
{Template OS Linux:system.cpu.util[,idle].last()} < 10

  • Триггер с гистерезисом (кайф):
{Template OS Linux:system.cpu.util[,idle].last()} < 10
and
{Template OS Linux:system.cpu.util[,idle].prev()} < 15

Что тут происходит?

  • Проблема возникнет, если текущее значение idle < 10% (CPU > 90%)
  • Проблема закроется, только когда предыдущее значение idle > 15% (CPU < 85%)

Zabbix не тупит — он помнит предыдущее значение. Мы используем `.prev()` как триггер восстановления.

Защита от кратковременных скачков

Допустим, у вас высоконагруженная система, и кратковременные пики до 95% — норма. Но если CPU валится в пол на 5 минут — это уже беда.

min({Template OS Linux:system.cpu.util[,idle].avg(5m)}, 5) < 10

Проблема — только если минимальное значение idle за последние 5 минут было ниже 10%. Всплески на 10 секунд игнорируются.

Живой пример из конфига

Вот как выглядит правильный триггер для загрузки CPU в production:

Имя: Высокая загрузка CPU на {HOST.NAME}
Выражение:
last(/Linux by Zabbix agent/system.cpu.util[,idle]) < {$CPU_CRIT}
and
min(/Linux by Zabbix agent/system.cpu.util[,idle], 5m) < {$CPU_RECOVER}
{$CPU_CRIT} = 10 (CPU > 90%)
{$CPU_RECOVER} = 20 (CPU < 80%)

Мы используем макросы, чтобы не переписывать триггеры под каждую железку. Нагруженному БД-серверу можно подкрутить пороги, не отвязывая шаблон.

Зависимости триггеров

Допустим, упал сам сервер. Zabbix честно создаст проблемы:

  • Хост недоступен по ICMP
  • Nginx не отвечает
  • PostgreSQL не отвечает
  • Диски не читаются

Дежурный получает 4 уведомления об одной проблеме.

Лечится зависимостями: создаем триггер «Хост недоступен по ICMP» и делаем так, чтобы триггеры сервисов зависели от него.

В конфигурации триггера Nginx:

Тип: Зависимость от
Выражение: {Host:icmpping.last()} = 0

Если пинга нет — Zabbix молчит по остальным триггерам. Упал сервер, а не Nginx. Не плодим сущности.

Резюме

-2

P.S. Код из поста можно копировать. Замените макросы под свои реалии.