Настроить алерты на p99 latency spike

ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить алерты на p99 latency spike

1. Цель задачи

Научиться настраивать систему мониторинга и оповещения для критической метрики latency (p99) в production-среде. Развернуть Prometheus для сбора метрик, создать дашборд в Grafana, настроить алерт-правило на превышение p99 latency порога и интегрировать внешнюю систему оповещения PagerDuty. Добиться времени обнаружения пика latency не более 1 минуты с момента его возникновения.

Ключевой результат Работающий алерт, который отправляет уведомление в PagerDuty при превышении p99 latency > 500 мс в течение 1 минуты.


2. Исходные данные

Что нужноОткуда взять
Работающий сервис с HTTP-эндпоинтамиРазвёрнутый pet-проект или любой веб-сервер (Flask/FastAPI/Express)
PrometheusУстановить локально или через Docker
GrafanaУстановить локально или через Docker
PagerDuty (аккаунт и API-токен)Зарегистрироваться на pagerduty.com (free tier)
Экспортёр метрик для сервисаНапример, prometheus_client для Python или OpenTelemetry
Инструмент для генерации нагрузкиwrk, hey, locust или самописный скрипт

Если нет реального сервиса — симулируем:

  1. Разверните минимальное FastAPI-приложение с одним эндпоинтом (/latency), который может отдавать ответ со случайной задержкой (0–1000 мс).
  2. Используйте библиотеку prometheus_client для экспорта гистограммы http_request_duration_seconds.
  3. Запустите локально prometheus.yml, указав target на своё приложение.
  4. Установите Grafana и подключите к Prometheus.

3. Технологический стек

КомпонентИнструментыНазначение
Мониторинг метрикPrometheus + prometheus_clientСбор и хранение метрик latency
ВизуализацияGrafanaДашборды для анализа p99 latency
ОповещениеPagerDuty (Webhook/API)Отправка алертов дежурным инженерам
Тестируемое приложениеFastAPI (или Flask) + uvicornГенерация HTTP latency
Генератор нагрузкиhey / wrk / locustИмитация пользовательского трафика
КонтейнеризацияDocker (опционально)Упрощение развёртывания компонентов

4. Этапы выполнения

Этап 1: Подготовка инфраструктуры и генерация метрик (1–1.5 часа)

