告警简介#
告警能力在 Prometheus 的架构中被划分为两个部分:
在 Prometheus Server 中定义告警规则以及产生告警
Alertmanager 组件用于处理由 Prometheus 产生的告警
Alertmanager 是 Prometheus 体系中告警的统一处理中心。Alertmanager 提供了多种内置第三方告警通知方式,同时还提供对 Webhook 通知的支持,通过 Webhook 可以完成对告警更多个性化的扩展。
Prometheus会周期性的对告警规则进行计算,如果满足告警触发条件就会向 Alertmanager 发送告警信息

告警规则主要由以下几部分组成:
- 告警名称:需要为告警规则命名,对于命名而言,需要能够直接表达出该告警的主要内容
- 告警规则:告警规则主要由
PromQL进行定义,其实际意义是当表达式(PromQL)查询结果持续多长时间(During)后触发告警
在 Prometheus 中,还可以通过Group(告警组)对一组相关的告警进行统一定义。这些定义通过 YAML 文件统一管理。
Alertmanager 作为一个独立的组件,负责接收并处理来自 Prometheus Server (也可以是其它的客户端程序)的告警信息。Alertmanager 可以对这些告警信息进行进一步的处理,比如当接收到大量重复告警时能够消除重复的告警信息,同时对告警信息进行分组并且路由到正确的通知方,Prometheus 内置了对邮件,Slack 等多种通知方式的支持,同时还支持与 Webhook 的集成,以支持更多定制化的场景。
例如,目前 Alertmanager 还不支持钉钉,可以通过 Webhook 与钉钉机器人进行集成,从而通过钉钉接收告警信息。同时 AlertManager 还提供了静默和告警抑制机制来对告警通知行为进行优化。
Alertmanager 特性#
Alertmanager 除了提供基本的告警通知能力以外,还主要提供了如:分组、抑制以及静默等告警特性:

