Документация

Интеграция с Grafana Alerting

Версия v2.3.1 · Обновлено

Интеграция с Grafana Alerting#

IncidentRelay может принимать уведомления Grafana Alerting через отдельный эндпоинт-вебхук. Каждый экземпляр алерта Grafana нормализуется, маршрутизируется, группируется, дедуплицируется и обрабатывается через стандартный жизненный цикл алертов IncidentRelay.

Эндпоинт#

POST /api/integrations/grafana

Эндпоинт требует токен приёма активного маршрута IncidentRelay, источником которого является grafana.

Authorization: Bearer <route-intake-token>
Content-Type: application/json

Создание маршрута IncidentRelay#

  • Откройте Routes в IncidentRelay.
  • Создайте маршрут или отредактируйте существующий.
  • Выберите Grafana в качестве источника.
  • Выберите команду, которой принадлежат алерты.
  • Настройте матчеры, группировку и цель назначения.
  • Убедитесь, что маршрут активен.
  • Скопируйте сгенерированный URL приёма и токен маршрута.

Типовая конфигурация группировки:

[
  "alertname",
  "grafana_folder",
  "instance"
]

Выбирайте только те метки, которые идентифицируют логический инцидент. Избегайте группировки по меткам, значения которых часто меняются.

Пример матчеров маршрута:

{
  "environment": "production",
  "team": "sre"
}

Метки Grafana становятся доступны матчерам маршрута после слияния общих меток и меток отдельных алертов.

Настройка Grafana#

В Grafana:

  • Откройте Alerts & IRM → Alerting → Notification configuration.
  • Откройте вкладку Contact points.
  • Добавьте точку контакта (contact point).
  • Выберите Webhook в качестве интеграции.
  • Укажите URL эндпоинта Grafana IncidentRelay:

``text https://incidentrelay.example.com/api/integrations/grafana ``

  • Установите HTTP-метод POST.
  • В настройках авторизации задайте:
  • Authentication Header Scheme: Bearer
  • Authentication Header Credentials: токен маршрута IncidentRelay
  • Оставьте Disable resolved message отключённым, чтобы IncidentRelay получал уведомления о восстановлении.
  • Сохраните точку контакта.
  • Используйте тестовое действие Grafana для проверки доставки.

Привяжите точку контакта к нужной политике уведомлений Grafana.

Пример provisioning-конфигурации Grafana#

Grafana OSS/Enterprise позволяет создать contact point из файла в каталоге provisioning/alerting:

apiVersion: 1

contactPoints:
  - orgId: 1
    name: IncidentRelay
    receivers:
      - uid: incidentrelay-webhook
        type: webhook
        disableResolveMessage: false
        settings:
          url: https://incidentrelay.example.com/api/integrations/grafana
          httpMethod: POST
          authorization_scheme: Bearer
          authorization_credentials: $INCIDENTRELAY_ROUTE_TOKEN

Передайте INCIDENTRELAY_ROUTE_TOKEN через окружение процесса/контейнера Grafana вместо хранения токена в provisioning-файле. Оставьте disableResolveMessage: false, чтобы IncidentRelay получал события восстановления.

Например, сохраните файл как:

/etc/grafana/provisioning/alerting/incidentrelay.yaml

После этого перезапустите Grafana или перезагрузите provisioned alerting resources через provisioning API Grafana. Contact point всё равно нужно выбрать в alert rule или notification policy.

Рекомендуемые метки Grafana#

Добавьте стабильные метки к правилам алертов Grafana, чтобы IncidentRelay мог предсказуемо маршрутизировать и группировать их.

labels:
  team: sre
  environment: production
  severity: critical

Полезные метки включают:

МеткаНазначение
teamМаршрутизация по команде
environmentProduction, staging, development
severityПриоритет алерта
serviceЗатронутый сервис
instanceЗатронутый хост или инстанс
grafana_folderПапка Grafana
alertnameИмя правила алерта

Нормализатор также распознаёт oncall_team как запасную метку команды, а priority или level — как запасные метки важности.

Нормализация алертов#

IncidentRelay обрабатывает каждый объект в массиве alerts Grafana независимо.

Статус#

Статус экземпляра алерта имеет приоритет над статусом уведомления верхнего уровня.

Значения, похожие на resolved, нормализуются в:

resolved

Остальные значения трактуются как:

firing

Это позволяет одной группе уведомлений Grafana содержать экземпляры алертов с разными состояниями.

Заголовок#

IncidentRelay выбирает первое доступное значение из:

  • annotations.summary
  • labels.alertname
  • title верхнего уровня
  • Grafana alert

Сообщение#

IncidentRelay выбирает первое доступное значение из:

  • annotations.description
  • annotations.message
  • message верхнего уровня
  • valueString

Важность#

IncidentRelay выбирает первую доступную метку из:

  • severity
  • priority
  • level

Команда#

IncidentRelay выбирает первое доступное значение из:

  • labels.team
  • labels.oncall_team
  • team верхнего уровня

Приоритет остаётся за сопоставлением маршрута. Метка не обходит обычные проверки доступа к маршруту или проверки матчеров.

Метки, добавляемые IncidentRelay#

При наличии в полезной нагрузке Grafana интеграция предоставляет следующие значения в виде меток:

Метка IncidentRelayПоле Grafana
dashboard_urldashboardURL
panel_urlpanelURL
generator_urlgeneratorURL
silence_urlsilenceURL
grafana_urlexternalURL
grafana_org_idorgId
grafana_receiverreceiver
grafana_group_keygroupKey
grafana_statestate

