转载自:https://www.cnblogs.com/dogfei/p/14552186.html

本篇文章主要介绍如何编写alertmanager的告警模板,使用这个告警模板,可以格式化我们的告警信息,让告警内容更加易读和美观

prometheus 告警规则详解: https://www.dogfei.cn/archives/alertmanager-rule prometheus 配置文件参考与介绍: https://www.dogfei.cn/archives/prometheus-config

告警模板 上篇文章介绍了关于告警规则的一些编写,在使用企业微信告警的时候,提到了告警模板,这里详细说下告警模板如何写。

首先,告警模板是基于go语言的模板来写的,具体可参考官方文档:https://golang.org/pkg/text/template/,这里列举一些常用的写法,然后再去看下面的示例,就知道什么意思了。

"."的用法 写过helm的一定知道这个'.',就是你定义了一个模板,当给这个模板传数据的时候,可以使用'.'来访问获取对应的变量

{{ .Country.Name.Age }} 这种就是通过链式访问这个复杂类型的数据。

模板变量 在模板中定义了变量后,在整个模板中都能使用,例如:

{{ $Name := "fei" }} hello {{ $Name }} define {{ define "this.is.template" }} 定义了一个名为"this.is.template"的模板

if/else语句 满足条件继续执行,不满足则去执行else,不满足条件可以是一些空值,或者false,例如false,0,nill,空字符串

{{ if .Name }} hello {{ .Name }} {{ else }} no one!!! {{ end }} 这里就是判断Name是否有值,有就会输出hello {{ .Name }},没有输出no one,结束用{{ end }} 多条件可以使用

{{ if .Name1 }} hello {{ .Name1 }} {{ else if .Name2 }} hello {{ .Name2 }} {{ else }} no one {{ end }} Range语法 模板里使用range来进行遍历数据,类似于jinja2模板语言中的for,例如: 假设数据结构为:

type Info struct { Name string Age int } 然后模板写法如下:

{{ range .Info }} name: {{ .Name }} age: {{ .Age }} {{ end }} 比较 eq 等于 ne 不等于 lt 小于 le 小于等于 gt 大于 ge 大于等于 可以做判断比较之类的 {{ if gt .Number1 .Number2 }} {{ .Number1 }}大于{{ .Number2 }} {{ end }} 逻辑运算 and 全都满足,返回true not 取反 or 有一个为true,即可返回true 做一些逻辑运算,比如说 {{ if and .Username .Passwd }} begin login {{ if gt (len .Passwd) 16 }} passwd valid {{ end }} {{ else }} login faild {{ end }} {{ if not .Authenticated }} access deny {{ end }} 内置函数 title: 将字符串转换为首字母大写 toUpper: 所有字母转换成大写 toLower: 所有字母转换成小写 join: 拼接字符串 safeHtml: 将字符串标记为不需要自动转义的html len: 获取长度 简单举例:

{{ "abcd" | toUpper }} {{ "ABCD" | toLower }} {{ .Values | join "," }} 移除空格 写过ansible-playbook的一定知道,在使用jinja2写模板的时候,缩进、空格会让人很头疼,go语言的模板同样也是如此,也是使用-减号来做处理

{{- }} #去掉左边的空格 {{ -}} #去掉右边的空格 {{- -}} #去掉两边所有的空格 数据结构介绍 .Receiver: 接收器的名称 .Status: 如果正在告警,值为firing,恢复为resolved .Alerts: 所有告警对象的列表,是一个列表, .Alerts.Firing: 告警列表 .Alerts.Resolved: 恢复列表 .GroupLabels: 告警的分组标签 .CommonLabels: 所有告警共有的标签 .CommonAnnotations: 所有告警共有的注解 .ExternalURL: 告警对应的alertmanager连接地址 具体可以看下报警出来的信息:

{ 'receiver': 'webhook', 'status': 'firing', 'alerts': [{ 'status': 'firing', 'labels': { 'alertname': '内存使用率', 'instance': '10.127.92.100', 'job': 'sentry', 'severity': 'warning', 'team': 'ops' }, 'annotations': { 'description': '内存使用率已超过55%,内存使用率:58%', 'summary': '内存使用率' }, 'startsAt': '2020-12-30T07:20:08.775177336Z', 'endsAt': '0001-01-01T00:00:00Z', 'generatorURL': 'http://prometheus-server:9090/graph?g0.expr=round%28%281+-+%28node_memory_MemAvailable_bytes%7Bjob%3D%22sentry%22%7D+%2F+%28node_memory_MemTotal_bytes%7Bjob%3D%22sentry%22%7D%29%29%29+%2A+100%29+%3E+55&g0.tab=1', 'fingerprint': '09f94bd1aa7da54f' }], 'groupLabels': { 'alertname': '内存使用率' }, 'commonLabels': { 'alertname': '内存使用率', 'job': 'sentry', 'severity': 'warning', 'team': 'ops' }, 'commonAnnotations': { 'summary': '内存使用率' }, 'externalURL': 'http://alertmanager-server:9093', 'version': '4', 'groupKey': '{}:{alertname="内存使用率"}', 'truncatedAlerts': 0 } 这么一看是不是就清晰了。

模板参考示例 下面看一下示例

官方模板参考:https://raw.githubusercontent.com/prometheus/alertmanager/master/template/default.tmpl

{{ define "wechat.default.message" }} {{- if gt (len .Alerts.Firing) 0 -}} // 判断报警列表的长度是否大于0,大于0说明有报警,否则没有 {{- range $index, $alert := .Alerts -}} // 遍历所有的告警列表,$index是索引,$alert是每一个报警元素 ==========异常告警========== 告警类型: {{ $alert.Labels.alertname }} 告警级别: {{ $alert.Labels.severity }} 告警详情: {{ $alert.Annotations.description}};{{$alert.Annotations.summary}} 故障时间: {{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }} // 调整为北京时间 {{- if gt (len $alert.Labels.instance) 0 }} // 判断下是否存在instance 实例信息: {{ $alert.Labels.instance }} {{- end }} ============END============ {{- end }} {{- end }} {{- if gt (len .Alerts.Resolved) 0 -}} // 判断恢复列表长度是否大于0,大于0说明有恢复信息,否则没有 {{- range $index, $alert := .Alerts -}} //遍历恢复列表 ==========异常恢复========== 告警类型: {{ $alert.Labels.alertname }} 告警级别: {{ $alert.Labels.severity }} 告警详情: {{ $alert.Annotations.description}};{{$alert.Annotations.summary}} 故障时间: {{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }} #调整为北京时间 恢复时间: {{ ($alert.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }} #调整为北京时间 {{- if gt (len $alert.Labels.instance) 0 }} 实例信息: {{ $alert.Labels.instance }} {{- end }} ============END============ {{- end }} {{- end }} {{- end }} 需要特别说明下告警信息里的时间是utc时间,需要转换为北京时间,也就是在utc时间的基础上加8小时,也就是28800秒,也就是这里写的28800e9

基本上到这儿,我们对如何编写告警信息模板有了一个很清晰的认识,下面看下如何配置到alertmanager里,其实之前的文章也说过了,下面再说下:

receivers:

  • name: 'wechat' wechat_configs:
    • send_resolved: true message: '{{ template "wechat.default.message" . }}' to_party: '接收告警的部门ID' agent_id: '应用ID' to_user: '用户ID' api_secret: '部门secret' wechat.default.message就是上面define的模板名称