Примеры шаблонов уведомлений

Шаблоны уведомлений позволяют изменять уведомительные сообщения по умолчанию.

Вы можете изменять содержимое и формат уведомительных сообщений. Например, вы можете настроить содержимое так, чтобы показывать только определённую информацию, или скорректировать формат под конкретную точку контакта, такую как Slack или Email.

Note

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

Вместо этого вам следует использовать аннотации или метки, чтобы добавлять информацию напрямую в оповещение, обеспечивая её видимость также в состоянии оповещения и истории оповещений в Grafana. Затем вы можете вывести новую аннотацию или метку оповещения в шаблонах уведомлений.

Эта страница содержит различные примеры, иллюстрирующие шаблонизацию распространённых уведомительных сообщений. Подробнее о шаблонах уведомлений см.:

Базовые примеры

Шаблоны уведомлений могут получать доступ к данным уведомления с помощью dot (.). Следующие примеры демонстрируют некоторые базовые случаи использования языка шаблонов.

Примеры форматирования текста

Форматирование текста в шаблонах уведомлений зависит от типа точки контакта. У каждой платформы свой синтаксис форматирования:

Форматирование Slack

Для точек контакта Slack вы можете использовать:

Go
{{ define "slack_formatted_message" -}}
*This text will be bold in Slack*
_This text will be italic in Slack_
Regular text without formatting
{{ end }}

Выполните шаблон:

Go
{{ template "slack_formatted_message" . }}
template_output
*This text will be bold in Slack*
_This text will be italic in Slack_
Regular text without formatting

Дополнительные типы точек контакта

Note

У каждого типа точки контакта свои требования к форматированию:

  • Некоторые поддерживают форматирование в стиле Markdown
  • Другие используют HTML-теги
  • Некоторые могут вообще не поддерживать форматирование

Проверьте документацию вашей конкретной точки контакта на предмет поддерживаемого синтаксиса форматирования.

Примеры логики шаблонов

Помимо форматирования текста, вы можете использовать логику шаблонов для создания динамического содержимого уведомлений. Следующие примеры демонстрируют базовые операции с шаблонами:

Условная логика

Чтобы проверить наличие общих меток (.CommonLabels) для всех оповещений в уведомлении, используйте if:

Go
{{ define "custom_message" -}}
{{ if .CommonLabels }}
Alerts have common labels
{{ else }}
There are no common labels
{{ end }}
{{ end }}

Итерация по оповещениям

Чтобы итерироваться по оповещениям в уведомлении и вывести конкретную метку, используйте range и index:

Go
{{ define "custom_message" -}}
{{ range .Alerts }}
The name of the alert is {{ index .Labels "alertname" }}
{{ end }}
{{ end }}

В качестве альтернативы вы можете использовать нотацию . для вывода значения ключа.

Go
{{ define "custom_message" -}}
{{ range .Alerts }}
The name of the alert is {{ .Labels.alertname }}
{{ end }}
{{ end }}

Затем вы можете использовать шаблон, передав данные уведомления (dot .):

Go
{{ template "custom_message" . }}
template_output
The name of the alert is InstanceDown

The name of the alert is CpuOverload

Вот пример, отображающий аннотации summary и description для каждого оповещения в уведомлении.

Go
{{ define "custom.alerts" -}}
{{ len .Alerts }} alert(s)
{{ range .Alerts -}}
  {{ template "alert.summary_and_description" . -}}
{{ end -}}
{{ end -}}
{{ define "alert.summary_and_description" }}
  Summary: {{.Annotations.summary}}
  Status: {{ .Status }}
  Description: {{.Annotations.description}}
{{ end -}}

В этом примере:

  • Определяется шаблон (alert.summary_and_description) для вывода summary, status и description одного оповещения.
  • Основной шаблон custom.alerts итерируется по списку оповещений (.Alerts) в данных уведомления, выполняя шаблон alert.summary_and_description для вывода деталей каждого оповещения.

Выполните шаблон, передав dot (.):

