一 告警功能概述
Prometheus对指标的收集、存储同告警能力分属于Prometheus Server和Alertmanager连个独立的组件,前者仅负责基于告警规则生成告警通知,具体的告警操作则由后者完成;
- Alertmanager负责处理由客户端发来的告警通知
- 客户端通常是Prometheus Server,但它也支持接收来自其它工具的告警;
- Alertmanager对告警通知进行分组、去重后,根据路由由规则将其路由到不同的receiver,如Email、短信或PagerDuty等;
二 Prometheus告警逻辑
- 首先要配置Prometheus称为Alertmanager的告警客户端;
- 反过来,Alertmanager也是应用程序,它自身同样应该纳入Prometheus的监控目标;
- 配置逻辑
- 在Alertmanager上定义receiver,他们通常是能够基于某个媒介接收告警消息的特定用户;
- Email、Wechat、Pagerduty、Slack和Webhook等是为常见的发送告警信息的媒介;
- 在不同的媒介上,代表告警消息接收人的地址表示也会有所不同;
- 在Alertmanager上定义路由规则(route),以便将收到的告警通知按需分别进行处理;
- 在Prometheus上定义告警规则生成告警通知,发送给Alertmanager;
三 Alertmanager
3.1 Alertmanager功能
Alertmanager除了基本的告警通知能力外,Alertmanager还支持对告警进行去重、分组、抑制、静默和路由等功能;
- 分组(Grouping):将相似告警合并为单个告警通知的机制,在系统因大面积故障而触发告警潮时,分组机制能避免用户被大量的告警噪声淹没,进而导致关键信息的隐没;
- 抑制(Inhibition):系统中某个组件或服务故障而触发告警通知后,那些依赖于该组件或服务的其它组件或服务可能也会因此而触发告警,抑制便是避免类似的级联告警的一种特性,从而让用户能将精力集中于真正的故障所在;
- 静默(Silent):是指在一个特定的时间窗口内,即便接收到告警通知,Alertmanager也不会真正向用户发送告警信息的行为;通常,在系统例行维护期间,需要激活告警系统的静默特性;
- 路由(route):用于配置Alertmanager如何处理传入的特定类型的告警通知,其基本逻辑是根据路由匹配规则的匹配结果来确定处理当前告警通知的路径和行为;
3.2 告警规则文件
类似于记录规则,告警规则(Alerting rule)也定义在独立的文件中,而后由Prometheus在rule_files配置段中加载;
- 尽管可以将所有的告警规则定义在同一个文件中,但出于便捷管理之目的,建议将其按功能分布放置于不同的文件中;
- rule_files配置段加载告警规则的文件,同样可以使用文件名通配机制;
rule_files:
- "rules/*.yaml"
- "alert_rules/*.yaml" #专用于加载告警规则相关的文件
3.3 告警规则
类似于记录规则,有着类似或相关联功能的告警规则同样可以组织为group,从而为规则名称提供“名称空间”;一个组内的每个告警规则必须有个名称,且在该组内其名称必须唯一;
- alert:告警规则的名称
- expr:基于PromQL表达式的告警触发条件(布尔表达式),用于计算是否有时间序列可以满足该条件;可以使用由Recording rule定义的指标;
- for:控制在触发告警之前,测试表达式的值必须为true的时长;
- 表达式值为true,但其持续时间未能满足for定义的时长时,相关的告警状态为pending;
- 满足该时长之后,相关的告警江北触发,并转为firing状态;
- 表达式的值为false时,告警将处于inactive状态;
- labels:告警规则被激活时,相关时间序列上的所有标签都会添加到生成告警实例之上,而labels则允许用户在告警上附加其它自定义的标签;该类标签支持模板化;
- 告警的名称及其标签即为告警的标识,因而,这类似于时间序列的标识机制;
- annotations:附加在告警之上的注解信息,其格式类似于标签,但不能被用于标识告警实例;经常用于存储告警摘要,且其值支持模板化;
3.4 触发告警
- Prometheus以一个固定的周期来评估所有告警规则,其值由evaluate_interval参数定义,默认15s;在每个评估周期内,Prometheus会计算每个告警规则中的布尔表达式并更新告警状态;
- 未使用for字句的告警,会自动从Inactive状态转为Firing,它只需要一个评估周期便能触发;而带有for字句的告警状态将先转为Pending,而后才到Firing,因而至少需要两个评估周期才能触发;
- 除以Pending状态的告警,在其支持时长满足for字句的定义之前,若布尔表达式的值转回了false,则告警状态将转回Inactive;
- 由此可见经由Pending在到Firing的转换,可以确保告警更有效,且不会来回浮动;
- Prometheus将为Pending和Firing状态中的每个告警创建指标,该指标名称为ALERT,其值固定为1,并且在告警处于Pending和Firing状态期间存在;在此之后,它将不接受任何更新,知道过期;
3.5 告警模板
Prometheus支持在告警中使用模板
- 告警模板是指在告警中的标签和注解上引用时间序列的标签和样本值的方法;
- 它使用标准的Go语法,并暴露一些包含时间标签和值的变量;
- 标签引用:{{$label_name}}
- 指标样本值引用:{{$value}}
- 若要在description注解中引用触发告警的时间序列上的instance和job标签的值,可分别使用“{{$label.instance}}”和“{{$label.job}}”;
3.6 告警路由
Alertmanager的route配置段支持定义树状路由表,入口位置称为根节点,每个子节点可以基于匹配条件定义出一个独立的路由分支;
- 所有告警都将进入路由根节点,而后进行子节点遍历;
- 若路由上continue字段的值为false,则遇到第一个匹配的路由分支后即终止;否则,将继续匹配后续的子节点;
3.7 记录规则
3.7.1 recording rule
- 记录规则将生成新的时间序列,因而其名称必须是规范的指标名称格式;
- 记录规则必须定义在规则组(rule group)中,各规则按给定的顺序依次运行;
3.7.2 规则组的定义语法
groups:
[ - <rule_group> ]
<rule_group>
name: <string>
[ interval: <duration> | default = global.evaluation_interval ]
[ limit: <int> | default = 0 ]
rules:
[ - <rule> ... ]
3.7.3 记录规则的定义语法
<rule>
record: <string>
expr: <string>
labels:
[ <labelname>: <labelvalue> ]
3.7.4 记录规则使用案例
记录规则通常要保存于单独的文件中。如rules/recording_rules.yaml;
而后在prometheus.yml中通过rule_files加载该文件;
groups:
- name: example
rules:
- record: job:http_inprogress_requests:sum
expr: sum by (job) (http_inprogress_requests)