Configure notification templates and webhook templates
When an alert rule in a notification policy is triggered, ARMS sends alert notifications through channels such as DingTalk, Lark, WeCom, SMS, phone, email, and webhooks. ARMS provides pre-configured notification templates for each notification method. If these default templates do not meet your needs, you can customize them. This topic explains the Go template syntax for customization, describes the pre-configured templates, and lists the available template variables.
Go template syntax
ARMS alert notification templates use the Go template syntax to populate the template with data from a provided context.
Alert parameters in a notification template consist of multiple labels. Labels allow you to include specific alert parameters in your notifications. For example, the alertname label in this example indicates the alert name.
This topic uses the following sample code to describe common Go template syntax.
{
"alerts": [
{
"annotations": {
"message": "Namespace: arms-prom / Pod: kube-state-metrics-ccb59dbff-jljg4 / Container: kube-state-metrics memory usage has exceeded 80%, current value 15.52%",
"value": "15.521240234375"
},
"endsAt": "2023-02-22T07:27:15.404000000Z",
"fingerprint": "bec72890cc2c7b4a027e008df0cd1013",
"labels": {
"container": "kube-state-metrics",
"severity": "warning",
"instance": "10.0.80.186:10255",
"clustername": "klyz1688-kubernetes-1",
"alertname": "Container memory usage exceeds 80%",
"_aliyun_arms_involvedObject_name": "klyz1688-kubernetes-1",
"pod_name": "kube-state-metrics-ccb59dbff-jljg4",
"_aliyun_arms_involvedObject_kind": "cluster",
"name": "k8s_kube-state-metrics_kube-state-metrics-ccb59dbff-jljg4_arms-prom_359508f3-7e76-4740-b915-41ea48849641_0",
"namespace": "arms-prom"
},
"startsAt": "2023-02-22T07:18:15.578000000Z",
"status": "firing"
}
],
"commonAnnotations": {
"message": "Namespace: arms-prom / Pod: kube-state-metrics-ccb59dbff-jljg4 / Container: kube-state-metrics memory usage has exceeded 80%, current value 15.52%",
"value": "15.521240234375"
},
"commonLabels": {
"container": "kube-state-metrics",
"severity": "warning",
"instance": "10.0.80.186:10255",
"clustername": "klyz1688-kubernetes-1",
"alertname": "Container memory usage exceeds 80%",
"_aliyun_arms_involvedObject_name": "klyz1688-kubernetes-1",
"pod_name": "kube-state-metrics-ccb59dbff-jljg4",
"_aliyun_arms_involvedObject_kind": "cluster",
"name": "k8s_kube-state-metrics_kube-state-metrics-ccb59dbff-jljg4_arms-prom_359508f3-7e76-4740-b915-41ea48849641_0",
"namespace": "arms-prom"
},
"groupLabels": {
"alertname": "Container memory usage exceeds 80%"
},
"status": "firing",
"startTime":"2023-02-22 07:18:15",
"endTime":"Alert resolution time",
"level":"error",
"dispatchRuleName":"notification policy name",
"alarmId":"123456"
},
The . character
Represents the current object in scope, allowing you to access its data.
Example 1: Get all content from the top-level scope, which is the entire context data from the sample code.
{{ . }}
Returns the entire content of the sample code.
Example 2: Get the level field from the context data.
{{ .level }}
Returns:
error
Example 3: Get the commonLabels.alertname field from the context data.
{{ .commonLabels.alertname }}
Returns:
Container memory usage exceeds 80%
Variables
You can store data passed to the template in variables that are accessible throughout the template. For example, in {{$context := .}}, the $context variable stores the incoming data, which you can access using {{$context}}.
Example 1: Assign the alert name to $alertname, and then output $alertname.
{{ $alertname := .commonLabels.alertname }} {{$alertname}}
Returns:
Container memory usage exceeds 80%
Example 2: Assign the first alert from the alerts list to $alert0 and output its alertname.
{{ $alert0 := index .alerts 0 }} {{$alert0.labels.alertname}}
Returns:
Container memory usage exceeds 80%
The if/else action
The if action provides conditional logic. If the condition is false, an optional else block is executed. Values like 0, nil, or an empty string are evaluated as false.
Example 1: If the value of the severity label in an alert event is warning, output P3 alert.
{{if eq "warning" .commonLabels.severity }} P3 alert {{ end }}
Returns:
P3 alert
Example 2: If the value of the severity label in an alert event is critical, output P1 alert. Otherwise, output P2 alert.
{{if eq "critical" .commonLabels.severity }} P1 alert {{ else }} P2 alert {{ end }}
Returns:
P2 alert
The for action
The for action executes a block of code repeatedly.
Example 1: Iterate through the alerts list to get the alertname of each alert.
{{ for .alerts}} {{.labels.alertname}} \n {{end}}
Returns:
Container memory usage exceeds 80%
The range action
The range action iterates over a data structure, such as a slice or map.
Example 1: Iterate over a list to get the index and value of each element.
{{ range $index, $alert := .alerts }}Index {{ $index }}: {{ $alert.labels.alertname }}\n{{ end }}
Returns:
Index 0: Container memory usage exceeds 80%
The index function
The index function accesses an element of an array, slice, or map.
Example 1: Get the first element from the alerts list and assign it to $alert0.
{{ $alert0 := index .alerts 0 }} {{$alert0.labels.alertname}}
Returns:
Container memory usage exceeds 80%
Comparison functions
The following comparison functions are commonly used:
-
eq: Equal to -
ne: Not equal to -
lt: Less than -
le: Less than or equal to -
gt: Greater than -
ge: Greater than or equal to
Example: If the value of the severity label in commonLabels is equal to warning, output P3 alert.
{{if eq "warning" .commonLabels.severity }} P3 alert {{ end }}
Returns:
P3 alert
Logical functions: and, or, not
Example: If the value of the severity label in commonLabels is equal to warning or warnning, output P3 alert.
{{if or (eq "warning" .commonLabels.severity) (eq "warnning" .commonLabels.severity) }} P3 alert {{ end }}
Returns:
P3 alert
Common built-in functions
printf: Formats a string according to a specified format specifier.
Example: Output the value of the first alert in the alerts list, formatted to two decimal places.
{{ $alert0 := index .alerts 0 }} {{ printf "%.2f" $alert0.annotations.value }}
Returns:
15.52
humanizePercentage: Formats a value as a percentage.
Example: Convert the string "0.95332123123124" to a more readable percentage.
{{ "0.95332123123124" | humanizePercentage }}
Returns:
95.33%
humanizeDate: Formats a millisecond timestamp into a date. The date format is yyyy-MM-dd HH:mm:ss.
Example: Convert the timestamp 1671074058234 to a date.
{{ "1671074058234" | humanizeDate }}
Returns:
2022-12-15 11:14:18
len: Returns the length of an array, slice, string, or map.
Example: Get the length of the alerts list.
{{ len .alerts }}
Returns:
1
Pre-configured notification templates
Email notification template
Alert name: {{ .commonLabels.alertname }}
{{if .commonLabels.clustername }}
Cluster name: {{ .commonLabels.clustername }}
{{ end }}
{{if eq "app" .commonLabels._aliyun_arms_involvedObject_kind }}
Application name: {{ .commonLabels._aliyun_arms_involvedObject_name }}
{{ end }}
Notification policy: {{ .dispatchRuleName }}
Alert time: {{ .startTime }}
Alert content: {{ if .newIncidentIn }} (New event) {{end}} {{ for .alerts }} {{ .annotations.message }} {{if .generatorURL }} <a href="{{.generatorURL}}" >Details URL</a> {{ end }} {{ end }}
|
Template content |
Description |
|
The alert name. By default, a notification policy groups alerts by the |
|
If an event contains the |
|
If the involved object's kind is |
|
The name of the matching notification policy. |
|
The time when the alert was first triggered. |
|
Iterate over the list of alert events to render the Note
The pre-configured template uses HTML
The |
Example of rendered output:
Alert name: Container memory usage exceeds 80%
Cluster name: klyz1688-kubernetes-1
Notification policy: notification policy name
Alert time: 2023-02-22 07:18:15
Alert content: Namespace: arms-prom / Pod: kube-state-metrics-ccb59dbff-jljg4 / Container: kube-state-metrics memory usage has exceeded 80%, current value 15.52%
SMS and phone notification templates
These templates are similar to the email template but omit the details URL.
{{ .level }} alert occurred
Alert name: {{ .commonLabels.alertname }}
{{if .commonLabels.clustername }}
Cluster name: {{ .commonLabels.clustername }}
{{ end }}
{{if eq "app" .commonLabels._aliyun_arms_involvedObject_kind }}
Application name: {{ .commonLabels._aliyun_arms_involvedObject_name }}
{{ end }}
Notification policy: {{ .dispatchRuleName }}
Alert time: {{ .startTime }}
Alert content: {{ if .newIncidentIn }} (New event)
{{end}} {{ for .alerts }} {{ .annotations.message }} {{ end }}
Chatbot notification template
{{ if .newIncidentIn }} (New event) {{end}}
{{if .commonLabels.clustername }} > Cluster name: {{ .commonLabels.clustername }}
{{ end }}
{{if eq "app" .commonLabels._aliyun_arms_involvedObject_kind }} > Application name: {{ .commonLabels._aliyun_arms_involvedObject_name }}
{{ end }}
{{ for .alerts }} > {{ .annotations.message }} {{if .generatorURL }} [details URL]({{.generatorURL}}) {{end}}{{if .annotations._aliyun_arms_insights_analyze_link }}[<font color='#ff0000'>root cause</font>]({{ .annotations._aliyun_arms_insights_analyze_link}}){{ end }}{{if eq "1" .labels._aliyun_arms_denoise_code }} (Important:{{.labels._aliyun_arms_important_reason }}) {{end}}
{{end}}
The output is rendered in Markdown. Feature support varies by chatbot.
-
Blockquote:
> -
Font color:
<font color='#ff0000'>root cause</font>NoteOnly DingTalk and WeCom support font color changes. Lark does not.
-
Line breaks:
-
DingTalk: Add two newlines in the template.
-
Lark: Add one newline in the template.
-
WeCom: Add one newline in the template.
-
Webhook template
{
"alert_name":"{{ .commonLabels.alertname }}",
{{if .commonLabels.clustername }}"cluster_name":"{{ .commonLabels.clustername }}",{{ end }}
{{if eq "app" .commonLabels._aliyun_arms_involvedObject_kind }}"application_name":"{{ .commonLabels._aliyun_arms_involvedObject_name }}",{{ end }}
"notification_policy":"{{ .dispatchRuleName }}",
"alert_time":"{{ .startTime }}",
"alert_content":"{{ range $index, $alert := .alerts }}{{if $index}}, {{end}}{{.annotations.message}}{{ end }}"
}
Example of rendered output:
{
"alert_name": "Container memory usage exceeds 80%",
"cluster_name": "klyz1688-kubernetes-1",
"notification_policy": "notification policy name",
"alert_time": "2023-02-22 07:18:15",
"alert_content": "Namespace: arms-prom / Pod: kube-state-metrics-ccb59dbff-jljg4 / Container: kube-state-metrics memory usage has exceeded 80%, current value 15.52%"
}
Variable reference
The following table describes the variables available in notification templates.
|
Parameter |
Description |
|
alarmId |
The ID of the original alert. |
|
alerts |
A list of the original alert events. Type: List<Alert>. |
|
alerts.annotations |
The annotations of an original alert. Type: map of strings. |
|
alerts.endsAt |
The resolution time of the original alert. Resolution time = Trigger time + Resolution duration |
|
alerts.startsAt |
The trigger time of the original alert. |
|
alerts.fingerprint |
The fingerprint of the original alert. Alerts with the same set of labels have the same fingerprint. |
|
alerts.labels |
The labels of the original alert. |
|
alerts.status |
The status of an original alert:
|
|
commonAnnotations |
A set of annotations that are common to all alerts in the group. |
|
commonLabels |
A set of labels that are common to all alerts in the group. |
|
groupLabels |
The labels used to group the alerts, as defined in the notification policy. |
|
status |
The status of the alert group:
|
|
startTime |
The time when the alert group was created. |
|
endTime |
The time when the alert group was resolved. This is the resolution time of the last original alert in the group. |
|
level |
The severity level of the notification. The values map to priority levels:
|
|
dispatchRuleName |
The name of the matching notification policy. |