Go
{{ template "custom.alerts" . }}
template_output
2 alert(s)

  Summary: The database server db1 has exceeded 75% of available disk space.
  Status: firing
  Description: This alert fires when a database server is at risk of running out of disk space. You should take measures to increase the maximum available disk space as soon as possible to avoid possible corruption.

  Summary: The web server web1 has been responding to 5% of HTTP requests with 5xx errors for the last 5 minutes.
  Status: resolved
  Description: This alert fires when a web server responds with more 5xx errors than is expected. This could be an issue with the web server or a backend service.

Следующий пример похож на предыдущий, но разделяет сработавшие и разрешившиеся оповещения.

Go
{{ define "custom.firing_and_resolved_alerts" -}}
{{ len .Alerts.Resolved }} resolved alert(s)
{{ range .Alerts.Resolved -}}
  {{ template "alert.summary_and_description" . -}}
{{ end }}
{{ len .Alerts.Firing }} firing alert(s)
{{ range .Alerts.Firing -}}
  {{ template "alert.summary_and_description" . -}}
{{ end -}}
{{ end -}}
{{ define "alert.summary_and_description" }}
  Summary: {{.Annotations.summary}}
  Status: {{ .Status }}
  Description: {{.Annotations.description}}
{{ end -}}

Вместо .Alerts шаблон отдельно обращается к .Alerts.Firing и .Alerts.Resolved, чтобы вывести детали для каждого оповещения.

Запустите шаблон, передав dot (.):

Go
{{ template "custom.firing_and_resolved_alerts" . }}
template_output
1 resolved alert(s)

  Summary: The database server db1 has exceeded 75% of available disk space.
  Status: resolved
  Description: This alert fires when a database server is at risk of running out of disk space. You should take measures to increase the maximum available disk space as soon as possible to avoid possible corruption.

1 firing alert(s)

  Summary: The web server web1 has been responding to 5% of HTTP requests with 5xx errors for the last 5 minutes.
  Status: firing
  Description: This alert fires when a web server responds with more 5xx errors than is expected. This could be an issue with the web server or a backend service.

Этот пример отображает только метки и аннотации, общие для всех оповещений в уведомлении.

Go
{{ define "custom.common_labels_and_annotations" -}}
{{ len .Alerts.Resolved }} resolved alert(s)
{{ len .Alerts.Firing }} firing alert(s)
Common labels: {{ len .CommonLabels.SortedPairs }}
{{ range .CommonLabels.SortedPairs -}}
- {{ .Name }} = {{ .Value }}
{{ end }}
Common annotations: {{ len .CommonAnnotations.SortedPairs }}
{{ range .CommonAnnotations.SortedPairs }}
- {{ .Name }} = {{ .Value }}
{{ end }}
{{ end -}}

Обратите внимание, что .CommonAnnotations и .CommonLabels являются частью данных уведомления.

Выполните шаблон, передав dot (.) в качестве аргумента:

Go
{{ template "custom.common_labels_and_annotations" . }}
template_output
1 resolved alert(s)
1 firing alert(s)
Common labels: 2
- grafana_folder = server_alerts
- team = server_admin

Common annotations: 0

Этот пример отображает все метки и аннотации для каждого оповещения в уведомлении.

Go
{{ define "custom.alert_labels_and_annotations" -}}
{{ len .Alerts.Resolved }} resolved alert(s)
{{ range .Alerts.Resolved -}}
  {{ template "alert.labels_and_annotations" . -}}
{{ end }}
{{ len .Alerts.Firing }} firing alert(s)
{{ range .Alerts.Firing -}}
  {{ template "alert.labels_and_annotations" . -}}
{{ end -}}
{{ end -}}
{{ define "alert.labels_and_annotations" }}
Alert labels: {{ len .Labels.SortedPairs }}
{{ range .Labels.SortedPairs -}}
- {{ .Name }} = {{ .Value }}
{{ end -}}
Alert annotations: {{ len .Annotations.SortedPairs }}
{{ range .Annotations.SortedPairs -}}
- {{ .Name }} = {{ .Value }}
{{ end -}}
{{ end -}}

