Мониторинг через Burn Rate: как перестать получать ложные алерты
Почему статические пороги не работают
Наивный подход к мониторингу заключается в настройке статических порогов — например, оповещение при превышении 1% ошибок в течение пяти минут. Это тот подход, который мы рассматривали ранее в статье Prometheus vs Zabbix.
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) > 0.01
for: 5m
Главная проблема такого метода — неспособность одинаково эффективно реагировать на разные типы инцидентов. Статический порог либо игнорирует медленную деградацию, которая постепенно исчерпывает бюджет ошибок, либо «шумит» на кратковременные всплески, не требующие немедленного вмешательства.
Концепция Burn Rate: расчет расхода Error Budget
Практика Google SRE предлагает более гибкий подход: настраивать алерты не на абсолютную долю ошибок, а на скорость расходования бюджета ошибок (Error Budget). Мы используем два временных окна: короткое (для фиксации резких сбоев) и длинное (для выявления плавной деградации).
# Быстрый burn: за 1 час тратим бюджет в 14.4 раза быстрее
# устойчивого темпа — при таком темпе весь месячный бюджет
# сгорит примерно за два дня. Точно достойно пейджа.
- alert: ErrorBudgetBurnFast
expr: |
(
rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) > 14.4 * 0.001
and
rate(http_requests_total{status=~"5.."}[1h]) / rate(http_requests_total[1h]) > 14.4 * 0.001
)
labels:
severity: page
# Медленный burn: за сутки тратим бюджет в 3 раза быстрее устойчивого
# темпа — недостаточно срочно для пейджа, но достаточно, чтобы
# завести тикет и разобраться до конца недели
- alert: ErrorBudgetBurnSlow
expr: |
(
rate(http_requests_total{status=~"5.."}[6h]) / rate(http_requests_total[6h]) > 3 * 0.001
and
rate(http_requests_total{status=~"5.."}[1d]) / rate(http_requests_total[1d]) > 3 * 0.001
)
labels:
severity: ticket
Использование комбинации короткого и длинного окон защищает от ложных срабатываний: короткое окно отсеивает шум, а длинное — позволяет своевременно заметить системные проблемы.
Правильная маршрутизация: не каждый алерт — критический
Важно различать критические инциденты и задачи для бэклога. Используя метку severity, можно настроить маршрутизацию в Alertmanager, чтобы не беспокоить дежурного инженера ночью по пустякам.
route:
routes:
- match:
severity: page
receiver: pagerduty-oncall
repeat_interval: 15m
- match:
severity: ticket
receiver: jira-backlog
repeat_interval: 24h
Основной критерий для severity: page: «Может ли инженер сделать что-то прямо сейчас, чего нельзя отложить до утра?». Если ответ отрицательный, такой алерт должен попадать в систему тикетов.
Группировка уведомлений
Чтобы избежать «шторма алертов», когда один сбой вызывает каскад уведомлений, используйте механизм group_by. Это позволяет сгруппировать связанные события в одно информативное сообщение.
route:
group_by: ['alertname', 'cluster', 'service']
group_wait: 30s # подождать полминуты, вдруг придут связанные алерты
group_interval: 5m # не слать новую группу чаще раза в 5 минут
repeat_interval: 4h # не повторять один и тот же несработавший алерт чаще