分组#
分组机制可以将详细的告警信息合并成一个通知。在某些情况下,比如由于系统宕机导致大量的告警被同时触发,在这种情况下分组机制可以将这些被触发的告警合并为一个告警通知,避免一次性接受大量的告警通知,而无法对问题进行快速定位。
例如,当集群中有数百个正在运行的服务实例,并且为每一个实例设置了告警规则。假如此时发生了网络故障,可能导致大量的服务实例无法连接到数据库,结果就会有数百个告警被发送到 Alertmanager。
而作为用户,可能只希望能够在一个通知中就能查看哪些服务实例收到影响。这时可以按照服务所在集群或者告警名称对告警进行分组,而将这些告警内聚在一起成为一个通知。
告警分组,告警时间,以及告警的接受方式可以通过 Alertmanager 的配置文件进行配置。
抑制#
抑制是指当某一告警发出后,可以停止重复发送由此告警引发的其它告警的机制。
例如,当集群不可访问时触发了一次告警,通过配置 Alertmanager 可以忽略与该集群有关的其它所有告警。这样可以避免接收到大量与实际问题无关的告警通知。
抑制机制同样通过 Alertmanager 的配置文件进行设置。
静默#
静默提供了一个简单的机制可以快速根据标签对告警进行静默处理。如果接收到的告警符合静默的配置,Alertmanager 则不会发送告警通知。
静默设置需要在 Alertmanager 的 Werb 页面上进行设置。
自定义告警规则#
告警规则允许基于 PromQL 表达式定义告警触发条件,Prometheus 后端对这些触发规则进行周期性计算,当满足触发条件后则会触发告警通知。默认情况下可以通过 Prometheus 的 Web 界面查看这些告警规则以及告警的触发状态。当 Promthues 与 Alertmanager 关联之后,可以将告警发送到外部服务如 Alertmanager 中并通过 Alertmanager 可以对这些告警进行进一步的处理。
定义告警规则#
一条典型的告警规则如下所示:
groups:
- name: example
rules:
- alert: HighErrorRate
expr: job:request_latency_seconds:mean5m{job="myjob"} > 0.5
for: 10m
labels:
severity: page
annotations:
summary: High request latency
description: description info在告警规则文件中,可以将一组相关的规则设置定义在一个 group下。在每一个 group 中可以定义多个告警规则(rule)。一条告警规则主要由以下几部分组成:
alert:告警规则的名称expr:基于 PromQL 表达式告警触发条件,用于计算是否有时间序列满足该条件for:评估等待时间,可选参数。用于表示只有当触发条件持续一段时间后才发送告警。在等待期间新产生告警的状态为pendinglabels:自定义标签,允许用户指定要附加到告警上的一组附加标签annotations:用于指定一组附加信息,比如用于描述告警详细信息的文字等,annotations 的内容在告警产生时会一同作为参数发送到 Alertmanager
为了能够让 Prometheus 启用定义的告警规则,需要在 Prometheus 全局配置文件中通过 rule_files 指定一组告警规则文件的访问路径,Prometheus 启动后会自动扫描这些路径下规则文件中定义的内容,并且根据这些规则计算是否向外部发送通知。
rule_files:
[ - <filepath_glob> ... ]
# 示例
rule_files:
- "/etc/prometheus/rules.yml"默认情况下 Prometheus 会每分钟对这些告警规则进行计算,如果想定义自己的告警计算周期,可以通过evaluation_interval 来覆盖默认的计算周期:
global:
[ evaluation_interval: <duration> | default = 1m ]模板化#
一般来说,在告警规则文件的 annotations 中使用 summary 描述告警的概要信息,description 用于描述告警的详细信息。同时 Alertmanager 的UI也会根据这两个标签值显示告警信息。为了让告警信息具有更好的可读性,Prometheus 支持模板化 label 和 annotations 的中标签的值。
通过 $labels.<labelname> 变量可以访问当前告警实例中指定标签的值。$value 则可以获取当前 PromQL 表达式计算的样本值。
# To insert a firing element's label values:
{{ $labels.<labelname> }}
# To insert the numeric expression value of the firing element:
{{ $value }}例如,可以通过模板化优化 summary 以及 description 的内容的可读性:
groups:
- name: example
rules:
# Alert for any instance that is unreachable for >5 minutes.
- alert: InstanceDown
expr: up == 0
for: 5m
labels:
severity: page
annotations:
summary: "Instance {{ $labels.instance }} down"
description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."
# Alert for any instance that has a median request latency >1s.
- alert: APIHighRequestLatency
expr: api_http_request_latencies_second{quantile="0.5"} > 1
for: 10m
annotations:
summary: "High request latency on {{ $labels.instance }}"
description: "{{ $labels.instance }} has a median request latency above 1s (current value: {{ $value }}s)"实践#
在目录 /etc/prometheus/ 下创建 rules.yml 文件,内容如下:
groups:
- name: 主机监控
rules:
- alert: HostOutOfMemory
# 下面为了测试内存使用率高于1%告警
expr: node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100 < 99
for: 10s
labels:
severity: warning
annotations:
summary: Host out of memory (instance {{ $labels.instance }})
description: "Node memory is filling up (< 10% left)\n VALUE = {{ $value }}\n LABELS = {{ $labels }}"调整 prometheus.yml :
rule_files:
- "/etc/prometheus/rules.yml"重新启动 Prometheus 容器,将 rules.yml 也挂载到容器内:
docker run -d --name prometheus -p 9090:9090 -v /etc/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml -v /etc/prometheus/rules.yml:/etc/prometheus/rules.yml prom/prometheus查看告警状态#
如下所示,可以通过 Prometheus WEB界面中的 Alerts 菜单查看当前 Prometheus 下的所有告警规则,以及其当前所处的活动状态。