В этом примере:

  • Шаблон custom.alert_labels_and_annotations итерируется по списку разрешившихся и сработавших оповещений, подобно предыдущим примерам. Затем он выполняет alert.labels_and_annotations для каждого оповещения.
  • Шаблон alert.labels_and_annotations выводит все метки и аннотации оповещения, обращаясь к .Labels.SortedPairs и .Annotations.SortedPairs.

Запустите шаблон, передав dot (.):

Go
{{ template "custom.alert_labels_and_annotations" . }}
template_output
1 resolved alert(s)

Alert labels: 4
- alertname = db_server_disk_space
- grafana_folder = server_alerts
- server = db1
- team = server_admin

Alert annotations: 2
- summary = The database server db1 has exceeded 75% of available disk space.
- description = This alert fires when a database server is at risk of running out of disk space. You should take measures to increase the maximum available disk space as soon as possible to avoid possible corruption.

1 firing alert(s)

Alert labels: 4
- alertname = web_server_http_errors
- grafana_folder = server_alerts
- server = web1
- team = server_admin

Alert annotations: 2
- summary = The web server web1 has been responding to 5% of HTTP requests with 5xx errors for the last 5 minutes.
- description = This alert fires when a web server responds with more 5xx errors than is expected. This could be an issue with the web server or a backend service.

Обратите внимание, что следующий пример работает только для Grafana-managed оповещений. Он отображает некоторые данные оповещения, такие как DashboardURL, PanelURL и SilenceURL, которые эксклюзивны для Grafana-managed оповещений.

Go
{{ define "custom.alert_additional_details" -}}
{{ len .Alerts.Resolved }} resolved alert(s)
{{ range .Alerts.Resolved -}}
  {{ template "alert.additional_details" . -}}
{{ end }}
{{ len .Alerts.Firing }} firing alert(s)
{{ range .Alerts.Firing -}}
  {{ template "alert.additional_details" . -}}
{{ end -}}
{{ end -}}
{{ define "alert.additional_details" }}
- Dashboard: {{ .DashboardURL }}
- Panel: {{ .PanelURL }}
- AlertGenerator: {{ .GeneratorURL }}
- Silence: {{ .SilenceURL }}
- RunbookURL: {{ .Annotations.runbook_url}}
{{ end -}}

Передайте dot (.), чтобы выполнить шаблон:

Go
{{ template "custom.alert_additional_details" . }}
template_output
1 resolved alert(s)

- Dashboard: https://example.com/d/uiyahbsdaubsd?from=1740070380000&orgId=1&to=1740074106395
- Panel: https://example.com/d/uiyahbsdaubsd?from=1740070380000&orgId=1&to=1740074106395&viewPanel=31
- AlertGenerator: ?orgId=1
- Silence: https://example.com/alerting/silence/new
- RunbookURL: https://example.com/on-call/db_server_disk_space

1 firing alert(s)

- Dashboard: https://example.com/d/uiyahbsdaubsd?from=1740070380000&orgId=1&to=1740074106395
- Panel: https://example.com/d/uiyahbsdaubsd?from=1740070380000&orgId=1&to=1740074106395&viewPanel=31
- AlertGenerator: ?orgId=1
- Silence: https://example.com/alerting/silence/new
- RunbookURL: https://example.com/on-call/web_server_http_errors

Заголовок или тема дают однострочную сводку содержимого уведомления.

Вот базовый пример, отображающий количество сработавших и разрешившихся оповещений в уведомлении.

Go
{{ define "custom_title" -}}
{{ if gt (.Alerts.Firing | len) 0 }}🚨 {{ .Alerts.Firing | len }} firing alerts. {{ end }}{{ if gt (.Alerts.Resolved | len) 0 }}✅ {{ .Alerts.Resolved | len }} resolved alerts.{{ end }}
{{ end -}}

Выполните шаблон, передав dot (.) в качестве аргумента:

Go
{{ template "custom_title" . }}
template_output
🚨 1 firing alerts. ✅ 1 resolved alerts.

Следующий пример — это копия шаблона заголовка/темы по умолчанию, используемого в Grafana.