Первая доступная ссылка Grafana также сохраняется как event_link. Порядок выбора:

  • URL дашборда
  • URL панели
  • URL правила алерта
  • URL заглушки
  • базовый URL Grafana

Дедупликация#

Когда Grafana предоставляет fingerprint, IncidentRelay использует его в качестве ключа дедупликации.

Когда fingerprint отсутствует, IncidentRelay генерирует стабильный ключ из:

  • источника Grafana;
  • UID правила алерта, если доступен;
  • заголовка алерта;
  • стабильных меток;
  • ID организации Grafana.

Уведомление firing, за которым следует уведомление resolved с тем же ключом дедупликации, обновляет существующий алерт, а не создаёт новый.

Сохранённая полезная нагрузка#

IncidentRelay сохраняет исходный контекст группы Grafana, но каждый нормализованный алерт IncidentRelay хранит в сохранённом массиве alerts только свой собственный экземпляр алерта Grafana.

Это сохраняет такие поля, как:

  • orgId;
  • receiver;
  • groupKey;
  • общие метки и аннотации;
  • ссылки на дашборд и панель;
  • значения выражений;
  • временные метки.

Пример полезной нагрузки#

{
  "receiver": "incidentrelay",
  "status": "firing",
  "orgId": 1,
  "groupKey": "{}:{alertname=\"DiskFull\"}",
  "commonLabels": {
    "team": "sre",
    "environment": "production"
  },
  "commonAnnotations": {
    "runbook_url": "https://example.com/runbooks/disk"
  },
  "externalURL": "https://grafana.example.com/",
  "title": "[FIRING:1] DiskFull",
  "state": "alerting",
  "message": "Grafana notification",
  "alerts": [
    {
      "status": "firing",
      "labels": {
        "alertname": "DiskFull",
        "severity": "critical",
        "instance": "host1",
        "grafana_folder": "Infrastructure",
        "__alert_rule_uid__": "disk-full-rule"
      },
      "annotations": {
        "summary": "Disk is full",
        "description": "/var is 95% full"
      },
      "startsAt": "2026-06-21T10:00:00Z",
      "endsAt": "0001-01-01T00:00:00Z",
      "generatorURL": "https://grafana.example.com/alerting/grafana/disk-full-rule/view",
      "fingerprint": "grafana-disk-full-host1",
      "silenceURL": "https://grafana.example.com/alerting/silence/new",
      "dashboardURL": "https://grafana.example.com/d/system-overview",
      "panelURL": "https://grafana.example.com/d/system-overview?viewPanel=12",
      "values": {
        "A": 95
      },
      "valueString": "[ var='A' value=95 ]"
    }
  ]
}

Ручной тест#

curl -X POST \
  "https://incidentrelay.example.com/api/integrations/grafana" \
  -H "Authorization: Bearer ROUTE_INTAKE_TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary @grafana-payload.json

Успешный ответ содержит по одному результату на каждый объект в массиве alerts Grafana.

[
  {
    "created": true,
    "alert_id": 123,
    "group_id": 45,
    "status": "firing",
    "team_id": 2,
    "team_slug": "sre",
    "route_id": 7,
    "routing_error": null,
    "trace_id": "..."
  }
]

HTTP-ответы#

СтатусЗначение
200Все экземпляры алертов обработаны успешно
202Обработка принята, но не завершена полностью синхронно
207Уведомление содержит смешанные результаты обработки
400Некорректная полезная нагрузка или сбой маршрутизации
401Токен приёма маршрута отсутствует или недействителен

При сбое маршрутизации ответ включает trace_id. Администратор может использовать трассировку объяснения алерта для проверки вычисления матчеров и точной причины сбоя маршрутизации.

Устранение неполадок#

Требуется токен приёма маршрута#

Grafana не отправила заголовок авторизации.

Проверьте:

Authentication Header Scheme: Bearer
Authentication Header Credentials: <route-intake-token>

Не добавляйте слово Bearer в поле учётных данных, когда схема настроена отдельно.

Алерт не сопоставился ни с одним активным маршрутом#

Проверьте, что:

  • маршрут активен;
  • источник маршрута — grafana;
  • токен принадлежит этому маршруту;
  • входящие метки удовлетворяют каждому настроенному матчеру;
  • команда маршрута активна и доступна.

Используйте возвращённый trace_id для проверки вычисления маршрута.

Уведомления resolved не приходят#

Убедитесь, что в точке контакта вебхука Grafana не включён параметр Disable resolved message.

IncidentRelay использует статус каждого элемента в массиве alerts, а не только статус верхнего уровня.

Алерты дублируются#

Проверьте, что Grafana отправляет стабильный fingerprint. Когда fingerprint недоступен, сохраняйте UID правила и метки маршрутизации стабильными между уведомлениями firing и resolved.

Не включайте изменчивые значения в метки, используемые для идентификации экземпляра алерта.

Ссылки на дашборд или панель пусты#

Grafana включает ссылки на дашборд и панель только тогда, когда правило алерта связано с соответствующими метаданными дашборда и панели. URL правила алерта остаётся доступным через generatorURL.

Тестовое уведомление не соответствует production-маршрутизации#

Метки тестовой полезной нагрузки Grafana могут отличаться от реальных меток правил алертов. Сравните полученные метки в трассировке объяснения с матчерами маршрута.

Безопасность#

  • Используйте HTTPS для эндпоинта-вебхука.
  • Храните токены приёма маршрутов как секреты.
  • Используйте отдельный токен маршрута для каждой интеграции или границы доверия.
  • Немедленно ротируйте токен, если он был раскрыт.
  • Не помещайте токен в URL.
  • Ограничивайте матчеры маршрута, чтобы утёкший токен не мог маршрутизировать посторонние алерты.