Действия

  1. Разверните FastAPI-приложение с эндпоинтом / и /latency. Пример:

    from fastapi import FastAPI
    import random
    import time
    from prometheus_client import Histogram, generate_latest, REGISTRY
    import uvicorn
    
    app = FastAPI()
    LATENCY_HIST = Histogram('http_request_duration_seconds',
                             'HTTP request latency (seconds)',
                             buckets=[0.1, 0.25, 0.5, 1.0, 2.5, 5.0])
    
    @app.get("/")
    async def root():
        return {"status": "ok"}
    
    @app.get("/latency")
    async def latency():
        delay = random.uniform(0, 1.0)  # 0–1000 ms
        time.sleep(delay)
        LATENCY_HIST.observe(delay)
        return {"latency": delay}
    
    @app.get("/metrics")
    async def metrics():
        return generate_latest(REGISTRY)
    
    if __name__ == "__main__":
        uvicorn.run(app, host="0.0.0.0", port=8000)
    
  2. Запустите приложение (python app.py).

  3. Установите Prometheus (через Docker рекомендуемо):

    docker run -d --name prometheus -p 9090:9090 \
      -v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml \
      prom/prometheus
    

    Пример prometheus.yml:

    scrape_configs:
      - job_name: 'fastapi-app'
        static_configs:
          - targets: ['host.docker.internal:8000']  # для Docker Desktop используем host.docker.internal
    
  4. Проверьте, что метрики доступны: http://localhost:9090/graph -> выполните запрос http_request_duration_seconds_count.

  5. Установите Grafana:

    docker run -d --name grafana -p 3000:3000 grafana/grafana
    
  6. В Grafana добавьте Data Source Prometheus (URL = http://localhost:9090).

Ожидаемый результат этапа Prometheus собирает метрики latency с приложения, Grafana подключена к Prometheus.


Этап 2: Создание дашборда для p99 latency (1 час)

Действия

  1. В Grafana создайте новый дашборд (Dashboard → New Dashboard).
  2. Добавьте панель (Panel) типа Stat или Time series.
  3. Настройте запрос для квантиля p99:
    histogram_quantile(0.99,
      sum(rate(http_request_duration_seconds_bucket[1m])) by (le))
    
    • Legend p99 latency
    • Unit seconds (или ms: Custom unit → ms с multiplier 1000)
  4. Добавьте вторую панель с запросом rate(http_request_duration_seconds_sum[1m]) / rate(http_request_duration_seconds_count[1m]) для среднего latency.
  5. Настройте временной интервал: последние 15 минут, автообновление 10 секунд.
  6. Сохраните дашборд (название "Latency Overview").

Ожидаемый результат этапа Дашборд отображает p99 latency и среднюю latency в реальном времени.


Этап 3: Настройка алерт-правила в Prometheus (45 минут)

Действия

  1. Добавьте в prometheus.yml секцию rule_files и создайте файл alerts.yml:
    groups:
      - name: latency_alerts
        rules:
          - alert: P99LatencySpike
            expr: histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[1m])) by (le)) > 0.5
            for: 1m
            labels:
              severity: critical
            annotations:
              summary: "P99 latency spike ({{ $value | humanizeDuration }})"
              description: "P99 latency превысил 0.5s на протяжении 1 минуты. Текущее значение: {{ $value }}s."
    
  2. Перезапустите Prometheus с обновлённой конфигурацией:
    docker restart prometheus
    
  3. Проверьте статус алерта: http://localhost:9090/alerts — должно быть правило с состоянием inactive.
  4. Сгенерируйте нагрузку, чтобы вызвать превышение порога. Используйте hey:
    hey -n 1000 -c 10 -m GET -d "" http://localhost:8000/latency
    
    При успехе алерт перейдёт в pending, затем в firing.
  5. Проверьте, что алерт отображается в Grafana (AlertingAlert rules).

Ожидаемый результат этапа Алерт срабатывает при превышении p99 > 500ms в течение 1 минуты.


Этап 4: Интеграция PagerDuty (1 час)

Действия

  1. Зарегистрируйтесь на PagerDuty, создайте сервис:
    • Services → Add Service → Integration type: Prometheus.
    • Скопируйте Integration Key (вида abc123def456).
  2. Настройте Alertmanager для отправки в PagerDuty:
    • Установите Alertmanager (через Docker):
      docker run -d --name alertmanager -p 9093:9093 \
        -v /path/to/alertmanager.yml:/etc/alertmanager/alertmanager.yml \
        prom/alertmanager
      
    • Пример alertmanager.yml:
      route:
        receiver: pagerduty
      receivers:
        - name: pagerduty
          pagerduty_configs:
            - routing_key: "abc123def456"  # замените на ваш Integration Key
      
  3. Настройте Prometheus на отправку алертов в Alertmanager. Обновите prometheus.yml (добавьте alerting секцию):
    alerting:
      alertmanagers:
        - static_configs:
            - targets: ['localhost:9093']
    rule_files:
      - 'alerts.yml'
    scrape_configs:
      ...
    
    Перезапустите Prometheus.
  4. Снова сгенерируйте нагрузку, чтобы алерт сработал. Проверьте, что в PagerDuty появился инцидент (Incidents).
  5. Закройте инцидент в PagerDuty (Acknowledge → Resolve), чтобы протестировать полный цикл.

Ожидаемый результат этапа Уведомление о spike latency доставляется в PagerDuty в течение 1 минуты после возникновения.


Этап 5: Валидация и документирование (30 минут)

Действия

  1. Убедитесь, что время обнаружения (с момента пика до появления алерта в PagerDuty) ≤ 1 минуты.
    • Для точной проверки: запустите скрипт, который каждые 5 секунд проверяет метрики и временные метки.
  2. Создайте README-документ с описанием проделанной работы:
    • Настройка Prometheus/Grafana
    • Правила алертинга
    • Интеграция с PagerDuty
    • Инструкция по проверке и тестированию.
  3. Сохраните конфигурационные файлы (prometheus.yml, alerts.yml, alertmanager.yml, код приложения) в Git-репозиторий.