这里可以看到规则已经生效,同时对于已经 pending 或者 firing 的告警,Prometheus也会将它们存储到时间序列 ALERTS{} 中。
Alertmanager 部署#
上面看到配置的规则已经生效并且产生了告警,下面开始集成 Alertmanager 实现后续对告警信息的处理,Alertmanager 和 Prometheus Server 一样均采用 Golang 实现,并且没有第三方依赖。一般可以通过以下几种方式来部署 :
- 二进制包
- 容器部署
- 源码方式安装
二进制包部署#
Alertmanager 最新版本的下载地址可以从 Prometheus 官方网站 https://prometheus.io/download/ 获取
curl -LO https://github.com/prometheus/alertmanager/releases/download/v$VERSION/alertmanager-$VERSION.darwin-amd64.tar.gz
tar xvf alertmanager-$VERSION.darwin-amd64.tar.gzAlertmanager 解压后会包含一个默认的 alertmanager.yml 配置文件,内容如下所示:
global:
resolve_timeout: 5m
route:
group_by: ['alertname']
group_wait: 10s
group_interval: 10s
repeat_interval: 1h
receiver: 'web.hook'
receivers:
- name: 'web.hook'
webhook_configs:
- url: 'http://127.0.0.1:5001/'
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']容器部署#
在 etc 目录下新建 alertmanager 目录:
[root@wangpengliang100ecs ~]# cd /etc/
[root@wangpengliang100ecs etc]# mkdir alertmanager在 etc/alertmanager 目录下新建 alertmanager.yml:
global:
resolve_timeout: 5m
route:
group_by: ['alertname']
group_wait: 10s
group_interval: 10s
repeat_interval: 30h
receiver: 'web.hook'
receivers:
- name: 'web.hook'
webhook_configs:
- url: 'http://127.0.0.1:5001/'
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']启动 alertmanager 容器:
docker run -d --name alertmanager -p 9093:9093 -v /etc/alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml prom/alertmanager:v0.23.0访问 http://ipaddress:9093 在浏览器中查看:

Alert 菜单下可以查看 Alertmanager 接收到的告警内容。Silences 菜单下则可以通过UI创建静默规则,Status菜单可以看到当前系统的运行状态以及配置信息。
Alertmanager 集成#
Alertmanager 部署完成后,需要在 Prometheus 中设置 Alertmanager 相关的信息
调整 prometheus.yml :
alerting:
alertmanagers:
- static_configs:
- targets:
- 47.93.56.197:9093重新启动 prometheus:
[root@wangpengliang100ecs etc]# docker restart prometheus

集成163邮箱#
上面看到 Prometheus 的告警信息已经推送到了 Alertmanager,下面将告警信息发送到邮箱。这里使用163邮箱进行测试,需要在邮箱中开启 POP3/SMTP服务,具体方法自行百度。
调整 alertmanager.yml:
# 全局配置,包括报警解决后的超时时间、SMTP 相关配置、各种渠道通知的 API 地址等等。
global:
# 告警超时时间
resolve_timeout: 5m
# 发送者邮箱地址
smtp_from: '15101587969@163.com'
# 邮箱smtp服务器地址及端口
smtp_smarthost: 'smtp.163.com:465' # 因为阿里云默认封了25端口,所以选择465端口
# 发送者邮箱账号
smtp_auth_username: '15101587969@163.com'
# 发送者邮箱密码,这里填入邮箱开启SMTP中获取的授权码
smtp_auth_password: 'xxxxxx'
# 是否使用tls
smtp_require_tls: false
# 路由配置,设置报警的分发策略,它是一个树状结构,按照深度优先从左向右的顺序进行匹配。
route:
# 用于将传入警报分组在一起的标签。
# 基于告警中包含的标签,如果满足group_by中定义标签名称,那么这些告警将会合并为一个通知发送给接收器。
group_by: ['alertname']
# 发送通知的初始等待时间
group_wait: 30s
# 在发送有关新警报的通知之前需要等待多长时间
group_interval: 30s
# 如果已发送通知,则在再次发送通知之前要等待多长时间,通常约3小时或更长时间
repeat_interval: 30s
# 接受者名称
receiver: '163.email'
# 配置告警消息接受者信息,例如常用的 email、wechat、slack、webhook 等消息通知方式
receivers:
- name: '163.email'
email_configs:
# 配置接受邮箱地址
- to : '15101587969@163.com'重启 alertmanager 容器:
[root@wangpengliang100ecs etc]# docker restart alertmanager
配置邮件模板#
上面看到已经成功接收到了邮件,但是格式比较乱,可以使用邮件模板,Alertmanager 带有默认模板,可以自定义模板内容,Alertmanager 的通知模板基于 Go 模板系统,具体支持哪些变量请参照 官网说明。
在 etc/alertmanager 目录下新建 email.tmpl 文件:
{{ define "email.html" }}
{{ range .Alerts }}
告警程序: prometheus_alert <br>
告警类型: {{ .Labels.alertname }} <br>
故障主机: {{ .Labels.instance }} <br>
告警主题: {{ .Annotations.summary }} <br>
告警详情: {{ .Annotations.description }} <br>
{{ end }}
{{ end }}调整 alertmanager.yml 添加模板扫描,及邮件使用模板
templates:
- 'templates/*.tmpl
receivers:
- name: '163.email'
email_configs:
# 配置接受邮箱地址
- to : '15101587969@163.com'
html: '{{ template "email.html" . }}'
# 邮件主题信息
headers: {Subject: "[WARN] 报警邮件 {{ .CommonLabels.instance }} {{ .CommonAnnotations.summary }}"} 重启容器并映射邮件模板文件到容器内:
docker run -d --name alertmanager -p 9093:9093 -v /etc/alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml -v /etc/alertmanager/email.tmpl:/etc/alertmanager/templates/email.tmpl prom/alertmanager:v0.23.0查看邮件:

