Guide: Grafana alerts → PartyFlow
Настроить Grafana Alerting так, чтобы алерты приходили в канал PartyFlow с цветной полоской, полями и push-уведомлением только для critical-алертов.
Рабочее время — около 10 минут, если у вас уже есть права admin в space PartyFlow и права editor в Grafana.
Что получится
- Сообщения от Grafana попадают в канал как structured message с color bar, title, fields.
severity: criticalв Grafana-правиле → push пробивает DND дежурного.severity: warning/info→ в канал попадает, но без push (чтобы не разбудить команду ночью скучными алертами).- Подпись HMAC — опциональна, но рекомендуется для прод-Grafana.
Шаг 1. Создать webhook в PartyFlow
В space → Integrations → Incoming webhooks → New webhook:
| Поле | Значение |
|---|---|
| Name | grafana-alerts |
| Channel | #alerts (или какой у вас) |
| Require signature | On для прода. Off для быстрого старта. |
| Default push | Off — мы хотим, чтобы push решался per-alert через severity. |
Сохраните:
- Webhook URL (
https://api.partyflow.ru/api/v1/webhooks/incoming/whk_...) - Signing secret (если выбрали Require signature: On)
Шаг 2. Contact Point в Grafana
В Grafana → Alerting → Contact points → + Add contact point:
| Поле | Значение |
|---|---|
| Name | partyflow |
| Integration | Webhook |
| URL | <webhook URL из шага 1> |
| HTTP Method | POST |
| Authorization Header — Scheme | оставить пустым |
| Max Alerts | 0 (без ограничения) |
| Custom payload | см. ниже |
Payload template
Grafana умеет шаблонизировать JSON. Вставьте в "Optional Webhook settings → Custom payload":
{
"text": "{{ range .Alerts }}{{ .Labels.alertname }} — {{ .Annotations.summary }}\n{{ end }}",
"severity": "{{ if eq (index .Alerts 0).Labels.severity \"critical\" }}critical{{ else if eq (index .Alerts 0).Labels.severity \"warning\" }}warning{{ else }}info{{ end }}",
"mentions": {{ if eq (index .Alerts 0).Labels.severity "critical" }}["<user-id-oncall>"]{{ else }}[]{{ end }},
"attachments": [
{{ range $i, $a := .Alerts }}{{ if $i }},{{ end }}{
"color": "{{ if eq $a.Status \"firing\" }}#E01E5A{{ else }}#2EB67D{{ end }}",
"title": "[{{ $a.Status | ToUpper }}] {{ $a.Labels.alertname }}",
"title_link": "{{ $a.GeneratorURL }}",
"text": "{{ $a.Annotations.description }}",
"fields": [
{ "title": "Severity", "value": "{{ $a.Labels.severity }}", "short": true },
{ "title": "Instance", "value": "{{ $a.Labels.instance }}", "short": true }
],
"ts": {{ $a.StartsAt.Unix }}
}{{ end }}
]
}Подставьте в "mentions" реальный user_id дежурного (узнать в PartyFlow → профиль → Copy user ID).
Для signed webhook'а
Grafana сам не умеет считать HMAC. Есть два варианта:
Вариант A (простой): Webhook в режиме Require signature: Off. Безопасность держится на URL-токене — достаточно для multi-tenant прод-Grafana, если URL не попадает в публичные репо/PR.
Вариант B (надёжный): Прокси-сервис между Grafana и PartyFlow. Grafana шлёт в прокси, прокси подписывает и форвардит. Пример прокси — в guides/verify-signatures.md.
Шаг 3. Attach к Alert Rule
В Alerting → Notification policies убедитесь, что matchers вашего правила направляют его на contact point partyflow. По default — root policy.
Шаг 4. Тест
В Grafana → Contact points → partyflow → Test. В канале должно появиться test-сообщение с color bar.
Если не пришло:
| Симптом | Диагностика |
|---|---|
В логе Grafana HTTP 400 |
Payload невалиден. Скопируйте body из "Test alert" Grafana и прогоните через jq . — что-то не JSON. |
В логе Grafana HTTP 401 |
Неверный URL или (если Require signature: On) нет подписи. |
В логе Grafana HTTP 413 |
Payload > 256 KB. Урежьте шаблон — например, уберите .Annotations.description из text attachment'а. |
В логе Grafana HTTP 429 |
Rate limit. У вас десятки alerts в секунду — сгруппируйте в Notification policy (grouping by alertname). |
200, но нет в канале |
Проверьте ID канала; возможно webhook создан на другой канал. |
Шаг 5. Настроить push для critical
По дефолту push придёт только если в payload есть хоть одно из:
mentions[]с user_id@channelили@hereвtext
Что настроили в шаблоне выше:
severity: "critical"+mentions: [oncall]→ push дежурному, пробивает DND.severity: "warning"+mentions: []→ в канал, без push.severity: "info"+mentions: []→ в канал, без push.
Для ротации дежурных — проще использовать канал типа @oncall-team и в шаблоне подставлять "text": "... @here" или перечислять user_id через PagerDuty-like schedule-aware скрипт в прокси.
Частые правки
Убрать дубли одного alert'а
Grafana периодически переотправляет все firing-alerts. Если не хотите этого, в Notification policies → Group interval поставьте бОльшее значение (например, 4h) — PartyFlow покажет повторы только при эскалации.
Показывать только changes (firing/resolved)
Добавьте в Notification policies → Repeat interval: 0 или очень большое значение, чтобы resolved приходил отдельно, а firing — только при новом событии.
Собрать подпись на стороне прокси (Вариант B)
См. guides/verify-signatures.md — взять snippet на Python, поставить Flask/FastAPI-прокси между Grafana и PartyFlow.
Связанное
- reference/http-webhook-endpoint.md — все поля payload и response codes.
- reference/message-format.md — Planned. Полная спека
attachments/blocks. - concepts/security.md — почему сигнатура это важно.