Ожидаемый результат этапа Полная документация и конфигурация, готовая к повторению.


5. Критерии приемки (Definition of Done)

  • Prometheus собирает метрику http_request_duration_seconds с целевого сервиса.
  • В Grafana создан дашборд, отображающий p99 latency с обновлением каждые 10 секунд.
  • Алерт-правило P99LatencySpike определено в Prometheus, проверено на срабатывание при нагрузке.
  • Alertmanager настроен на отправку алертов в PagerDuty с использованием корректного Integration Key.
  • При превышении p99 > 500ms в течение 1 минуты в PagerDuty создаётся инцидент Critical severity.
  • Время от превышения порога до появления инцидента в PagerDuty не превышает 1 минуты (допуск ±10 секунд).
  • Все конфигурационные файлы сохранены в Git-репозитории с пояснительным README.

6. Ожидаемый результат

Основные артефакты

  • Файл app.pyFastAPI-приложение с экспортом метрик.
  • Файл prometheus.yml — конфигурация Prometheus (scrape + alerting).
  • Файл alertmanager.yml — конфигурация Alertmanager для PagerDuty.
  • Файл alerts.yml — алерт-правило для p99 latency.
  • Скриншот дашборда Grafana с панелью p99 latency.
  • Подтверждение инцидента в PagerDuty (скриншот или лог).

Дополнительно (необязательно):

  • Docker Compose-файл для запуска всех компонентов одной командой.
  • Скрипт для автоматической генерации нагрузки и проверки алерта.

7. Возможные сложности и их решение

СложностьРешение
PagerDuty Integration Key не принимаетсяУбедитесь, что вы выбрали Prometheus как тип интеграции; ключ состоит из букв и цифр, скопируйте без лишних пробелов.
Алерт в Prometheus не переходит в firingПроверьте for: 1m — нужно, чтобы условие выполнялось непрерывно 1 минуту. Увеличьте интенсивность нагрузки (количество запросов в секунду).
Grafana не может подключиться к Prometheus (Docker)Используйте правильный сетевой режим; при Docker Desktop используйте host.docker.internal или разместите оба контейнера в одной сети.
histogram_quantile даёт странные значенияУбедитесь, что метрика _bucket присутствует; для FastAPI правильно вызывайте .observe(delay).
Alertmanager не принимает алертыПроверьте, что targets в alerting секции Prometheus указаны корректно и порт 9093 открыт.

8. Бюджет времени (оценка)

ЭтапВремя
Этап 1: Подготовка инфраструктуры1–1.5 ч
Этап 2: Создание дашборда Grafana1 ч
Этап 3: Настройка алерт-правила45 мин
Этап 4: Интеграция PagerDuty1 ч
Этап 5: Валидация и документирование30 мин
Итого4–4.75 часов

Примечание: для первого выполнения (особенно если не знакомы с PromQL) может потребоваться до 6 часов. Рекомендуется выделить целый рабочий день.


9. Связанные вопросы из базы знаний

ВопросТема
12PromQL: histogram_quantile
37Настройка Alertmanager
45Интеграция с PagerDuty
78Мониторинг latency в микросервисах
119Экспорт метрик через prometheus_client
203Понятие SLO и SLI для latency
298Написание алерт-правил best practices
367Дедупликация алертов
412Grafana provisioning (дашборды as code)
559Load testing для проверки алертов

10. Чек-лист самопроверки

  • Я развернул приложение и убедился, что метрики доступны по /metrics.
  • Я настроил Prometheus на сбор метрик и проверил запрос http_request_duration_seconds_bucket в интерфейсе Prometheus.
  • Я создал дашборд в Grafana, и на нём отображается p99 latency при генерации нагрузки.
  • Я настроил алерт-правило, и оно перешло в firing при превышении порога на 1 минуту.
  • Я интегрировал PagerDuty, и после срабатывания алерта в PagerDuty появился инцидент.
  • Я измерил время от начала пика до появления инцидента — оно не превышает 1 минуты.