Modern QA2026Проектирование алертов: обнаружение реальных проблем без усталости от алертов
Join

Course06 Observability-Driven Testing

Cutting-edge · Chapter 06

Проектирование алертов: обнаружение реальных проблем без усталости от алертов

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}"

Тестирование алертов на основе хаос-экспериментов

Лучший способ протестировать алерты — вызвать условия, которые они обнаруживают:

  1. Запустите хаос-эксперимент (убейте поды, внедрите задержку)
  2. Убедитесь, что ожидаемый алерт срабатывает в ожидаемые сроки
  3. Убедитесь, что ссылка на runbook корректна и runbook актуален
  4. Убедитесь, что алерт разрешается после завершения хаос-эксперимента

Это естественное расширение учений game day — включите «сработал ли правильный алерт?» как критерий успеха.

Практики гигиены алертов

Еженедельный обзор алертов

Каждую неделю проводите обзор алертов за прошедшую неделю:

Вопрос Действие при ответе «Да»
Были ли вызовы, не потребовавшие действий? Понизить до тикета или дашборда
Были ли вызовы без подтверждения > 10 мин? Проверить маршрутизацию и назначение дежурного
Было ли > 5 вызовов от одного алерта? Добавить дедупликацию или увеличить пороги
Были ли инциденты, прошедшие незамеченными? Добавить новый алерт для обнаруженного пробела
Были ли алерты, мигающие (срабатывающие/разрешающиеся многократно)? Добавить гистерезис или увеличить длительность for

SLO системы алертинга

Да, ваша система алертинга сама должна иметь SLO:

Метрика Целевое значение
Доля ложных срабатываний < 20% вызовов
Среднее время подтверждения < 5 минут
Соотношение алертов к действиям > 70%
Вызовов за смену дежурного < 5
Незамеченные инциденты 0

Хорошее проектирование алертов — это непрерывная практика, а не одноразовая настройка. Относитесь к своим алертам с той же строгостью, с какой вы относитесь к набору тестов.