Alertmanager 配置#
在 Alertmanager 中通过路由(Route)来定义告警的处理方式。路由是一个基于标签匹配的树状匹配结构。根据接收到告警的标签匹配相应的处理方式。
Alertmanager 主要负责对 Prometheus 产生的告警进行统一处理,因此在 Alertmanager 配置中一般会包含以下几个主要部分:
- 全局配置(global):用于定义一些全局的公共参数,如全局的SMTP配置,Slack配置等内容;
- 模板(templates):用于定义告警通知时的模板,如HTML模板,邮件模板等;
- 告警路由(route):根据标签匹配,确定当前告警应该如何处理;
- 接收人(receivers):接收人是一个抽象的概念,它可以是一个邮箱也可以是微信,Slack或者Webhook等,接收人一般配合告警路由使用;
- 抑制规则(inhibit_rules):合理设置抑制规则可以减少垃圾告警的产生
完整配置格式如下:
global:
[ resolve_timeout: <duration> | default = 5m ]
[ smtp_from: <tmpl_string> ]
[ smtp_smarthost: <string> ]
[ smtp_hello: <string> | default = "localhost" ]
[ smtp_auth_username: <string> ]
[ smtp_auth_password: <secret> ]
[ smtp_auth_identity: <string> ]
[ smtp_auth_secret: <secret> ]
[ smtp_require_tls: <bool> | default = true ]
[ slack_api_url: <secret> ]
[ victorops_api_key: <secret> ]
[ victorops_api_url: <string> | default = "https://alert.victorops.com/integrations/generic/20131114/alert/" ]
[ pagerduty_url: <string> | default = "https://events.pagerduty.com/v2/enqueue" ]
[ opsgenie_api_key: <secret> ]
[ opsgenie_api_url: <string> | default = "https://api.opsgenie.com/" ]
[ hipchat_api_url: <string> | default = "https://api.hipchat.com/" ]
[ hipchat_auth_token: <secret> ]
[ wechat_api_url: <string> | default = "https://qyapi.weixin.qq.com/cgi-bin/" ]
[ wechat_api_secret: <secret> ]
[ wechat_api_corp_id: <string> ]
[ http_config: <http_config> ]
templates:
[ - <filepath> ... ]
route: <route>
receivers:
- <receiver> ...
inhibit_rules:
[ - <inhibit_rule> ... ]在全局配置中需要注意的是 resolve_timeout,该参数定义了当 Alertmanager 持续多长时间未接收到告警后标记告警状态为 resolved(已解决)。该参数的定义可能会影响到告警恢复通知的接收时间,可根据自己的实际场景进行定义,其默认值为5分钟。