Построение иерархии алертов, эскалация, подавление, dependency-aware alerting
«Хороший алертинг — это когда просыпаешься только когда действительно нужно»
Плоский алертинг — все алерты одного уровня.
# ПЛОХО: все алерты critical
- alert: HighCPU
severity: critical # CPU 85%
- alert: ServiceDown
severity: critical # Сервис упал
- alert: DiskLow
severity: critical # Диск 80%Проблемы:
Решение: многоуровневая иерархия с разной срочностью реакции.
| Уровень | Когда | Реакция | Канал |
|---|---|---|---|
| critical | Сервис недоступен или критически деградировал | Немедленно (24/7) | PagerDuty, телефон |
| warning | Проблема, которая может стать критической | В течение часа | Slack, email |
| info | Информация для контекста | Когда удобно | Email, лог |
Critical:
Warning:
Info:
# alerting_rules.yml
groups:
- name: application_alerts
rules:
# Critical
- alert: ServiceDown
expr: up{job="api"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Service {{ $labels.job }} is DOWN"
description: "{{ $labels.instance }} не отвечает более 1 минуты"
runbook_url: "https://wiki/runbooks/service-down"
- alert: HighErrorRate
expr: |
sum by (service) (rate(http_requests_total{status=~"5.."}[5m]))
/
sum by (service) (rate(http_requests_total[5m]))
> 0.10
for: 5m
labels:
severity: critical
annotations:
summary: "High error rate on {{ $labels.service }}"
description: "Error rate is {{ $value | humanizePercentage }}"
# Warning
- alert: HighCPU
expr: |
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
> 80
for: 15m
labels:
severity: warning
annotations:
summary: "High CPU on {{ $labels.instance }}"
description: "CPU usage is {{ $value | humanizePercentage }}"
- alert: HighMemory
expr: |
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes)
/
node_memory_MemTotal_bytes
* 100 > 90
for: 15m
labels:
severity: warning
annotations:
summary: "High memory usage on {{ $labels.instance }}"
description: "Memory usage is {{ $value | humanizePercentage }}"
# Info
- alert: ServerRebooted
expr: changes(node_boot_time_seconds[5m]) > 0
for: 0m
labels:
severity: info
annotations:
summary: "Server {{ $labels.instance }} was rebooted"# alertmanager.yml
global:
smtp_smarthost: 'smtp.example.com:587'
smtp_from: 'alertmanager@example.com'
slack_api_url: 'https://hooks.slack.com/services/XXX/YYY/ZZZ'
pagerduty_url: 'https://events.pagerduty.com/v2/enqueue'
route:
receiver: 'default-receiver'
group_by: ['alertname', 'severity']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
# Critical → PagerDuty + Slack
- match:
severity: critical
receiver: 'pagerduty-critical'
continue: true # Отправить и в Slack тоже
# Warning → Slack
- match:
severity: warning
receiver: 'slack-warnings'
# Info → Email (без уведомлений)
- match:
severity: info
receiver: 'email-info'
group_wait: 5m
group_interval: 1h
receivers:
- name: 'default-receiver'
email_configs:
- to: 'alerts@example.com'
- name: 'pagerduty-critical'
pagerduty_configs:
- service_key: 'your-pagerduty-service-key'
severity: critical
description: '{{ .CommonAnnotations.summary }}'
- name: 'slack-warnings'
slack_configs:
- channel: '#alerts-warning'
send_resolved: true
title: '{{ .CommonAnnotations.summary }}'
text: '{{ .CommonAnnotations.description }}'
- name: 'email-info'
email_configs:
- to: 'info-alerts@example.com'group_by:
group_by: ['alertname', 'severity']Группирует алерты по имени и уровню. Вместо 10 отдельных алертов о высоком CPU — одно уведомление.
continue:
continue: trueОтправляет алерт в следующий маршрут тоже. Critical уйдёт и в PagerDuty, и в Slack.
group_wait:
group_wait: 30s # Для critical
group_wait: 5m # Для infoЖдёт перед отправкой первой группы. Для info — дольше, чтобы собрать больше контекста.
Алерт warning не реагируют — проблема становится critical.
route:
routes:
# Сначала warning в Slack
- match:
severity: warning
receiver: 'slack-warnings'
group_wait: 5m
repeat_interval: 1h
# Если не resolved через 2 часа → эскалация
routes:
- match:
severity: warning
receiver: 'pagerduty-escalated'
group_wait: 1s
repeat_interval: 30m
matchers:
- alertname =~ ".+"Создайте метрику «возраст» алерта:
# Recording rule
- record: alert:pending_duration
expr: time() - alert_start_time_secondsАлерт на эскалацию:
- alert: WarningEscalatedToCritical
expr: alert:pending_duration{severity="warning"} > 7200 # 2 часа
labels:
severity: critical
annotations:
summary: "Warning {{ $labels.alertname }} not resolved for 2 hours"Упали 10 сервисов — 10 алертов. Но причина в одном: база данных.
# inhibit_rules в Alertmanager
inhibit_rules:
# Если БД упала, подавить алерты сервисов
- source_match:
alertname: DatabaseDown
target_match:
alertname: ServiceDown
equal: ['cluster']
# Если critical, подавить warning той же системы
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'instance']Как работает:
- alert: ServiceDown
expr: up{job="api"} == 0
labels:
severity: critical
depends_on: 'database,cache'
annotations:
summary: "Service {{ $labels.job }} is DOWN"
dependencies: "Check database and cache first"alertname="HighCPU", instance="server1"curl -X POST http://alertmanager:9093/api/v2/silences \
-H "Content-Type: application/json" \
-d '{
"matchers": [
{"name": "alertname", "value": "HighCPU"},
{"name": "instance", "value": "server1"}
],
"startsAt": "2026-03-18T10:00:00Z",
"endsAt": "2026-03-18T12:00:00Z",
"createdBy": "admin",
"comment": "Плановое обслуживание"
}'# Документация в README
## Severity Levels
- **critical**: Сервис недоступен. Реакция немедленно 24/7.
- **warning**: Проблема может стать критической. Реакция в течение часа.
- **info**: Информация для контекста. Реакция когда удобно.# Critical: быстро, но не слишком
for: 1m
# Warning: дольше, чтобы избежать ложных срабатываний
for: 15m
# Info: можно сразу
for: 0mannotations:
runbook_url: "https://wiki/runbooks/high-cpu"# Проверка синтаксиса
promtool check rules alerting_rules.yml
# Тестовое срабатывание (вручную создайте условие)# Количество отправленных уведомлений
alertmanager_notifications_total
# Ошибки отправки
alertmanager_notifications_failed_total
# Текущие активные алерты
alertmanager_alerts
# Длительность тишины
alertmanager_silences- alert: AlertmanagerDown
expr: up{job="alertmanager"} == 0
for: 1m
labels:
severity: critical
- alert: AlertmanagerNotificationsFailing
expr: rate(alertmanager_notifications_failed_total[5m]) > 0.1
for: 10m
labels:
severity: warningВ следующей теме вы изучите мониторинг Kubernetes — полный стек метрик для подов, нод и кластера.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.