一、Prometheus告警功能概述
Prometheus对指标的收集、存储同告警能力分别由Prometheus Server和 AlertManager两个独立的组件完成。Prometheus Server负责生成告警,AlertManager负责发送告警。
对于AlertManager而言,客户端通常是Prometheus Server,但它也支持接收来自其它工具的告警。通常,AlertManager对告警通知进行分组、去重后,根据路由规则将其路由到不同的接收方,比如Email、短信等。
二、Prometheus的告警逻辑
需要配置Prometheus成为AlertManager的客户端。而AlertManager本身也是应用程序,它也应该被纳入Prometheus的监控目标。
配置逻辑如下:
- 在Prometheus Server定义告警规则(alert rule),Prometheus会周期性的对告警规则进行计算,如果满足告警触发条件就向AlertManager发送告警通知。
- 在AlertManager定义路由规则(route,即满足什么匹配条件就发送给谁),以便将收到的告警通知按需分别进行处理。
- 在AlertManager定义接收人(receiver),他们通常是基于某个媒介接收告警信息的指定用户。
三、AlertManager的核心概念(功能)
除了基本的告警通知能力外,AlertManager还支持对告警进行去重、分组、抑制、静默和路由等功能。
3.1 分组(Grouping)
将相似告警合并为单个告警通知的机制,在系统因大面积故障而触发告警潮时,分组机制能避免用户被大量的告警噪声淹没,进而导致关键信息的隐没。
3.2 抑制(Inhibition)
系统中某个组件或服务故障触发告警通知后,那些依赖于该组件或服务的其它组件或服务可能也会因此触发告警,抑制便是避免类似的级联告警的一种特性,从而让用户能够将精力集中于真正的故障所在。
抑制的关键作用在于,同时存在的两组告警条件中,级别更高的一组生效,使得级别更低的一组失效。例如,关于内存空闲比例定义了两条告警规则,一个是
3.3 静默(Slient)
是指在一个特定的时间窗口内,即使接到告警通知,AlertManager也不会向用户发送告警信息的行为。通常,在系统例行维护期间,需要激活告警服务的静默特性。
3.4 路由(Route)
用于配置AlertManager如何处理和传入特定类型的告警通知,其基本逻辑是根据路由匹配规则的匹配结果来确定处理当前告警通知的路径和行为。
四、部署AlertManager
当Prometheus Server服务器负载较重时,也可将AlertManager部署在其它服务器上。这里就在Prometheus Server服务器之外的其它服务器部署AlertManager。
4.1 部署软件包
wget https://github.com/prometheus/alertmanager/releases/download/v0.26.0/alertmanager-0.26.0.linux-amd64.tar.gz
tar -xf alertmanager-0.26.0.linux-amd64.tar.gz
mv alertmanager-0.26.0.linux-amd64 /usr/local/alertmanager
#创建存储目录
mkdir /usr/local/alertmanager/data
4.2 为AlertManager设置systemd unit配置文件
vim /lib/systemd/system/alertmanager.service
[Unit]
Descriptinotallow=Prometheus Alertmanager
After=network.target
[Service]
ExecStart=/usr/local/alertmanager/alertmanager --config.file=/usr/local/alertmanager/alertmanager.yml --storage.path=/usr/local/alertmanager/data
Restart=on-failure
[Install]
WantedBy=multi-user.target
systemctl start alertmanager && systemctl enable alertmanager
启动9093端口说明AlertManager服务启动成功。
启动参数介绍如下:
- –config.file:指定AlertManager配置文件。
- –storage.path:指定AlertManager的数据存储目录。
- –data.retention:指定历史数据保留时间,默认为120h,即5天。
- –log.level:日志级别。可选项为[debug, info, warn, error]。
- –log.format:日志输出格式,可选项为[logfmt, json]。
五、AlertManager配置文件解析
具体可参考https://prometheus.io/docs/alerting/latest/configuration,这里以配置邮件告警为例来说明。
cat /usr/local/alertmanager/alertmanager.yml
#global配置段定义全局配置
global:
#当Alertmanager持续多长时间未接收到告警后标记告警状态为resolved(已解决),默认为5分钟
resolve_timeout: 5m
#SMTP邮件服务器配置
smtp_smarthost: 'smtp.qq.com:465'
#发件人邮箱
smtp_from: 'xxxx@qq.com'
#发件人用户名
smtp_auth_username: 'xxxx@qq.com'
#邮箱授权码
smtp_auth_password: 'xxxxxx'
smtp_hello: 'qq.com'
smtp_require_tls: false
#templates配置段定义告警模板文件
templates:
- '/etc/alertmanager/template/*.tmpl'
#route配置段定义如何处理传入的告警,此为根路由
route:
#报警分组使用的标签。分组就是将多条告警信息聚合成一条发送,告警信息通过标签进行分组
group_by: ['alertname', 'cluster']
#第一次等待多长时间即发送告警通知。这种方式可以确保有足够的时间为同一分组获取多个告警,然后一起触发这个告警信息
group_wait: 30s
#发送第一个告警后,再发送新告警的等待时间
group_interval: 1m
#分组内发送相同告警的时间间隔。这里的配置是每5分钟发送告警到分组中。举个例子:收到告警后,一个分组被创建,等待1分钟发送组内告警,如果后续组内的告警信息相同,这些告警会在5分钟后发送,但是5分钟内这些告警不会被发送。
repeat_interval: 5m
#发送警报的接收者的名称
receiver: 'team-X-mails'
##下面配置的是子路由,子路由的属性继承于根路由(即上面的配置),在子路由中可以覆盖根路由的配置
routes:
#基于正则表达式验证当前告警标签的值是否满足正则表达式的内容
- match_re:
service: ^(foo1|foo2|baz)$
receiver: team-X-mails
#此为子路由的子路由
routes:
#基于字符串匹配告警
- match:
#含有severity=critical标签的警报就发给team-X-pager
severity: critical
receiver: team-X-pager
- match:
service: files
receiver: team-Y-mails
routes:
- match:
severity: critical
receiver: team-Y-pager
# inhibit_rules配置段用于定义抑制规则。抑制规则允许在另一个警报正在触发的情况下使一组警报静音
inhibit_rules:
#如果同一对应的告警条目之上已经有了critical级别告警规则,则warning级别的告警规则不用处理
- source_matchers:
- severity="critical"
target_matchers:
- severity="warning"
#如果警报名称相同,则应用抑制规则。
#注意:如果equal中列出的所有标签的值相同,说明是同一种告警规则。根据源警报和目标警报,将应用抑制规则
equal: ['alertname']
#receivers配置段定义告警信息的接收器
receivers:
- name: 'team-X-mails'
email_configs:
- to: 'team-X+alerts@example.org, team-Y+alerts@example.org'
#当告警问题得到解决时,是否将服务恢复的信息也发给用户。默认为false
send_resolved: true
##html和headers字段用来丰富告警内容
#调用模板对告警信息格式化
html: '{{ template "email.default.html" . }}'
#定义邮件头(以键值对形式)
headers: { Subject: " {{ .CommonAnnotations.summary }}" }
使用的配置文件内容如下:
global:
resolve_timeout: 2m
#SMTP邮件服务器配置
smtp_smarthost: 'smtp.qq.com:465'
#发件人邮箱
smtp_from: 'xxx@qq.com'
#发件人用户名
smtp_auth_username: 'xxx@qq.com'
#邮箱授权码
smtp_auth_password: 'xsvcxuzbhzxecgjd'
smtp_hello: 'qq.com'
smtp_require_tls: false
templates:
- '/usr/local/alertmanager/template/*.tmpl'
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 1m
repeat_interval: 10m
receiver: 'email'
receivers:
- name: 'email'
email_configs:
#收件人邮箱
- to: 'xxx@qq.com'
send_resolved: true
headers:
subject: "{{ .Status | toUpper }} {{ .CommonLabels.env }}:{{ .CommonLabels.cluster }} {{ .CommonLabels.alertname }}"
html: '{{ template "email.default.html" . }}'
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']
六、警报通知接收器
6.1 Prometheus配置邮箱告警
6.1.1 邮箱告警模板配置
在/usr/local/alertmanager/template目录下也准备好了对应的告警模板文件email_template.tmpl,内容见下图,用于在AlertManager中将原有的告警信息通过模板作进一步的格式化处理。上半部分是针对告警信息的格式化,下半部分是针对告警恢复信息的格式化。
6.1.2 Prometheus rule文件配置
这里就使用之前部署的黑盒监控去定义告警规则,采用邮件方式告警。
#在Prometheus Server服务器操作
mkdir /usr/local/prometheus/rule && cd /usr/local/prometheus/rule
vim alert_blackbox.yml
groups:
- name: blackbox
rules:
# Blackbox probe failed
- alert: BlackboxProbeFailed
expr: probe_success == 0
for: 0m
labels:
severity: critical
annotations:
summary: Blackbox probe failed (instance {{ $labels.instance }})
description: "Probe failedn VALUE = {{ $value }}n LABELS = {{ $labels }}"
# Blackbox slow probe
- alert: BlackboxSlowProbe
expr: avg_over_time(probe_duration_seconds[1m]) > 1
for: 1m
labels:
severity: warning
annotations:
summary: Blackbox slow probe (instance {{ $labels.instance }})
description: "Blackbox probe took more than 1s to completen VALUE = {{ $value }}n LABELS = {{ $labels }}"
# Blackbox probe HTTP failure
- alert: BlackboxProbeHttpFailure
expr: probe_http_status_code = 400
for: 0m
labels:
severity: critical
annotations:
summary: Blackbox probe HTTP failure (instance {{ $labels.instance }})
description: "HTTP status code is not 200-399n VALUE = {{ $value }}n LABELS = {{ $labels }}"
# Blackbox probe slow HTTP
- alert: BlackboxProbeSlowHttp
expr: avg_over_time(probe_http_duration_seconds[1m]) > 1
for: 1m
labels:
severity: warning
annotations:
summary: Blackbox probe slow HTTP (instance {{ $labels.instance }})
description: "HTTP request took more than 1sn VALUE = {{ $value }}n LABELS = {{ $labels }}"
# Blackbox probe slow ping
- alert: BlackboxProbeSlowPing
expr: avg_over_time(probe_icmp_duration_seconds[1m]) > 1
for: 1m
labels:
severity: warning
annotations:
summary: Blackbox probe slow ping (instance {{ $labels.instance }})
description: "Blackbox ping took more than 1sn VALUE = {{ $value }}n LABELS = {{ $labels }}"
6.1.3 告警规则说明
在告警规则中,有着类似或相关联功能的告警规则可组织为group,从而为规则名称提供“名称空间”。一个组内的告警规则必须有名称,且在该组内其名称必须唯一。
- alert:告警规则的名称,其格式要遵循label取值的语法要求。
- expr:基于PromQL的告警触发条件(布尔表达式),用于计算是否有时间序列可以满足该条件。
- for:控制在触发告警之前,布尔表达式的值为true的时长。当表达式值为true,但其持续时间未能满足for定义的时长时,相关的告警状态为pending;满足该时长后,相关的告警将被触发,并转为firing状态;表达式的值为false时,告警处于inactive状态。
- labels:告警规则被激活时,相关时间序列上的所有标签都会添加到生成告警实例之上,而labels则允许用户在告警上附加其它自定义的标签,该类标签值支持模板化。
- annotations:附加在告警上的注解信息,其格式类似于标签,但不能被用于标识告警实例;常用于存储告警摘要,且其值支持模板化。
6.1.4 告警模板说明
Prometheus支持在告警中使用模板(即模板子串)。告警模板是指在告警中的标签和注解上引用时间序列的标签和样本值的方法。它使用标准的go语法,并暴露一些包含时间标签和值的变量。
标签引用:{{$label.
指标样本值引用:{{$value}}
若要在注解中引用触发告警的时间序列上的instance和job标签的值,可分别使用“{{$label.instance}}”和“{{$label.job}}”。
6.1.5 Prometheus加载rule文件
在prometheus.yml添加如下配置:
alerting:
alertmanagers:
- static_configs:
- targets: #指定alertmanager地址,可指定多个
- 192.168.131.12:9093
rule_files: #指定要加载的rule文件
- "rule/alert_*.yml"
#热加载配置
curl -XPOST 192.168.131.11:9090/-/reload
此时可以看到,规则已经发挥了作用,也出现了告警信息。告警变为Firing状态,如下图,就表示已经将告警发送到AlertManager。
Prometheus中的告警存在3种状态:
- inactive:表示无事件发生,没有告警。
- pending:已经触发阈值但未满足告警持续时间(即rule文件中的for字段)。
- firing:已经触发阈值且满足持续时间,并且已经将告警发送至Alertmanager。
开启邮箱授权
目标邮箱也看到相关告警通知,也用上了指定的模板。
6.2 Prometheus配置企业微信告警
6.2.1 AlertManager相关配置介绍
#故障恢复后是否发送通知
[ send_resolved: | default = false ]
#调用WeChat API时使用的API Key,可在企业微信后台中添加的告警机器人上获取该信息
[ api_secret: | default = global.wechat_api_secret ]
# The WeChat API URL.
[ api_url: | default = global.wechat_api_url ]
#企业微信中的企业ID
[ corp_id: | default = global.wechat_api_corp_id ]
#微信消息内容,支持使用模板格式化告警信息,默认使用名为“wechat.default.message”的模板
[ message: | default = '{{ template "wechat.default.message" . }}' ]
#消息格式,支持“text”和“markdown”
[ message_type: | default = 'text' ]
[ agent_id: | default = '{{ template "wechat.default.agent_id" . }}' ]
#如果需要发送给指定用户可以使用to_user,@all表示所有人
[ to_user: | default = '{{ template "wechat.default.to_user" . }}' ]
#部门ID,即发送给指定的部门。部门ID可以在企业微信通讯录获得
[ to_party: | default = '{{ template "wechat.default.to_party" . }}' ]
[ to_tag: | default = '{{ template "wechat.default.to_tag" . }}' ]
6.2.2 注册企业微信
访问企业微信官网,注册企业微信账号。之后在企业微信群添加群机器人。
之后点击该机器人中Secret的查看按钮即可获取该机器人的密钥(后续会用到,对应的是api_secret参数)。
部门ID可通过通讯录获取。
6.2.3 企业微信告警模板配置
在/usr/local/alertmanager/template目录下有个wechat_template.tmpl模板文件,这里定义了名为wechat.default.message的模板,也是默认使用的模板。内容如下:
{{ define "wechat.default.message" }}
{{- if gt (len .Alerts.Firing) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 }}
========= 监控报警 =========
告警状态:{{ .Status }}
告警级别:{{ .Labels.severity }}
告警类型:{{ $alert.Labels.alertname }}
故障主机: {{ $alert.Labels.instance }}
告警主题: {{ $alert.Annotations.summary }}
告警详情: {{ $alert.Annotations.message }}{{ $alert.Annotations.description}};
触发阈值:{{ .Annotations.value }}
故障时间: {{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
========= = end = =========
{{- end }}
{{- end }}
{{- end }}
{{- if gt (len .Alerts.Resolved) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 }}
========= 异常恢复 =========
告警类型:{{ .Labels.alertname }}
告警状态:{{ .Status }}
告警主题: {{ $alert.Annotations.summary }}
告警详情: {{ $alert.Annotations.message }}{{ $alert.Annotations.description}};
故障时间: {{ ($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 }}
{{- end }}
6.2.4 AlertManager配置企业微信告警渠道
templates:
- '/usr/local/alertmanager/template/wechat_template.tmpl'
route:
…
receiver: 'wechat'
…
receivers:
- name: 'wechat'
wechat_configs:
- corp_id: ww153923be29cf5398
to_user: '@all'
to_party: '2'
agent_id: 1000002
api_secret: L7CGANEeYlU5-sg1qcLeB-jk7gbJ_8MKVbd37tl905g
send_resolved: true
#之后重载AlertManager配置
curl -XPOST http://192.168.131.12:9093/-/reload
还是使用之前的黑盒监控的告警规则做验证,此时在Prometheus界面和AlertManager界面都能看到有新的告警生成。
但由于企业微信增加了对IP的限制,我所使用的IP不在可信IP之内,所以这里没有在企业微信收到告警信息。AlertManager报错信息如下:
level=error compnotallow=dispatcher msg="Notify for alerts failed" num_alerts=1 err="wechat/wechat[0]: notify retry canceled due to unrecoverable error after 1 attempts: not allow to access from your ip, hint: [1697624345500614210513454], from ip: 117.36.7.3, more info at https://open.work.weixin.qq.com/devtool/query?e=60020"
可以在之前创建的企业微信应用详情界面下选择添加可信IP解决此问题。但是由于个人没有公网IP或域名进行校验,所以此处无法演示。
6.3 Prometheus配置钉钉告警
6.3.1 AlertManager相关配置介绍
#故障恢复后是否发送通知
[ send_resolved: | default = false ]
#HTTP POST请求发向的目标地址
url:
#HTTP客户端配置,主要包括认证信息等
[ http_config: | default = global.http_config ]
#在单次webhook调用中允许发送的告警信息的个数
#多出的部分将自动被移除,默认值0表示不限制
[ max_alerts: | default = 0 ]
6.3.2 创建钉钉告警机器人
6.3.3 安装钉钉告警插件
wget https://github.com/timonwong/prometheus-webhook-dingtalk/releases/download/v2.1.0/prometheus-webhook-dingtalk-2.1.0.linux-amd64.tar.gz
tar -xf prometheus-webhook-dingtalk-2.1.0.linux-amd64.tar.gz
mv prometheus-webhook-dingtalk-2.1.0.linux-amd64 /usr/local/prometheus-webhook-dingtalk
6.3.4 修改钉钉告警插件的配置文件
cat /usr/local/prometheus-webhook-dingtalk/config.yml
#针对告警信息内容格式化,具体指向哪个模板文件
templates:
- /usr/local/prometheus-webhook-dingtalk/template/dingtalk_template.tmpl
## You can also override default template using `default_message`
## The following example to use the 'legacy' template from v0.3.0
default_message:
title: '{{ template "legacy.title" . }}'
text: '{{ template " dingtalk.default.message " . }}'
## Targets, previously was known as "profiles"
targets:
webhook1:
#钉钉机器人的webhook,在创建完钉钉机器人后会看到
url: https://oapi.dingtalk.com/robot/send?access_token=xxxxx
#加签后的值
secret: SECxxxxx
6.3.5 钉钉告警模板配置
在/usr/local/prometheus-webhook-dingtalk/template目录下有个dingtalk_template.tmpl的模板文件,内容如下:
{{ define "dingtalk.default.message" }}
{{- if gt (len .Alerts.Firing) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 }}
========= 监控告警 =========
告警状态:{{ .Status }}
告警级别:{{ .Labels.severity }}
告警类型:{{ $alert.Labels.alertname }}
故障主机: {{ $alert.Labels.instance }}
告警主题: {{ $alert.Annotations.summary }}
告警详情: {{ $alert.Annotations.message }}{{ $alert.Annotations.description}}
触发阈值:{{ .Annotations.value }}
故障时间: {{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
=========== End ===========
{{- end }}
{{- end }}
{{- end }}
{{- if gt (len .Alerts.Resolved) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 }}
========= 故障恢复 =========
告警类型:{{ .Labels.alertname }}
告警状态:{{ .Status }}
告警主题: {{ $alert.Annotations.summary }}
告警详情: {{ $alert.Annotations.message }}{{ $alert.Annotations.description}}
故障时间: {{ ($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 }}
{{- end }}
6.3.6 prometheus-webhook-dingtalk设置systemd启动
vim /lib/systemd/system/prometheus-webhook-dingtalk.service
[Unit]
Descriptinotallow=prometheus-webhook-dingtalk
After=network-online.target
[Service]
Restart=on-failure
ExecStart=/usr/local/prometheus-webhook-dingtalk/prometheus-webhook-dingtalk --config.file=/usr/local/prometheus-webhook-dingtalk/config.yml
[Install]
WantedBy=multi-user.target
它默认使用8060端口
6.3.7 AlertManager配置钉钉告警渠道
alertmanager.yml相关配置如下:
route:
…
receiver: 'dingtalk'
…
receivers:
- name: 'dingtalk'
webhook_configs:
#这里的webhook1,根据我们在钉钉告警插件配置文件中targets中指定的值做修改
- url: http://192.168.131.12:8060/dingtalk/webhook1/send
send_resolved: true
#重新加载AlertManager配置
curl -XPOST http://192.168.131.12:9093/-/reload
还是使用之前的黑盒监控的告警规则做验证,此时在Prometheus界面能看到有新的告警生成,查看相关的钉钉群也能看到有新告警。
七、自定义告警模板
Prometheus 创建警报转发给 Alertmanager,Alertmanager会根据不同的 Label 向不同的 Receiver 发送警报通知,如Email、钉钉、企业微信等。所有 Receiver都使用相同的模板语法,然后通过模板格式化以后发送警报信息给 Receiver。
Alertmanager 自带的模板是基于 Go 语言的 template 模板,用户可以根据自己的需求去定义自己需要的模板,上面给出的模板已经足够大家的基础使用了。
下面介绍下通常自定义模板中会需要用到的一些参数说明。
名称 |
数据类型 |
描述 |
Receiver |
string |
接受警报通知的接收器名称 |
Status |
stri服务器托管网ng |
警报状态,例如:Firing或Resolved的通知 |
Alert |
Alert |
警报通知的真实内容,警报中的所有列表 |
GroupLables |
KV |
包含警报通知的组标签 |
CommandLabels |
KV |
所有警报的公共标签,包含GroupLabels的所有标签 |
CommandAnnotations |
KV |
注释,比如自定义的一些字符串 |
ExternalURL |
string |
警报信息中的Alertmanager地址 |
上面说的KV类型是一组使用不标示标签与注释的Key/Value字符串对,可以在Alertmanager中的默认模板中看到其定义。
默认模板地址:https://github.com/prometheus/alertmanager/blob/main/template/default.tmpl
其中邮件中所显示的 View In AlertManager ,Receiver 与 ExternalURL的定义其实就是模板中的 .ExternalURL 与 .Receiver。
{{ define "__alertmanager"}}AlertManager{{ end }}
{{ define"__alertmanagerURL" }}{{ .ExternalURL }}/#/alerts?receiver={{.Receiver | urlquery }}{{ end }}
...
对于Alert的类型,警报列表的字段还包含了如下参数与定义、描述。
名称 |
数据类型 |
描述 |
Status |
string |
定义警报状态是已经解决或处于触发状态 |
Label |
KV |
包含警报中的标签 |
Annotations |
KV |
警报的一组注释 |
StartsAt |
time.Time |
警报触发时间 |
EndsAt |
time.Time |
警报结束时间,只在警报结束的时间时设置 |
GeneratorURL |
string |
警报规则的连接URL,也就是Prometheus中的Rules查询地址
|
对于警报中的通知模板首先要熟悉go语言的template语法以及HTML简单的基础知识,然后把上面相关的元数据的一些信息了解清楚,就可以自己调整模板了。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
相关推荐: docker-compose 方式安装phpmyadmin
phpmyadmin是访问mysql数据库的可视化web服务,可以在网页上对数据表进行增删改查操作。 安装phpmyadmin 0. 准备 服务器需要安装docker环境和docker-compose环境。具体安装过程不是本文介绍的重点,docker和dock…