Go
{{ define "copy_of_default_title" -}}
[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ if gt (.Alerts.Resolved | len) 0 }}, RESOLVED:{{ .Alerts.Resolved | len }}{{ end }}{{ end }}] {{ .GroupLabels.SortedPairs.Values | join " " }} {{ if gt (len .CommonLabels) (len .GroupLabels) }}({{ with .CommonLabels.Remove .GroupLabels.Names }}{{ .Values | join " " }}{{ end }}){{ end }}
{{ end }}

Это более сложный пример:

Выполните шаблон, передав dot (.):

Go
{{ template "copy_of_default_title" . }}
template_output
[FIRING:1, RESOLVED:1] api warning (sql_db)

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

Включение ссылки на дашборд в уведомление помогает дежурным быстро перейти к соответствующему контексту для расследования.

Используйте один из следующих способов, чтобы включить ссылку на дашборд с правильным временным диапазоном в уведомление об оповещении:

  1. Вы можете связать правило оповещения с панелью. Это включает URL дашборда и панели через {{.Alert.DashboardURL}} и {{.Alert.PanelURL}}.

    Go
    {{ define "custom.link_to_dashboard" -}}
    {{ range .Alerts -}}
      Dashboard: {{.DashboardURL}}
      Panel: {{ .PanelURL }}
    {{ end -}}
    {{ end -}}

    Запустите шаблон с помощью:

    Go
    {{ template "custom.link_to_dashboard" . }}
    template_output
    Dashboard: https://example.com/d/uiyahbsdaubsd?from=1740070380000&orgId=1&to=1740074106395
    Panel: https://example.com/d/uiyahbsdaubsd?from=1740070380000&orgId=1&to=1740074106395&viewPanel=31

    Эти URL включают временной диапазон на основе времени оповещения:

    • from: один час до срабатывания оповещения.
    • to: текущее время, если оповещение срабатывает, или время окончания оповещения, если оно разрешилось.
  2. В качестве альтернативы вы можете использовать пользовательскую аннотацию, чтобы задать URL дашборда и построить полный URL с помощью параметров запроса from и to, полученных из {{.Alert.StartsAt}} и {{.Alert.EndsAt}}.

    Go
    {{ define "custom.my_dashboard_url_annotation" -}}
    {{ range .Alerts -}}
    
      {{/* StartsAt - 1h */}}
      {{- $from := (.StartsAt.Add -3600000000000).UnixMilli }}
    
      {{- $to := "" }}
      {{- if eq .Status "resolved" }}
         {{- $to = (.EndsAt).UnixMilli }}
      {{- else -}}
        {{/* Use current time if alert is firing */}}
        {{- $to = (time.Now).UnixMilli }}
      {{- end -}}
    
      Dashboard: {{.Annotations.MyDashboardURL}}?from={{$from}}&to={{$to}}
    {{ end }}
    {{ end }}

    Чтобы использовать этот шаблон, определите пользовательскую аннотацию с именем MyDashboardURL, содержащую базовый URL дашборда без параметров from и to. Например: http://localhost:3000/d/uiyahbsdaubsd.

    Запустите шаблон с помощью:

    Go
    {{ template "custom.my_dashboard_url_annotation" . }}
    template_output
    Dashboard: http://localhost:3000/d/uiyahbsdaubsd?from=1740070380000&to=1740071880000

Пользовательская полезная нагрузка JSON

Опция пользовательской полезной нагрузки в точке контакта webhook позволяет настраивать полезную нагрузку уведомлений webhook с помощью пользовательского шаблона.

Следующий пример генерирует пользовательскую полезную нагрузку JSON, выполняя другие шаблоны с помощью tmpl.Exec и используя функции вроде coll.Dict и data.ToJSON для обработки и форматирования данных JSON.

