Коротко:
- Усталость от уведомлений возникает не из-за количества метрик, а из-за плохо настроенной маршрутизации и отсутствия дедупликации.
- Первый шаг - аудит: посмотреть, сколько сработавших правил за последние 30 дней не привели ни к одному действию дежурного.
- Grouping и inhibition rules в Alertmanager убирают большую часть шума без изменения самих правил Prometheus.
- В PagerDuty дедупликация работает через Event Rules и Service-level deduplication key - без этого каждый повтор создает новый инцидент.
- Качество on-call мониторинга измеряется не количеством алертов, а долей тех, что потребовали реального действия.
Откуда берется шум
Представьте: дежурный получает 40 уведомлений за ночь. Из них 35 - это один и тот же упавший под, который Kubernetes перезапустил через 10 секунд. Три - предупреждения о высоком CPU, которые ушли сами. Одно - реальная проблема с базой данных. И одно - тест, который кто-то забыл отключить.
Через неделю такого режима дежурный начинает игнорировать уведомления. Не потому что ленится, а потому что мозг адаптируется к сигналам, которые не требуют действия. Это и есть alert fatigue - состояние, при котором важный инцидент тонет в потоке незначимых срабатываний.
Проблема почти никогда не в самих правилах Prometheus. Правила могут быть написаны корректно. Проблема в том, что между метрикой и звонком дежурному нет ни одного фильтра: нет группировки, нет подавления зависимых сигналов, нет дедупликации на уровне PagerDuty.
Аудит перед настройкой: что смотреть
Прежде чем что-то менять, нужно понять, где именно теряется качество. Хороший способ - выгрузить историю срабатываний за последние 30 дней и посмотреть на три вещи.
Actionability rate - доля уведомлений, после которых дежурный что-то сделал. Если она ниже 50%, система генерирует больше шума, чем сигнала. В здоровой системе этот показатель должен быть выше 80%.
Топ повторяющихся правил. Обычно 20% правил дают 80% срабатываний. Именно с ними нужно работать в первую очередь - либо поднять порог, либо добавить for-задержку, либо настроить inhibition.
Время до первого действия. Если дежурный в среднем реагирует через 20 минут после получения уведомления, это сигнал: либо уведомления приходят ночью и человек не успевает, либо он перестал доверять системе и проверяет, не уйдет ли само.
Эти данные можно получить из Alertmanager API (/api/v2/alerts) или из истории инцидентов в PagerDuty через Analytics раздел.
Настройка алертов Prometheus: for, labels и severity
Большинство ложных срабатываний можно убрать еще на уровне правил, не трогая Alertmanager.
Параметр for задает минимальную продолжительность состояния до отправки уведомления. Без него правило срабатывает на любой кратковременный всплеск.
- alert: HighCPU
expr: rate(container_cpu_usage_seconds_total[5m]) > 0.9
for: 10m
labels:
severity: warning
annotations:
summary: "CPU выше 90% на {{ $labels.pod }}"Десять минут - разумный порог для предупреждения о CPU. Если проблема ушла сама за 9 минут, дежурный не получит ничего. Для критических ситуаций - например, сервис полностью недоступен - for: 1m или даже for: 30s оправданы.
Метки severity и team - не просто документация. Они управляют маршрутизацией в Alertmanager. Если все правила имеют одинаковый severity или вообще не имеют его, routing tree работает вхолостую.
Хорошая практика - три уровня: critical (будит ночью), warning (приходит в Slack, не звонит), info (только в дашборд, без уведомлений). Большинство команд используют два уровня и отправляют все в PagerDuty - отсюда и шум.
Alertmanager routing: дерево маршрутов без хаоса
Alertmanager получает все сигналы от Prometheus и решает: кому отправить, когда, в каком виде и нужно ли вообще. Ключевые механизмы - это route, group_by, inhibit_rules и receivers.
Группировка
Без группировки каждое срабатывание - отдельное сообщение. С группировкой Alertmanager собирает похожие события в один пакет и отправляет их вместе.
route:
group_by: ['alertname', 'cluster', 'service']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: 'slack-warnings'
routes:
- match:
severity: critical
receiver: 'pagerduty-critical'
group_wait: 10sgroup_wait - сколько ждать перед первой отправкой, чтобы собрать связанные события. group_interval - как часто отправлять обновления по уже открытой группе. repeat_interval - через сколько повторить, если проблема не решена.
Параметр repeat_interval: 4h для предупреждений - разумный минимум. Если его не выставить или оставить значение по умолчанию (1h), дежурный будет получать одно и то же каждый час.
Inhibition rules
Это один из самых недооцененных инструментов. Inhibition позволяет подавить одни уведомления, если уже активно другое - более высокоуровневое.
Классический пример: нода упала. Prometheus начинает генерировать десятки сигналов - недоступны поды, растет latency, падают health checks. Но все это - следствие одного события. Если настроить inhibition, дежурный получит только один сигнал: нода недоступна.
inhibit_rules:
- source_match:
severity: 'critical'
alertname: 'NodeDown'
target_match:
severity: 'warning'
equal: ['cluster', 'node']Здесь: если активен NodeDown с severity: critical для конкретного узла, все предупреждения с тем же cluster и node подавляются. Дежурный видит одну проблему вместо двадцати.
Inhibition работает только для активных алертов - как только источник разрешится, подавленные снова станут видимы. Это важно: ничего не теряется, просто приоритизируется.
Маршрутизация по команде
Если несколько команд используют один Prometheus, имеет смысл разделить маршруты по метке team. Тогда backend-команда не получает уведомления о проблемах с фронтом, и наоборот.
routes:
- match:
team: backend
receiver: 'pagerduty-backend'
- match:
team: frontend
receiver: 'slack-frontend'
- match:
team: infra
receiver: 'pagerduty-infra'Это снижает шум для каждой конкретной команды и повышает релевантность: дежурный видит только то, за что отвечает.
PagerDuty дедупликация: как не плодить инциденты
Даже при хорошо настроенном Alertmanager PagerDuty может создавать дублирующие инциденты, если не настроена дедупликация на его стороне.
PagerDuty использует поле dedup_key (в Events API v2) для определения, является ли событие новым инцидентом или обновлением существующего. Если Alertmanager отправляет одно и то же событие несколько раз без явного dedup_key, каждый раз создается новый инцидент.
При интеграции через Alertmanager receiver для PagerDuty dedup_key формируется автоматически на основе группы алертов. Но если вы используете прямую интеграцию или вебхуки, нужно явно задавать ключ:
{
"routing_key": "YOUR_INTEGRATION_KEY",
"dedup_key": "prod-payment-service-high-error-rate",
"event_action": "trigger",
"payload": {
"summary": "Error rate выше 5% на payment-service",
"severity": "critical",
"source": "prometheus"
}
}Хороший dedup_key - это детерминированная строка, которая одинакова для всех повторов одной и той же проблемы. Обычно это комбинация имени сервиса, типа проблемы и окружения: prod-payment-high-error-rate.
Event Rules в PagerDuty
Event Rules (в новом интерфейсе - Event Orchestration) позволяют фильтровать и трансформировать события до создания инцидента. Это второй рубеж фильтрации после Alertmanager.
Что можно сделать через Event Rules:
- Подавить события с определенными метками в нерабочее время (например, предупреждения о медленных фоновых задачах).
- Понизить severity для известных нестабильных сервисов во время планового обслуживания.
- Направить события в нужный сервис на основе содержимого payload.
- Автоматически добавить runbook-ссылку к инциденту.
Это особенно полезно, когда несколько источников (Prometheus, Datadog, CloudWatch) отправляют события в один PagerDuty аккаунт - правила позволяют нормализовать их без изменения каждого источника отдельно.
Silence и maintenance windows
Плановые работы - отдельная причина шума. Если команда деплоит в пятницу вечером и не выставляет silence, дежурный получает поток уведомлений о нормальных перезапусках подов.
В Alertmanager silence создается через UI или API:
amtool silence add \
alertname="PodRestarting" \
namespace="production" \
--duration=2h \
--comment="Плановый деплой payment-service"В PagerDuty аналогичный механизм - Maintenance Windows. Их можно создавать заранее и привязывать к конкретным сервисам. Во время окна инциденты создаются, но не эскалируются и не будят дежурного.
Хорошая практика - добавить создание silence в CI/CD пайплайн. Перед деплоем пайплайн автоматически выставляет silence на 30 минут для затронутых сервисов. После успешного деплоя silence снимается.
Типичные ошибки при настройке
| Ошибка | Последствие | Как исправить |
|---|---|---|
Нет параметра for в правилах | Срабатывание на любой кратковременный всплеск | Добавить for: 5m или for: 10m для предупреждений |
Все правила с severity: critical | Дежурный не может приоритизировать | Ввести три уровня и отправлять в PagerDuty только critical |
| Нет inhibition rules | Одна проблема генерирует десятки уведомлений | Настроить подавление зависимых сигналов |
repeat_interval не выставлен или слишком мал | Одно и то же уведомление каждый час | Установить repeat_interval: 4h для warning, 2h для critical |
| Нет dedup_key в PagerDuty | Каждый повтор создает новый инцидент | Задать детерминированный dedup_key на основе сервиса и типа проблемы |
| Silence не используется при деплоях | Шум во время плановых работ | Автоматизировать создание silence в CI/CD |
Метрики качества on-call мониторинга
Настройка - это не разовое действие. Нужно регулярно смотреть на несколько показателей, чтобы понимать, улучшается ли ситуация.
Actionability rate - главная метрика. Считается как отношение инцидентов, где дежурный выполнил хоть какое-то действие, к общему числу уведомлений. Цель - выше 80%.
Mean time to acknowledge (MTTA) - среднее время до подтверждения инцидента. Если оно растет, дежурный либо перегружен, либо перестал доверять системе.
Noise ratio - доля уведомлений, которые разрешились сами без вмешательства. Хорошее значение - ниже 10%. Если выше - нужно пересматривать пороги или добавлять задержки.
Pages per shift - количество ночных звонков за одно дежурство. Более трех звонков за ночь - это уже серьезная нагрузка, которая влияет на качество работы на следующий день.
Вакансии для DevOps-инженеров
Все эти метрики можно собрать из PagerDuty Analytics или построить дашборд в Grafana на основе данных Alertmanager.
Чеклист: что проверить перед следующим дежурством
- Все правила Prometheus имеют параметр
forс разумным значением. - Используются три уровня severity, в PagerDuty попадает только critical.
- Настроены inhibition rules для зависимых сигналов (нода, кластер, база данных).
- Выставлены
group_by,group_waitиrepeat_intervalв Alertmanager. - В PagerDuty настроен dedup_key для всех интеграций.
- Есть процедура создания silence при плановых деплоях.
- Настроены Event Rules или Event Orchestration в PagerDuty для фильтрации второго уровня.
- Команда регулярно (раз в месяц) проводит ревью правил и удаляет неактивные или неинформативные.
- Actionability rate отслеживается и видна в дашборде.
- Каждый новый алерт проходит ревью: что именно он должен сообщить дежурному и что тот должен сделать.
Как проверить правило до того, как оно попадет в продакшен
Одна из причин накопления шума - правила добавляются без проверки реального поведения. Инженер пишет выражение, смотрит, что оно синтаксически корректно, и отправляет в репозиторий. Через неделю выясняется, что правило срабатывает каждые 15 минут на нормальный трафик.
Перед тем как добавить новое правило, стоит пройти три шага.
Шаг 1: проверить выражение в Prometheus UI. Вкладка Graph показывает, как менялось значение метрики за последние часы или дни. Если выражение уже сейчас возвращает ненулевое значение на стабильной системе, порог выбран неверно.
Шаг 2: оценить частоту исторических пересечений порога. Если за последние 7 дней условие выполнялось 50 раз, а инцидентов было 2, правило будет генерировать шум. Нужно либо поднять порог, либо увеличить for.
Шаг 3: сформулировать runbook до публикации. Если нельзя ответить на вопрос «что именно должен сделать дежурный, получив это уведомление», правило не готово. Уведомление без понятного действия - это шум по определению.
Этот процесс можно формализовать через шаблон pull request для изменений в правилах: поле «ожидаемая частота срабатываний» и поле «действие дежурного» делают ревью быстрее и снижают риск добавления проблемных правил.
Разница между симптомным и причинным подходом к правилам
Большинство команд пишут правила на уровне причин: CPU выше порога, память заканчивается, диск заполнен. Это удобно, потому что метрики очевидны. Но такой подход дает много шума: причины могут меняться без влияния на пользователей.
Симптомный подход фокусируется на том, что видит пользователь: высокая задержка, рост ошибок, недоступность эндпоинта. Правила на уровне симптомов срабатывают реже, но каждое срабатывание действительно требует внимания.
| Тип правила | Пример | Частота ложных срабатываний | Когда использовать |
|---|---|---|---|
| Причинное | CPU выше 90% | Высокая | Для capacity planning, не для on-call |
| Причинное | Диск заполнен на 85% | Средняя | Предупреждение заранее, не критичный звонок |
| Симптомное | HTTP 5xx выше 1% за 5 минут | Низкая | Основной сигнал для дежурного |
| Симптомное | p99 latency выше 2 секунд | Низкая | Основной сигнал для дежурного |
| Симптомное | Сервис недоступен более 30 секунд | Очень низкая | Критичный звонок ночью |
Хорошая система мониторинга строится так: симптомные правила будят дежурного, причинные правила помогают разобраться в причине уже после того, как инцидент открыт. Причинные метрики - это инструмент диагностики, а не триггер для звонка.
Практический ориентир: если правило срабатывает, но пользователи ничего не замечают, это правило не должно попадать в PagerDuty. Переместите его в Slack или только в дашборд. Оставьте ночные звонки для ситуаций, которые реально влияют на работу сервиса прямо сейчас.
Работа с унаследованными правилами: как разобрать накопленный долг
Во многих командах правила копились годами. Кто-то добавил правило под конкретный инцидент, потом забыл удалить. Кто-то скопировал набор из открытого репозитория и не адаптировал под свою систему. В итоге в конфигурации десятки правил, половина из которых никто не понимает.
Разбирать такой долг проще поэтапно, а не за один раз.
Первый этап: инвентаризация. Выгрузить все активные правила и для каждого проверить: когда последний раз срабатывало, есть ли у него annotations с описанием и runbook, есть ли owner - метка команды или сервиса.
Второй этап: категоризация. Разделить правила на три группы: активно используемые и понятные, активные но без понятного действия, давно не срабатывавшие. Третья группа - первые кандидаты на удаление или перевод в silent режим.
Третий этап: постепенная чистка. Не удалять сразу - сначала перевести подозрительные правила в severity: info и наблюдать две недели. Если никто не заметил отсутствия уведомлений, правило можно убирать.
Важно договориться внутри команды: каждое новое правило добавляется с явным owner и датой ревью. Это не бюрократия, а способ не накапливать новый долг, пока разбираете старый.
FAQ
Что такое alert fatigue простыми словами?
Это состояние, когда дежурный получает так много уведомлений, что перестает реагировать на них осознанно. Мозг привыкает к постоянному потоку сигналов и начинает их игнорировать - в том числе важные. Результат: реальный инцидент остается без внимания.
Чем inhibition rules отличаются от silence в Alertmanager?
Silence - это ручное или автоматическое отключение уведомлений на заданный период. Inhibition - это динамическое подавление: одно активное событие автоматически блокирует другие, связанные с ним. Silence нужен для плановых работ, inhibition - для устранения каскадного шума при инцидентах.
Как понять, что настройка алертов Prometheus работает хорошо?
Главный признак - дежурный реагирует на большинство уведомлений реальным действием. Если actionability rate выше 80%, noise ratio ниже 10% и количество ночных звонков не превышает двух-трех за смену, система настроена адекватно.
Нужна ли дедупликация на уровне PagerDuty, если уже настроен Alertmanager?
Да, нужна. Alertmanager группирует события внутри себя, но если несколько источников отправляют данные напрямую в PagerDuty (например, CloudWatch и Prometheus одновременно), дедупликация на уровне PagerDuty - единственный способ избежать дублирующих инцидентов.
Как часто нужно пересматривать правила?
Минимум раз в месяц - смотреть на правила, которые срабатывали чаще всего, и на те, что не срабатывали ни разу. Первые - кандидаты на повышение порога или добавление задержки. Вторые - возможно, устарели или покрывают несуществующие сценарии.
Что делать, если команда не хочет менять существующие правила?
Начать с Alertmanager, не трогая сами правила Prometheus. Добавить группировку, inhibition и правильные repeat_interval - это уже даст заметный эффект. Параллельно вести статистику: через месяц цифры сами убедят команду пересмотреть пороги.
Итог
Усталость от уведомлений - это не проблема дежурного, а проблема конфигурации. Когда каждый сигнал требует осознанного решения, система работает правильно. Когда дежурный начинает угадывать, стоит ли реагировать, - что-то сломано в пайплайне от метрики до звонка.
Три уровня severity, inhibition rules, правильная группировка в Alertmanager и dedup_key в PagerDuty - это не сложные изменения. Большинство из них занимают несколько часов на внедрение, но кардинально меняют качество дежурств. Дежурный, который доверяет своей системе мониторинга, реагирует быстрее и принимает лучшие решения под давлением.