官方文档: Alertmanager 配置
Prometheus 中文文档: Alertmanager 配置
Alertmanager 配置概述
Alertmanager 主要负责对 Prometheus 产生的告警进行统一处理,因此在 Alertmanager 配置中一般会包含一下几个主要部分:
- 全局配置(global): 用于定义一些全局的公共参数,如全局的 SMTP 配置,Slack 配置等内容;
- 模板(templates): 用于定义告警通知时的模板,如 HTML 模板,邮件模板等;
- 告警路由(route): 根据标签匹配,确定当前告警应该如何处理;
- 接收人(receivers): 接收人是一个抽象的概念,他可以是一个邮箱也可以是微信,Slack 或者 Webhook 等,接收人一般配合告警路由使用;
- 抑制规则(inhibit_rules): 合理设置抑制规则可以减少垃圾告警的产生。
完整的配置格式如下:
1 | global: |
- resolve_timeout: 该参数定义了当 Alertmanager 持续多长时间未接收到告警后标记告警状态为resolved(已解决)。该参数的定义可能会影响到告警恢复通知的接收时间,读者可根据自己的实际场景进行定义,其默认值为5分钟。
告警路由(route)
在 Alertmanager 的配置中会定义一个基于标签匹配规则的告警路由树,以确定在接收到告警后 Alertmanager 需要如何对其进行处理:
1 | route: <route> |
其中 route 中则主要定义了告警的路由匹配规则,以及 Alertmanager 需要将匹配到的告警发送给哪一个 receiver,一个最简单的 route 定义如下所示:
1 | route: |
- 如上所示,在Alertmanager 配置文件中,我们只定义了一个路由,那就意味着所有由 Prometheus 产生的告警在发送到 Alertmanager 之后都会通过名为 web.hook 的receiver接收。
当然实际场景下,告警处理可不是这么简单的一件事情,对于不同级别的告警,我们可能会有完全不同的处理方式,因此在route中,我们还可以定义更多的子 Route,这些 Route 通过标签匹配告警的处理方式,route 的完整定义如下:
1 | [ receiver: <string> ] |
路由匹配
每一个告警都会从配置文件中顶级的 route 进入路由树,需要注意的是顶级的 route 必须匹配所有告警(即不能有任何的匹配设置,包括 match 和 match_re),每一个路由都可以定义自己的接收人以及匹配规则。
默认情况下,告警进入到顶级 route 后会遍历所有的子节点,直到找到最深的匹配 route,并将告警发送到该 route 定义的 receiver
中。但如果 route 中设置 continue
的值为 false,那么告警在匹配到第一个子节点之后就直接停止。如果 continue
为 true,报警则会继续进行后续子节点的匹配。如果当前告警匹配不到任何的子节点,那该告警将会基于当前路由节点的接收器配置方式进行处理。
其中告警的匹配有两种方式可以选择
- 一种方式基于字符串验证,通过设置
match
规则判断当前告警中是否存在标签 labelname 并且其值等于 labelvalue。 - 一种方式则基于正则表达式,通过设置
match_re
验证当前告警标签的值是否满足正则表达式的内容。
如果想设置发送告警通知之前要等待的时间,则可以通过 repeat_interval
参数进行设置。
告警分组
在之前的部分有讲过,Alertmanager 可以对告警通知进行分组,将多条告警合合并为一个通知。这里我们可以使用 group_by
来定义分组规则。基于告警中包含的标签,如果满足 group_by
中定义标签名称,那么这些告警将会合并为一个通知发送给接收器。
有的时候为了能够一次性收集和发送更多的相关信息时,可以通过 group_wait
参数设置等待时间,如果在等待时间内当前group接收到了新的告警,这些告警将会合并为一个通知向 receiver
发送。
而 group_interval
配置,则用于定义相同的 Group 之间发送告警通知的时间间隔。
例如,当使用 Prometheus 监控多个集群以及部署在集群中的应用和数据库服务,并且定义以下的告警处理路由规则来对集群中的异常进行通知。
1 | route: |
配置说明:
- 默认情况下所有的告警都会发送给集群管理员
default-receiver
,因此在 Alertmanager 的配置文件的根路由中,对告警信息按照集群以及告警的名称对告警进行分组。 - 如果告警是来源于数据库服务如 MySQL 或者 Cassandra ,此时则需要将告警发送给相应的数据库管理员(
database-pager
)。- 这里定义了一个单独子路由,如果告警中包含
service
标签,并且service
为 MySQL 或者 Cassandra, 则向database-pager
发送告警通知; - 由于这里没有定义
group_by
等属性,这些属性的配置信息将从上级路由继承,database-pager
将会接收到按cluster
和alertname
进行分组的告警通知。
- 这里定义了一个单独子路由,如果告警中包含
- 某些告警规则来源可能来源于开发团队的定义,这些告警中通过添加标签
team
来标示这些告警的创建者。- 在 Alertmanager 配置文件的告警路由下,定义单独子路由用于处理这一类的告警通知,如果匹配到告警中包含标签
team
,并且team
的值为frontend
,Alertmanager 将会按照标签product
和environment
对告警进行分组。此时如果应用出现异常,开发团队就能清楚的知道哪一个环境(environment)中的哪一个应用程序出现了问题,可以快速对应用进行问题定位。
- 在 Alertmanager 配置文件的告警路由下,定义单独子路由用于处理这一类的告警通知,如果匹配到告警中包含标签
告警接收器(receiver)
在 Alertmanager 中路由负责对告警信息进行分组匹配,并向告警接收器发送通知。告警接收器可以通过以下形式进行配置:
1 | receivers: |
每一个 receiver 具有一个全局唯一的名称,并且对应一个或者多个通知方式:
1 | name: <string> |
目前官方内置的第三方通知集成包括:邮件、 即时通讯软件(如Slack、Hipchat)、移动应用消息推送(如Pushover)和自动化运维工具(例如:Pagerduty、Opsgenie、Victorops)。Alertmanager的通知方式中还可以支持Webhook,通过这种方式开发者可以实现更多个性化的扩展支持。
SMTP 邮件告警
邮箱应该是目前企业最常用的告警通知方式,Alertmanager 内置了对 SMTP 协议的支持,因此对于企业用户而言,只需要一些基本的配置即可实现通过邮件的通知。在 Alertmanager 使用邮箱通知,用户只需要定义好 SMTP 相关的配置,并且在 receiver 中定义接收方的邮件地址即可。在 Alertmanager 中我们可以直接在配置文件的global
中定义全局的SMTP配置:
1 | global: |
完成全局 SMTP 配置之后,我们只需要为 receiver
配置 email_configs
用于定义一组接收告警的邮箱地址即可,如下所示:
1 | name: <string> |
每个 email_config
中定义相应的接收人邮箱地址,邮件通知模板等信息即可,当然如果当前接收人需要单独的 SMTP 配置,那直接在 email_config
中覆盖即可.
1 | [ send_resolved: <boolean> | default = false ] |
如果当前收件人需要接受告警恢复的通知的话,在 email_config
中定义 send_resolved
为 true
即可。
如果所有的邮件配置使用了相同的SMTP配置,则可以直接定义全局的SMTP配置。
这里,以 163 邮箱为例,定义一个全局的 SMTP 配置,并且通过 route 将所有告警信息发送到 default-receiver 中:
1 | global: |
企业微信告警
Alertmanager 已经内置了对企业微信的支持,我们可以通过企业微信来管理报警,更进一步可以通过企业微信和微信的互通来直接将告警消息转发到个人微信上。
Prometheus官网 中给出了企业微信的相关配置说明:
1 | # Whether or not to notify about resolved alerts. |
企业微信相关概念说明请参考企业微信API说明,可以在企业微信的后台中建立多个应用,每个应用对应不同的报警分组,由企业微信来做接收成员的划分。具体配置参考如下:
1 | global: |
配置模板示例如下:
微信告警模板 wechat.tmpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14{{ define "wechat.html" }}
{{ range $i, $alert := .Alerts }}
===alertmanager监控报警===
告警状态:{{ .Status }}
告警级别:{{ $alert.Labels.severity }}
告警类型:{{ $alert.Labels.alertname }}
告警应用:{{ $alert.Annotations.summary }}
故障主机: {{ $alert.Labels.instance }}
告警主题: {{ $alert.Annotations.summary }}
告警详情: {{ $alert.Annotations.description }}
触发时间: {{ $alert.StartsAt.Format "2006-01-02 15:04:05" }}
===========end============
{{ end }}
{{ end }}邮件告警模板
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34{{ define "email.html" }}
{{ range $i, $alert := .Alerts }}
<table border="1">
<tr>
<td>告警主题</td>
<td>{{ $alert.Annotations.summary }}</td>
</tr>
<tr>
<td>当前状态</td>
<td>{{ .Status }}</td>
</tr>
<tr>
<td>告警级别</td>
<td>{{ $alert.Labels.serverity }}</td>
</tr>
<tr>
<td>告警名称</td>
<td>{{ $alert.Labels.alertname }}</td>
</tr>
<tr>
<td>告警主机</td>
<td>{{ $alert.Labels.instance }}</td>
</tr>
<tr>
<td>详细信息</td>
<td>{{ $alert.Annotations.description }}</td>
</tr>
<tr>
<td>告警时间</td>
<td>{{ $alert.StartsAt.Local.Format "2006-01-02 15:04:05" }}</td>
</tr>
</table>
{{ end }}
{{ end }}