Go
{- /* Generates a pretty-printed JSON payload with alert group info and individual alerts metadata. */ -}}
{{ define "webhook.custom.payload" -}}
  {{ coll.Dict
  "receiver" .Receiver
  "status" .Status
  "alerts" (tmpl.Exec "webhook.custom.simple_alerts" .Alerts | data.JSON)
  "groupLabels" .GroupLabels
  "commonLabels" .CommonLabels
  "commonAnnotations" .CommonAnnotations
  "externalURL" .ExternalURL
  "version" "1"
  "orgId"  (index .Alerts 0).OrgID
  "truncatedAlerts"  .TruncatedAlerts
  "groupKey" .GroupKey
  "state"  (tmpl.Inline "{{ if eq .Status \"resolved\" }}ok{{ else }}alerting{{ end }}" . )
  "allVariables"  .Vars
  "title" (tmpl.Exec "default.title" . )
  "message" (tmpl.Exec "default.message" . )
  | data.ToJSONPretty " "}}
{{- end }}

{{- /* Embed json templates in other json templates. */ -}}
{{ define "webhook.custom.simple_alerts" -}}
  {{- $alerts := coll.Slice -}}
  {{- range . -}}
    {{ $alerts = coll.Append (coll.Dict
    "status" .Status
    "labels" .Labels
    "startsAt" .StartsAt
    "endsAt" .EndsAt
    ) $alerts}}
  {{- end -}}
  {{- $alerts | data.ToJSON -}}
{{- end }}
template_output
{
 "alerts": [
  {
   "endsAt": "0001-01-01T00:00:00Z",
   "labels": {
    "alertname": "InstanceDown",
    "grafana_folder": "Test Folder",
    "instance": "instance1"
   },
   "startsAt": "2025-04-21T10:19:46.179Z",
   "status": "firing"
  },
  {
   "endsAt": "2025-04-22T10:19:46.179Z",
   "labels": {
    "alertname": "CpuUsage",
    "grafana_folder": "Test Folder",
    "instance": "instance1"
   },
   "startsAt": "2025-04-22T06:19:46.179Z",
   "status": "resolved"
  }
 ],
 "allVariables": {},
 "commonAnnotations": {},
 "commonLabels": {
  "grafana_folder": "Test Folder",
  "instance": "instance1"
 },
 "externalURL": "http://localhost:3000/",
 "groupKey": "",
 "groupLabels": {
  "group_label": "group_label_value"
 },
 "message": "**Firing**\n\nValue: B=22, C=1\nLabels:\n - alertname = InstanceDown\n - grafana_folder = Test Folder\n - instance = instance1\nAnnotations:\n - summary = Instance instance1 has been down for more than 5 minutes\nSource: http://grafana.com/alerting/grafana/cdeqmlhvflz40f/view?orgId=1\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana\u0026matcher=alertname%3DInstanceDown\u0026matcher=grafana_folder%3DTest+Folder\u0026matcher=instance%3Dinstance1\u0026orgId=1\nDashboard: http://localhost:3000/d/dashboard_uid?from=1745227186179\u0026orgId=1\u0026to=1745317189058\nPanel: http://localhost:3000/d/dashboard_uid?from=1745227186179\u0026orgId=1\u0026to=1745317189058\u0026viewPanel=1\n\n\n**Resolved**\n\nValue: B=22, C=1\nLabels:\n - alertname = CpuUsage\n - grafana_folder = Test Folder\n - instance = instance1\nAnnotations:\n - summary = CPU usage above 90%\nSource: http://grafana.com/alerting/grafana/oZSMdGj7z/view?orgId=1\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana\u0026matcher=alertname%3DCpuUsage\u0026matcher=grafana_folder%3DTest+Folder\u0026matcher=instance%3Dinstance1\u0026orgId=1\nDashboard: http://localhost:3000/d/dashboard_uid?from=1745299186179\u0026orgId=1\u0026to=1745317186179\nPanel: http://localhost:3000/d/dashboard_uid?from=1745299186179\u0026orgId=1\u0026to=1745317186179\u0026viewPanel=1\n",
 "orgId": 1,
 "receiver": "TestReceiver",
 "state": "alerting",
 "status": "firing",
 "title": "[FIRING:1, RESOLVED:1] group_label_value (Test Folder instance1)",
 "truncatedAlerts": null,
 "version": "1"
}