Gymterview
senior

Что такое алертинг и как его правильно настроить?

Алертинг — процесс автоматического оповещения команды о проблемах в системе на основании заданных правил. Правильно настроенный алертинг позволяет быстро реагировать на инциденты, неправильный — приводит к alert fatigue (усталости от алертов), когда все уведомления игнорируются.

Принципы правильного алертинга

  1. Алерты на симптомы, а не на причины: алерт «высокая latency для пользователей» лучше, чем «высокий CPU», потому что CPU может быть высоким и при нормальной работе.

  2. Каждый алерт должен требовать действия (actionable): если при получении алерта дежурный не может ничего сделать — алерт не нужен.

  3. Минимум шума: лучше пропустить некритичный инцидент, чем завалить команду ложными срабатываниями.

Уровни severity

Severity Описание Действие Время реакции
Critical (P1) Сервис недоступен, потеря данных Немедленная эскалация, звонок < 5 минут
Warning (P2) Деградация сервиса, SLO под угрозой Уведомление в рабочее время < 1 час
Info (P3) Аномалия, требует внимания Тикет в бэклог Следующий рабочий день
Конфигурация Prometheus Alertmanager
# alertmanager.yml
global:
  resolve_timeout: 5m
  slack_api_url: 'https://hooks.slack.com/services/T.../B.../xxxx'

route:
  receiver: 'default-slack'
  group_by: ['alertname', 'job']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h

  routes:
    - match:
        severity: critical
      receiver: 'pagerduty-critical'
      continue: true
    - match:
        severity: critical
      receiver: 'slack-critical'
    - match:
        severity: warning
      receiver: 'slack-warning'

receivers:
  - name: 'default-slack'
    slack_configs:
      - channel: '#alerts'
        title: '{{ .GroupLabels.alertname }}'
        text: '{{ range .Alerts }}{{ .Annotations.description }}{{ end }}'

  - name: 'slack-critical'
    slack_configs:
      - channel: '#alerts-critical'
        title: 'CRITICAL: {{ .GroupLabels.alertname }}'
        color: 'danger'

  - name: 'slack-warning'
    slack_configs:
      - channel: '#alerts-warning'
        title: 'WARNING: {{ .GroupLabels.alertname }}'
        color: 'warning'

  - name: 'pagerduty-critical'
    pagerduty_configs:
      - service_key: '<pagerduty-service-key>'
        severity: critical

inhibit_rules:
  - source_match:
      alertname: 'ServiceDown'
    target_match:
      severity: 'warning'
    equal: ['job']
Примеры alert rules
# alert_rules.yml
groups:
  - name: application
    rules:
      # Сервис не отвечает
      - alert: ServiceDown
        expr: up{job="order-service"} == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Service {{ $labels.job }} is down"
          description: "{{ $labels.instance }} has been down for more than 1 minute"

      # Высокий процент ошибок (> 5%)
      - alert: HighErrorRate
        expr: |
          sum(rate(http_server_requests_seconds_count{status=~"5..", job="order-service"}[5m]))
          /
          sum(rate(http_server_requests_seconds_count{job="order-service"}[5m]))
          > 0.05
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "High error rate on {{ $labels.job }}"
          description: "Error rate is {{ $value | humanizePercentage }}"

      # Высокая latency (p99 > 2s)
      - alert: HighLatency
        expr: |
          histogram_quantile(0.99,
            sum(rate(http_server_requests_seconds_bucket{job="order-service"}[5m])) by (le)
          ) > 2
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "High p99 latency on {{ $labels.job }}"

      # JVM Heap > 90%
      - alert: HighHeapUsage
        expr: |
          jvm_memory_used_bytes{area="heap"}
          /
          jvm_memory_max_bytes{area="heap"}
          > 0.9
        for: 5m
        labels:
          severity: warning

      # HikariCP — нет свободных соединений
      - alert: NoFreeDbConnections
        expr: hikaricp_connections_idle{job="order-service"} == 0
        for: 2m
        labels:
          severity: critical

      # Error budget burn rate (SLO-based)
      - alert: ErrorBudgetBurnRate
        expr: |
          (
            1 - (
              sum(rate(http_server_requests_seconds_count{status!~"5..", job="order-service"}[1h]))
              /
              sum(rate(http_server_requests_seconds_count{job="order-service"}[1h]))
            )
          ) > (1 - 0.999) * 14.4
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Error budget burning too fast on {{ $labels.job }}"

Важное

  • Alert fatigue — главная проблема алертинга. Если команда получает 100 алертов в день, все они будут игнорироваться.
  • Алерт = действие: каждый алерт должен иметь runbook (документ с инструкцией по решению проблемы).
  • for clause обязателен: без него алерт сработает на короткий spike. for: 5m означает «проблема должна длиться 5 минут подряд».
  • group_by предотвращает спам: если упало 10 инстансов одного сервиса, приходит один алерт, а не десять.

Частые ошибки

  • Алерт на каждую метрику: «CPU > 80%» не означает проблему. Алертить нужно на влияние на пользователя (latency, errors).
  • Слишком низкие пороги: error_rate > 0.01 при 100 RPS будет срабатывать постоянно из-за единичных 500-ок.
  • Нет for clause: алерт срабатывает на каждый кратковременный spike, создавая шум.
  • Нет inhibit_rules: при падении всего кластера приходят сотни алертов, хотя нужен один.
  • Не настроен resolve: команда не знает, когда проблема решена, и продолжает тратить время.

Как используется в 2026

  • SLO-based alerting — вместо статических порогов используется burn rate error budget.
  • Grafana Unified Alerting — единый алертинг для метрик, логов и трейсов.
  • AIOps — ML-модели автоматически определяют аномалии и корреляции между алертами.
  • Grafana OnCall / PagerDuty — интеграция с системами управления дежурствами.
  • ChatOps — алерты в Slack/Teams с возможностью acknowledge, silence и escalate прямо из чата.

На собеседовании: ключевые принципы — алерты на симптомы (не причины), каждый алерт actionable, обязательный for clause. Покажите знание уровней severity и их маппинг на действия. Частая ошибка — не упомянуть alert fatigue и inhibit_rules. Сильный ответ включает SLO-based alerting с burn rate.