Проектирование алертов: обнаружение реальных проблем без усталости от алертов
Updated Jul 2026
Проблема усталости от алертов
Усталость от алертов — состояние, при котором дежурные инженеры игнорируют алерты, потому что большинство из них являются ложными срабатываниями — это враг тестирования на основе наблюдаемости. Хорошее проектирование алертов так же важно, как хорошее проектирование тестов. Набор тестов, который выдаёт слишком много ложных срабатываний, начинают игнорировать; система алертинга, которая выдаёт слишком много ложных срабатываний, получает такое же отношение.
Основные принципы проектирования алертов
1. Алертируйте по симптомам, а не по причинам
Алертируйте по тому, что испытывают пользователи, а не по тому, что делает инфраструктура:
| Симптом (хороший алерт) | Причина (плохой алерт) |
|---|---|
| "Error rate > 1% for checkout API" | "CPU > 80% on checkout-pod-3" |
| "p99 latency > 2s for search" | "Memory usage > 90% on search-worker" |
| "Zero orders processed in 5 minutes" | "Database connection pool at 95%" |
Высокий CPU, не вызывающий воздействия на пользователей, не заслуживает алерта. Пул соединений с базой данных на 95% может быть совершенно нормальным под нагрузкой. Фокусируйтесь на том, что видит пользователь.
2. Используйте алерты с множественным окном и множественной скоростью сгорания
Вместо одного порога используйте многоуровневый подход, который ловит как быстрое сгорание (внезапный сбой), так и медленное сгорание (постепенную деградацию):
| Тип алерта | Короткое окно | Длинное окно | В течение | Серьёзность |
|---|---|---|---|---|
| Быстрое сгорание | 5 мин | 1 час | 2 мин | Критический (вызов) |
| Умеренное | 15 мин | 3 часа | 5 мин | Высокий (вызов) |
| Медленное сгорание | 30 мин | 6 часов | 15 мин | Предупреждение (тикет) |
Требование двойного окна снижает ложные срабатывания: кратковременный всплеск срабатывает в коротком окне, но не в длинном, поэтому алерт не активируется.
3. Каждый алерт должен иметь runbook
Алерт без runbook — это вопрос без ответа. Runbook должен включать:
## Runbook: Checkout Error Rate > SLO
### What this alert means
The checkout service error rate has exceeded the SLO burn rate for the
specified window, indicating a potential reliability issue.
### Impact
Users may be unable to complete purchases. Revenue impact is proportional
to the duration and severity.
### Diagnosis steps
1. Check the error rate dashboard: [link]
2. Check recent deployments: `kubectl rollout history deployment/checkout`
3. Check dependency health: [payment-service dashboard link]
4. Check logs: `query: service=checkout level=error | last 15m`
### Common causes and fixes
- **Recent deployment**: Roll back with `kubectl rollout undo deployment/checkout`
- **Payment provider outage**: Enable fallback payment processor
- **Database connection exhaustion**: Scale up connection pool
- **Rate limiting from downstream**: Check rate limit headers
### Escalation
If not resolved within 30 minutes, escalate to:
- #checkout-team Slack channel
- Checkout team lead (page)
4. Вызывайте дежурного только для немедленного действия человека
| Необходимое действие | Тип уведомления | Время реакции |
|---|---|---|
| Немедленное вмешательство человека | Вызов (PagerDuty) | Минуты |
| Исправить в течение дня | Тикет (Jira) | Часы |
| Осведомлённость, действий не требуется | Дашборд / еженедельный отчёт | Дни |
Если ответ на вопрос «что должен сделать дежурный?» — «ничего, само разрешится», это не должно быть вызовом.
Проектирование алертов для типичных сценариев
Алерты SLO веб-приложения
# Best practice: multi-burn-rate SLO alerts
groups:
- name: web-app-slo
rules:
- alert: WebAppHighErrorRate_FastBurn
expr: |
(error_ratio_5m > 14.4 * 0.001) and (error_ratio_1h > 14.4 * 0.001)
for: 2m
labels:
severity: critical
annotations:
summary: "Error rate burning budget at 14.4x (2-day exhaustion)"
- alert: WebAppHighErrorRate_SlowBurn
expr: |
(error_ratio_30m > 3 * 0.001) and (error_ratio_6h > 3 * 0.001)
for: 15m
labels:
severity: warning
annotations:
summary: "Error rate burning budget at 3x (10-day exhaustion)"
Истечение сертификата
- alert: CertificateExpiringSoon
expr: |
(cert_expiry_timestamp_seconds - time()) / 86400 < 14
labels:
severity: warning # ticket, not page
annotations:
summary: "TLS certificate expires in {{ $value | humanizeDuration }}"
- alert: CertificateExpiringCritical
expr: |
(cert_expiry_timestamp_seconds - time()) / 86400 < 3
labels:
severity: critical # page -- 3 days is urgent
Сбой деплоя
- alert: DeploymentRollbackDetected
expr: |
kube_deployment_status_observed_generation
!= kube_deployment_metadata_generation
for: 10m
labels:
severity: warning # auto-rollback handled it, but investigate
annotations:
summary: "Deployment {{ $labels.deployment }} appears to have rolled back"
Тестирование алертов
Алерты — это код. Они заслуживают тестирования, как и любой другой код.
Модульное тестирование правил алертов
# test_alert_rules.py
"""
Test Prometheus alerting rules using promtool or programmatic evaluation.
"""
import subprocess
import yaml
def test_fast_burn_alert_fires_on_high_error_rate():
"""Verify the fast-burn alert fires when error rate exceeds 14.4x threshold."""
test_case = {
"interval": "1m",
"input_series": [
{
"series": 'http_requests_total{service="checkout",status="500"}',
"values": "0+10x60" # 10 errors per minute for 60 minutes
},
{
"series": 'http_requests_total{service="checkout",status="200"}',
"values": "0+100x60" # 100 successes per minute
}
],
"alert_rule_test": [
{
"eval_time": "10m",
"alertname": "HighErrorRateFastBurn",
"exp_alerts": [
{"exp_labels": {"severity": "critical", "team": "checkout"}}
]
}
]
}
# Write test file and run promtool
with open("/tmp/alert_test.yaml", "w") as f:
yaml.dump(test_case, f)
result = subprocess.run(
["promtool", "test", "rules", "/tmp/alert_test.yaml"],
capture_output=True, text=True
)
assert result.returncode == 0, f"Alert test failed: {result.stderr}"
Тестирование алертов на основе хаос-экспериментов
Лучший способ протестировать алерты — вызвать условия, которые они обнаруживают:
- Запустите хаос-эксперимент (убейте поды, внедрите задержку)
- Убедитесь, что ожидаемый алерт срабатывает в ожидаемые сроки
- Убедитесь, что ссылка на runbook корректна и runbook актуален
- Убедитесь, что алерт разрешается после завершения хаос-эксперимента
Это естественное расширение учений game day — включите «сработал ли правильный алерт?» как критерий успеха.
Практики гигиены алертов
Еженедельный обзор алертов
Каждую неделю проводите обзор алертов за прошедшую неделю:
| Вопрос | Действие при ответе «Да» |
|---|---|
| Были ли вызовы, не потребовавшие действий? | Понизить до тикета или дашборда |
| Были ли вызовы без подтверждения > 10 мин? | Проверить маршрутизацию и назначение дежурного |
| Было ли > 5 вызовов от одного алерта? | Добавить дедупликацию или увеличить пороги |
| Были ли инциденты, прошедшие незамеченными? | Добавить новый алерт для обнаруженного пробела |
| Были ли алерты, мигающие (срабатывающие/разрешающиеся многократно)? | Добавить гистерезис или увеличить длительность for |
SLO системы алертинга
Да, ваша система алертинга сама должна иметь SLO:
| Метрика | Целевое значение |
|---|---|
| Доля ложных срабатываний | < 20% вызовов |
| Среднее время подтверждения | < 5 минут |
| Соотношение алертов к действиям | > 70% |
| Вызовов за смену дежурного | < 5 |
| Незамеченные инциденты | 0 |
Хорошее проектирование алертов — это непрерывная практика, а не одноразовая настройка. Относитесь к своим алертам с той же строгостью, с какой вы относитесь к набору тестов.