prometheus告警系统
一、基础理论
告警能力在Prometheus的架构中被划分成两个独立的部分。如下所示,通过在Prometheus中定义AlertRule(告警规则),Prometheus会周期性的对告警规则进行计算,如果满足告警触发条件就会向Alertmanager发送告警信息。
在Prometheus中一条告警规则主要由以下几部分组成:
- 告警名称:用户需要为告警规则命名,当然对于命名而言,需要能够直接表达出该告警的主要内容
- 告警规则:告警规则实际上主要由PromQL进行定义,其实际意义是当表达式(PromQL)查询结果持续多长时间(During)后出发告警
在Prometheus中,还可以通过Group(告警组)对一组相关的告警进行统一定义。当然这些定义都是通过YAML文件来统一管理的。
Alertmanager作为一个独立的组件,负责接收并处理来自Prometheus Server(也可以是其它的客户端程序)的告警信息。Alertmanager可以对这些告警信息进行进一步的处理,比如当接收到大量重复告警时能够消除重复的告警信息,同时对告警信息进行分组并且路由到正确的通知方,Prometheus内置了对邮件,Slack等多种通知方式的支持,同时还支持与Webhook的集成,以支持更多定制化的场景。例如,目前Alertmanager还不支持钉钉,那用户完全可以通过Webhook与钉钉机器人进行集成,从而通过钉钉接收告警信息。同时AlertManager还提供了静默和告警抑制机制来对告警通知行为进行优化。
1.1、警报说明
- 警报方法中最常见的反模式是发送过多的警报,通常发送过多警报的原因可能包括:
- 警报缺少可操作性,它只是提供信息。你应关闭所有这些警报,或将其转换为计算速率的计数
器,而不是发出警报。 - ·故障的主机或服务上游会触发其下游的所有内容的警报。你应确保警报系统识别并抑制这些重复
的相邻警报。 - 对原因而不是症状(symptom)进行警报。
- 症状是应用程序停止工作的迹象,它们可能是由许多原因导致的各种问题的表现。API或网站的高延迟是一种症状,这种症状可能由许多问题导致:高数据库使用率、内存问题、磁盘性能等。对症状发送警报可以识别真正的问题。
- 仅对原因(例如高数据库使用率)发出警报也可能识别出问题(但通常很可能不会)。
- 对于这个应用程序,高数据库使用率可能是完全正常的,并且可能不会对最终用户或应用程序造成性能问题。作为一个内部状态,发送警报是没有意义的。
- 这种警报可能会导致工程师错过更重要的问题,因为他们已经对大量不可操作且基于原因的警报变得麻木。你应该关注基于症状的警报,并依赖你的指标或其他诊断数据来确定原因
- 警报缺少可操作性,它只是提供信息。你应关闭所有这些警报,或将其转换为计算速率的计数
- 第二种最常见的反模式是警报的错误分类。
- 第三种反模式是发送无用的警报
1.2、预警流程
因此,正常情况下,我们要想使用报警功能,我们就需要将Prometheus配置成为AlterManager的告警客户端,返回来,AlterManager作为一个应用程序,也应该纳入到监控系统中来,而在配置逻辑上,我们需要在AlterManager上定义出合理的receiver而后,再去根据对应的告警机制通过路由规则将合理的信息路由给对应的receiver;
如下流程图,首先在Prometheus上定义Alter rule,即触发规则,同时Prometheus也定义了谁是AlterManager,因此Alter rule触发的告警通知会达到AlterManager的route路由表的根路由,然后在每一个子路由上通过match来匹配这个通知信息的某一部分,或者某些特征,即标签,一旦匹配到了就交给匹配到receiver进行报警触发;
因此每一个receiver应该有具体的定义,比如定义receiver的媒介是什么,邮件、叮叮还是微信,如果对应的告警信息已经匹配到了第一个receiver,至于要不要继续匹配第二个、第三个实现告警升级等高级功能,这完全是可以通过配置逻辑来实现的,比如刚开始触发时为waring,一段时间没解决就升级;
有时候偶尔的一次状态转换不见得真正发生了严重事件,所以Alter rule在评估某一个异常发生的时候不应该第一时间就进行报警,因而,我们通常会给定一个持续的时间窗口,比如这个对应的告警规则表达式,采样的结果为True,这个True持续了2分钟还没有解决,那么就可以认为它可能真的出现问题了,所以要稍微等待一段时间,这是Prometheus上定义的,一旦第一次触发时,这个告警通知就会产生,但是这个告警通知不会立即交给AlterManager去发送,而是先在Prometheus上暂存一会儿,这个暂存的状态就上Pending,一旦超出了Pending的最长时长,这个告警就会交给AlterManager;
- **分组:**我们也可以通过Group功能,将告警规则进行统一定义,将多个规则定义在一个组当中,以实现分组的功能,分组可以将多个告警信息合并成一个,在某些情况下,比如系统宕机导致大量的告警触发时,这个时候做分组就可以只触发一次告警即可;
- **抑制:**抑制是指当某一告警发出后,可以停止重复发送由此告警引发的其它告警的机制。
- 例如,当集群不可访问时触发了一次告警,通过配置Alertmanager可以忽略与该集群有关的其它所有告警。这样可以避免接收到大量与实际问题无关的告警通知。
- 抑制机制同样通过Alertmanager的配置文件进行设置。
- 静默: 静默提供了一个简单的机制可以快速根据标签对告警进行静默处理。如果接收到的告警符合静默的配置,Alertmanager则不会发送告警通知。
- 例如,每一周周三晚上凌晨1:00例行维护,为例避免例行维护期间会触发告警,我们可以定制静默期间触发的任何异常状态都不进行告警;
- 静默设置需要在Alertmanager的Werb页面上进行设置。
二、自定义告警规则
Prometheus中的告警规则允许你基于PromQL表达式定义告警触发条件,Prometheus后端对这些触发规则进行周期性计算,当满足触发条件后则会触发告警通知。默认情况下,用户可以通过Prometheus的Web界面查看这些告警规则以及告警的触发状态。当Promthues与Alertmanager关联之后,可以将告警发送到外部服务如Alertmanager中并通过Alertmanager可以对这些告警进行进一步的处理。
2.1、自定义告警规则
groups:
- name: 节点预警
rules:
- alert: 节点下线通知
expr: up == 0
for: 60m # 需要在触发警报之前的60分钟内大于80%
labels:
severity: critical
annotations:
title: '节点下线'
description: '节点已下线1分钟'
指定了一个组名节点预警,该组中的规则包含在rules块中。每个规则都有一个名称,在alert子句中指定,这里是 up == 0 。在每个警报组中,警报名称都必须是唯一的
在告警规则文件中,我们可以将一组相关的规则设置定义在一个group下。在每一个group中我们可以定义多个告警规则(rule)。一条告警规则主要由以下几部分组成:
- alert:告警规则名称
- expr: 要监控的指标 instance:node_cpu:avg_rate5m,用于计算是否有时间序列可以满足该条件,也可以使用由Recording rule定义的指标
- for:控制在触发警报之前测试表达式必须为true的时间长度。但其持续时间未能满足for定义时长时,相关告警状态为pending,满足时长之后,相关告警将被触发,并转为firing状态,在示例中,指标instance:node_cpu:avg_rate5m需要在触发警报之前的60分钟内大于80%
- 标签(label)和注解(annotation): 装饰警报。警报规则中时间序列上的所有标签都会转移到警报。labels子句允许我们指定要附加到警报的其他标签,这里我们添加了一个值为warning的severity标签
- annotations子句允许我们指定展示更多信息的标签,如描述、运行手册的链接或处理警报的说
明,但不能被用于标示告警实例,经常用于存储告警摘要,且其值支持模版化 - console:注解,它指向了展示节点指标的Grafana仪表板
为了能够让Prometheus能够启用定义的告警规则,我们需要在Prometheus全局配置文件中通过rule_files指定一组告警规则文件的访问路径,Prometheus启动后会自动扫描这些路径下规则文件中定义的内容,并且根据这些规则计算是否向外部发送通知:
rule_files:
- "rules/node_rules.yml"
- "rules/node_alerts.yml"
# 规则:https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/
默认情况下Prometheus会每分钟对这些告警规则进行计算,如果用户想定义自己的告警计算周期,则可以通过evaluation_interval
来覆盖默认的计算周期:
global: [ evaluation_interval: <duration> | default = 1m ]
2.2、警报触发
那么警报是如何发出的呢?Prometheus以一个固定时间间隔来评估所有规则,这个时间由evaluate_interval定义,我们将其设置为15秒。在每个评估周期,Prometheus运行每个警报规则中定义的表达式并更新警报状态
警报可能有以下三种状态:
-
Inactive:警报未激活。
-
Pending:警报已满足测试表达式条件,但仍在等待for子句中指定的持续时间。
-
Firing:警报已满足测试表达式条件,并且Pending的时间已超过for子句的持续时间。
总结: Pending到Firing的转换可以确保警报更有效,且不会来回浮动。没有for子句的警报会自动从Inactive转换为Firing,只需要一个评估周期即可触发。带有for子句的警报将首先转换为Pending,然后转换为Firing,因此至少需要两个评估周期才能触发。
警报的生命周期如下:
- 节点的CPU不断变化,每隔一段由scrape_interval定义的时间被Prometheus抓取一次,默认15秒。
- 根据每个evaluation_interval的指标来评估警报规则,对我们来说还是15秒。
- 当警报表达式为true时(对于我们来说是CPU超过80%),会创建一个警报并转换到Pending状
态,执行for子句。 - 在下一个评估周期中,如果警报测试表达式仍然为true,则检查for的持续时间。如果超过了持续
时间,则警报将转换为Firing,生成通知并将其推送到Alertmanager。 - 如果警报测试表达式不再为true,则Prometheus会将警报规则的状态从Pending更改为Inactive。
AlterManager是一个独立的go二进制程序,需要独立部署维护,部署方式和Prometheus一样,官方提供的都是单一的二进制程序,也提供了配置文件,我们可以在配置文件里面定义好路由、分组、抑制、静默及媒介等信息,实现触发告警;
2.3、告警模板jinja2
-
labels、value
模版标签语法:{{ $labels.<label_name> }} 指标样本值引用:{{ $value }} # 模板的annotations中定义 title: 'instance {{ $labels.instance }} down' description: 'instance {{ $labels.instance }} of {{ $labels.job }} has been down for more than 1 minute.' # 邮件中显示 title: 'instance 192.168.0.237:9000 down'
-
humanize函数
annotations: summary: Node CPU of {{ humanize $value }}% for 1 # 使用这个函数,值会保留两位 如99.10%
三、部署Alertmanager
3.1、安装及使用
- 安装
]# tar xf alertmanager-0.22.1.linux-amd64.tar.gz -C /usr/local/
]# cd /usr/local/
]# ln -sv alertmanager-0.22.1.linux-amd64/ alertmanager
-
基础默认配置文件
[root@node1 alertmanager]# cat alertmanager.yml global: resolve_timeout: 5m route: group_by: ['alertname'] group_wait: 10s group_interval: 10s repeat_interval: 1h receiver: 'web.hook' # 发送告警的receiver 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']
-
实例
# 我们给它改成这个 配置清单 ]# cat /etc/alertmanager/alertmanager.yml global: smtp_smarthost: 'smtp.qiye.aliyun.com:25' smtp_hello: 'company.com' smtp_from: 'username@company.com' smtp_auth_username: 'username@company.com' smtp_auth_password: password smtp_require_tls: false templates: - "/etc/alertmanager/template/*.temp" route: group_by: ["instance"] group_wait: 30s group_interval: 5m repeat_interval: 3h receiver: test routes: - match: severity: critical receiver: test receivers: - name: "test" email_configs: - to: "alerts@example.com" - 对于电子邮件警报,我们使用email_configs块来指定电子邮件选项,例如接收警报的地址。我 们还可以指定SMTP设置(这将覆盖全局设置),并添加其他条目(例如邮件标头)。
-
自启脚本
]# cat >> /usr/lib/systemd/system/alertmanager.service << EOF [Unit] Description=alertmanager Documentation=https://prometheus.io/ After=network.target #StartLimitIntervalSec=0 [Service] Type=simple ExecStart=/usr/local/alertmanager/alertmanager --config.file=/usr/local/alertmanager/alertmanager.yml --storage.path="/usr/local/alertmanager/data/" Restart=always RestartSec=1 # Restart=on-failure [Install] WantedBy=multi-user.target EOF
--config.file
用于指定alertmanager配置文件路径--storage.path
用于指定数据存储路径
3.2、配置文件说明
- 全局配置(global):用于定义一些全局的公共参数,如全局的SMTP配置,Slack配置等内容;
- 模板(templates):用于定义告警通知时的模板,如HTML模板,邮件模板等;
- 告警路由(route):根据标签匹配,确定当前告警应该如何处理;
- 接收人(receivers):接收人是一个抽象的概念,它可以是一个邮箱也可以是微信,Slack或者Webhook等,接收人一般配合告警路由使用;
- 抑制规则(inhibit_rules):合理设置抑制规则可以减少垃圾告警的产生
3.2.1、route
- **route:**配置路由树;
- receiver: 从接受组(与route同级别)中选择接受;
- **group_by:**分组时使用的标签,默认情况下,所有告警都组织在一起,而一旦指定分组标签,则AlterManager将按这些标签进行分组;
- **continue:**告警是否去继续路由子节点;
- **match:**通过标签去匹配这次告警是否符合这个路由节点,必须全部匹配才可以告警,已弃用;
- **match_re:**通过正则表达是匹配标签,意义同上,已弃用;
- **matchers:**警报必须满足匹配节点的匹配器列表;
- **group_wait:**组内等待时间,同一分组内收到第一个告警等待多久开始发送,目标是为了同组消息同时发送,不占用告警信息,默认30s
- **group_interval:**当组内已经发送过一个告警,组内若有新增告警需要等待的时间,默认为5m,这条要确定组内信息是影响同一业务才能设置,若分组不合理,可能导致告警延迟,造成影响
- **repeat_interval:**告警已经发送,且无新增告警,若重复告警需要间隔多久 默认4h 属于重复告警,时间间隔应根据告警的严重程度来设置
- routes:
- **route:**路由子节点 配置信息跟主节点的路由信息一致;
- **route:**路由子节点 配置信息跟主节点的路由信息一致;
3.2.2、receiver
- 在当前的配置中,我们只定义了基本路由,即树的根节点
- receiver: 这是我们警报的默认目的地,在示例中是email电子邮件
- receivers: 指定警报目的地。可以通过电子邮件发送警报,或者发送到PagerDuty和VictorOps等服务,以及Slack和HipChat等聊天工具。这里我们只定义了一个目的地:一个电子邮件地址。
- 每个接收器都有一个名称和相关配置。这里我们已经命名了接收器email
- 对于电子邮件警报,我们使用email_configs块来指定电子邮件选项,例如接收警报的地址。我
们还可以指定SMTP设置(这将覆盖全局设置),并添加其他条目(例如邮件标头)。
3.2.3、完整配置示例
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分钟
3.3、AM加入Prometheus
利用AlterManager报警,首先需要将AlterManager,加入到Prometheus监控体系当中,作为整个监控体系的一部分,加入的方式有两种,一种是直接静态配置,另一种则是和Target一样,使用文件服务发现的方式动态添加,AlterManager到我们的Prometheus中;
此外,AlterManager自己也提供了/metrcis接口,来暴露自己的状态指标,我们也可以将AlterManager加入到Prometheus监控体系当中,作为一个Target给它监控起来;
-
为prometheus配置 Alertmanagers
# 也可以在 地址:9090/status中查看 Alertmanagers的endpoints alerting: alertmanagers: - static_configs: - targets: - 192.168.0.231:9093
-
监控Alertmanagers 静态配置
# 在prometheuse服务器中配置 prometheus.yml - job_name: "alertmanagers" static_configs: - targets: ["192.168.0.231:9093"]
-
监控Alertmanagers 基于文件的服务发现
prometheus]# vim prometheus.yml - job_name: 'alertmanager' file_sd_configs: - files: - targets/alert*.yaml targets]# cat alertmanager.yaml - targets: - 192.168.0.236:9090 labels: app: alertmanager
3.4、完整示例
-
prometheus配置
prometheus]# cat targets/first_rules.yml groups: - name: Allinstance rules: - alert: InstanceDown expr: up == 0 for: 10s annotations: title: 'instance down' description: 'instance has been down for more than 1 minute.' labels: severity: 'critcal' # 级别 - name: disk_alerts rules: - alert: DiskFull expr: 100*((node_filesystem_size_bytes{mountpoint="/"}-node_filesystem_avail_bytes{mountpoint="/"})/node_filesystem_size_bytes{mountpoint="/"}) > 80 for: 5s annotations: description: '节点{{ $labels.instance }}磁盘空间已经不足80%,请及时处理!!!' labels: severity: 'warning' # 级别
-
alertmanager
alertmanager]# cat alertmanager.yml global: resolve_timeout: 5m smtp_smarthost: 'mail.example.com:25' smtp_from: 'test@example.com' smtp_auth_username: 'test@example.com' smtp_auth_password: '密码或授权码' smtp_require_tls: false templates: - "/usr/local/alertmanager/temp/*.temp" route: group_by: ["instance"] group_wait: 30s group_interval: 5m repeat_interval: 3h receiver: test # 默认的receiver,标示没有匹配到的就发送给默认的receiver routes: - receiver: test match: severity: critical # prometheus预警中定义的值 - match: severity: warning receiver: disk # - match_re: # 或者匹配多个 # severity: ^(warning|critical)$ # receiver: support_team receivers: - name: "test" email_configs: - to: "test@qq.com" send_resolved: true #接受告警恢复的通知 - name: "disk" email_configs: - to: "disk@qq.com"
-
group_by: 控制的是Alertmanager分组警报的方式,默认情况下,所有警报都组合在一起,但如果我们指定了group_by和任何标签,则Alertmanager将按这些标签对警报进行分组, 如果是多组则可以
route: group_by: ["instance","alertname"]
-
group_wait: 触发警报之前查看是否收到该组中的其他警报。你可以将其视为警报缓冲。在例子中,这个等待时间是30秒
-
group_interval: 在发出警报后,如果收到来自该分组的下一次评估的新警报,等待设定的值(5分钟),然后再发送新警报。这可以防止警报分组的警报泛滥
-
**repeat_interval:**这个暂停并不适用于我们的警报组,而是适用于单个警报,并且是等待重新发送相同警报的时间段,我们指定为3个小时
-
-
temp模板
[root@node1 ~]# cat /usr/local/alertmanager/templates/email.html {{ define "email.to.html" }} {{ range .Alerts }} <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> </haed> <body style="margin: 0; padding: 0;"> <div align="center"> <table border="1" style="border:5px solid #F2F2F2;" cellspacing="4" cellpadding="3" width="650" style="table-layout:fixed"> <tr> <th align="center"><b>告警项</b></marquee></th> <th align="center"><b>内容信息</b></marquee></th> </tr> <tr> <td align="center" style="font-family:微软雅黑; width: 15%;WORD-WRAP:break-word">告警标题</td> <td align="center" style="font-family:微软雅黑; width: 60%;WORD-WRAP:break-word">{{ .Labels.alertname }}</td> </tr> <tr> <td align="center" style="font-family:微软雅黑; size=5;width: 20%;WORD-WRAP:break-word">告警描述</td> <td align="center" style="font-family:微软雅黑;width: 80%;color: red;WORD-WRAP:break-word">{{ .Annotations.description }} </td> </tr> <tr> <td align="center" style="font-family:微软雅黑;width: 20%;WORD-WRAP:break-word">告警等级</td> <td align="center" style="font-family:微软雅黑;width: 80%;padding-center: 15px;font-weight: bold;">{{ .Labels.severity }} </td> </tr> <tr> <td align="center" style="font-family:微软雅黑;width: 20%;WORD-WRAP:break-word">告警时间</td> <td align="center" style="font-family:微软雅黑;width: 80%;WORD-WRAP:break-word">{{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }} </td> </tr> <tr> <td align="center" style="font-family:微软雅黑;width: 20%;WORD-WRAP:break-word">告警主机</td> <td align="center" style="font-family:微软雅黑;width: 80%;WORD-WRAP:break-word">{{ .Labels.instance }}</td> </tr> </table> </body> </html> {{ end }} {{ end }}
四、告警路由
4.1、路由表
上面介绍过AlterManager是支持树状路由表的,示例只使用了一个根路由,只指定了一个route和一个receiver就完了,没有做任何区分,但事实上我们是完全可以使用match去区分对应的Alter的一些属性信息,如果能匹配到,可以根据匹配规则发给不同的receiver,以实现高级高级特性;
每一个告警都会从配置文件中顶级的route进入路由树,需要注意的是顶级的route必须匹配所有告警(即不能有任何的匹配设置match和match_re),每一个路由都可以定义自己的接受人以及匹配规则。默认情况下,告警进入到顶级route后会遍历所有的子节点,直到找到最深的匹配route,并将告警发送到该route定义的receiver中。但如果route中设置continue的值为false,那么告警在匹配到第一个子节点之后就直接停止。如果continue为true,报警则会继续进行后续子节点的匹配。如果当前告警匹配不到任何的子节点,那该告警将会基于当前路由节点的接收器配置方式进行处理。
其中告警的匹配有两种方式可以选择,一种方式基于字符串验证,通过设置match规则判断当前告警中是否存在标签labelname并且其值等于labelvalue。第二种方式则基于正则表达式,通过设置match_re验证当前告警标签的值是否满足正则表达式的内容。
如果警报已经成功发送通知, 如果想设置发送告警通知之前要等待时间,则可以通过repeat_interval参数进行设置
-
直接发送
routes: - match: severity: critical receiver: pager # 将匹配severity标签与critical值,并将它们发送到pager接收器
-
分支路由
routes: - match: severity: critical receiver: pager routes: - match: severity: application1 receiver: support_team # 两个kv都需要被匹配才能发送到最终的接收者
-
continue
routes: - match: severity: critical receiver: pager continue: true # continue选项默认为false,但如果设置为true,则警报将在此路由中触发(如果匹配),并继续执行下一个相邻路由。有时这对于向两个地方发送警报很有用,但更好的解决方法是在接收器中指定多个端点
4.2、告警分组
Alertmanager可以对告警通知进行分组,将多条告警合合并为一个通知。
- group_by来定义分组规则。基于告警中包含的标签,如果满足group_by中定义标签名称,那么这些告警将会合并为一个通知发送给接收器。
- group_wait参数设置等待时间,如果在等待时间内当前group接收到了新的告警,这些告警将会合并为一个通知向receiver发送。
- 而group_interval配置,则用于定义相同的Group之间发送告警通知的时间间隔。
示例
# 例如,当使用Prometheus监控多个集群以及部署在集群中的应用和数据库服务,并且定义以下的告警处理路由规则来对集群中的异常进行通知。
route:
receiver: 'default-receiver'
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
group_by: [cluster, alertname]
routes:
- receiver: 'database-pager'
group_wait: 10s
match_re:
service: mysql|cassandra
- receiver: 'frontend-pager'
group_by: [product, environment]
match:
team: frontend
如果告警时来源于数据库服务如MySQL或者Cassandra,此时则需要将告警发送给相应的数据库管理员(database-pager)。这里定义了一个单独子路由,如果告警中包含service标签,并且service为MySQL或者Cassandra,则向database-pager发送告警通知,由于这里没有定义group_by等属性,这些属性的配置信息将从上级路由继承,database-pager将会接收到按cluster和alertname进行分组的告警通知。
4.3、Receiver
内置告警接收器,Alertmanager中路由负责对告警信息进行分组匹配,并将像告警接收器发送通知
# 每一个receiver具有一个全局唯一的名称,并且对应一个或者多个通知方式:
name: <string>
email_configs:
[ - <email_config>, ... ]
hipchat_configs:
[ - <hipchat_config>, ... ]
pagerduty_configs:
[ - <pagerduty_config>, ... ]
pushover_configs:
[ - <pushover_config>, ... ]
slack_configs:
[ - <slack_config>, ... ]
opsgenie_configs:
[ - <opsgenie_config>, ... ]
webhook_configs:
[ - <webhook_config>, ... ]
victorops_configs:
[ - <victorops_config>, ... ]
目前官方内置的第三方通知集成包括:邮件、 即时通讯软件(如Slack、Hipchat)、移动应用消息推送(如Pushover)和自动化运维工具(例如:Pagerduty、Opsgenie、Victorops)。Alertmanager的通知方式中还可以支持Webhook,通过这种方式开发者可以实现更多个性化的扩展支持
-
SMTP为例
global: smtp_smarthost: smtp.gmail.com:587 smtp_from: <smtp mail from> smtp_auth_username: <usernae> smtp_auth_identity: <username> smtp_auth_password: <password> route: group_by: ['alertname'] receiver: 'default-receiver' receivers: - name: default-receiver email_configs: - to: <mail to address> send_resolved: true # 通过 route 将告警信息发送给告警器 default-receiver, 最终发送给 to:xx@email.com
4.4、抑制inhibit_rules
抑制主要是指当监控项存在依赖关系的时候,只对被依赖的故障报警了,依赖项就不需要报警了,比如一个节点运行了一个DB一个MQ,很显然,节点自己应该有一个node_exporter监控着节点的运行状况,假设,发现这个节点的node_exporter连不上了,那么这个时候Prometheus就会发出一条节点故障的告警信息;
但是节点故障了,DB和MQ也会故障,所以在正常情况下,报警要报三个,分别是节点故障、DB故障和MQ故障,那么这个时候,为了避免连续报警,我们可以使用抑制的规则进行监控项的依赖,当被依赖项报警,依赖项就不会再报警了,像这种就叫做抑制机制;
# 语法
source_match:
[ <labelname>: <labelvalue>,... ]
source_match_re:
[ <labelname>: <regex>,... ]
target_match:
[ <labelname>: <labelvalue>,... ]
target_match_re:
[ <labelname>: <regex>,... ]
如果之前已经发送过类似的告警通知,能匹配到target_match或者target_match_re所定义的匹配条件,那么产生新的告警时,如果可以满足source_match或者source_match_re时,那么这个告警信息就认为它与我们的目标标签完全相同,就启动抑制机制,新的告警就不会被发送了;
# 示例
source_match:
alertname: NodeDown
severity: critical
target_match:
severity: critical
equal:
- node
# 如果之前发生过NodeDown并且这个报警级别是critical,那么新产生的报警如果它的报警级别也是critical,并且之前的NodeDown报警时间序列的node标签和新产生的报警时间序列的node标签值一致,那么就开启抑制机制,新产生的报警将不会发送告警信息;
4.4.1、抑制示例
可参考: Alertmanager告警抑制与静默, 抑制规则的使用
Alertmanager的抑制机制可以避免当某种问题告警产生之后用户接收到大量由此问题导致的一系列的其它告警通知。例如当集群不可用时,用户可能只希望接收到一条告警,告诉他这时候集群出现了问题,而不是大量的如集群中的应用异常、中间件服务异常的告警通知。
# 语法
target_match:
[ <labelname>: <labelvalue>, ... ]
target_match_re:
[ <labelname>: <regex>, ... ]
source_match:
[ <labelname>: <labelvalue>, ... ]
source_match_re:
[ <labelname>: <regex>, ... ]
[ equal: '[' <labelname>, ... ']' ]
当已经发送的告警通知匹配到target_match和target_match_re规则,当有新的告警规则如果满足source_match或者定义的匹配规则,并且已发送的告警与新产生的告警中equal定义的标签完全相同,则启动抑制机制,新的告警不会发送
inhibit_rules:
- source_match:
alertname: 'InstanceDown'
severity: 'critical'
target_match:
severity: 'critical'
equal:
- instance
例如当集群中的某一个主机节点异常宕机导致告警NodeDown被触发,同时在告警规则中定义了告警级别severity=critical。由于主机异常宕机,该主机上部署的所有服务,中间件会不可用并触发报警。根据抑制规则的定义,如果有新的告警级别为severity=critical,并且告警中标签node的值与NodeDown告警的相同,则说明新的告警是由NodeDown导致的,则启动抑制机制停止向接收器发送通知。
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']
# 在alertname、dev、instance 都相等的情况下critaical的报警会抑制warning级别的报警信息