指标告警

夜莺监控(Nightingale)把告警分成告警+通知两个部分,告警指的是通过规则,周期性判定,最终产生告警事件,通知指的是告警事件的后续 Pipeline 和通知流程。本章节先介绍告警部分,最终能产生告警事件咱就算成功。

告警原理

夜莺支持两个告警模式,普通模式和高级模式(高级模式暂未开源,后面也计划开源):

  • 普通模式:在 Promql 中配置告警阈值,查询条件阈值设置 在一起,没有特殊需求的话就使用普通模式即可,这个模式就和 Prometheus 的告警逻辑是一样的,性能比较好。不过告警恢复时要想拿到恢复时的值稍微麻烦点
  • 高级模式:查询条件阈值设置 分开,如果有多个查询条件需要做加减乘除计算,可以使用高级模式,在告警事件的现场值中会将每个查询条件的值展示出来,在告警恢复时也可以轻松拿到恢复时的值

普通模式的原理

普通模式下,夜莺会根据用户配置的执行频率,周期性查询数据源,查询条件就是用户配置的 Promql,查询方式是 instant query,即调用的数据源的 /api/v1/query 接口,查到几条数据就生成几条告警事件。比如 Promql 是 cpu_usage_active > 80,夜莺拿着这个 Promql 去查询时序库,时序库返回的结果肯定是 CPU 利用率大于 80% 的那些数据点,都是触发了阈值的数据点,所以夜莺应该生成告警事件。

如果用户在告警规则里配置了大于 0 的 持续时长,此时就会更复杂一些,夜莺会在持续时长内按照执行频率多次执行查询,每次都查到某个数据才生成告警;如果 持续时长 置为 0,表示只要有一次查询到数据,就生成告警。

如果之前生成了告警事件,后来再次查询时发现没有数据了,此时就会生成恢复事件,毕竟查不到数据了嘛,就说明时序库里没有数据达到阈值条件了,故而时序库不再返回任何数据。针对告警恢复,还有一个高级配置叫 留观时长,表示在恢复事件生成后,夜莺会继续观察一段时间,如果在留观时长内又查询到数据了,就不会生成恢复事件(继续维持告警状态);如果留观时长内每次都没有查询到数据了,才会最终生成恢复事件。

从上文分析来看,告警恢复时,时序库不返回任何数据,所以夜莺无法拿到恢复时的值,这也是很多用户在使用普通模式时的一个痛点。夜莺为此设计了一个方式来解决这个问题,具体可以参考这篇文章《告警恢复时如何拿到恢复时的值?》。

高级模式的原理

高级模式下,阈值条件不放到 Promql 里,Promql 中只写过滤条件,比如 Promql:

cpu_usage_active{cpu="cpu-total"}

这样一来,夜莺拿着这个 Promql 去查询时序库,时序库每次都是返回 CPU 利用率的所有数据点(性能稍差),然后夜莺再根据用户配置的 阈值判断 规则,对返回的数据在内存里进行判断,如下图所示:

高级模式告警

高级模式和普通模式,关键区别是阈值判定是在 Promql 里进而交给时序库来做,还是在夜莺的内存里来做。高级模式下,如果触发了恢复事件,恢复事件里的 TriggerValue 会自动填充为恢复时刻的值,相比普通模式,获取恢复时的值更简单。

高级模式下,还会出现一个 数据缺失 的判断逻辑,俗称 NoData 告警,夜莺的行为是:周期性查询数据源,查到了数据,就塞到内存里,下次再查询,还查到了,那万事大吉,如果下次再查时,某条数据没查到,那这条数据就要告警。

功能说明

了解了原理,我们就来配置一个告警规则,演示一下如何使用夜莺的指标告警功能。

创建入口

菜单入口在 告警-规则管理-告警规则,如下图所示:

规则创建入口

首先要选中左侧的业务组,如果没有任何业务组需要先自行创建一个,因为告警规则可能会很多,需要分门别类管理,也需要权限管控,所以告警规则是和业务组绑定的。

业务组是一个扁平的列表,但是可以渲染成树形结构。只要在业务组名称中使用 / 符号,就可以渲染成树形结构。比如 DBA/MySQLDBA/Redis,就会渲染成上图的树形样式。当然,前提是要在 系统配置-站点配置 菜单中设置业务组展示模式为树形,同时设置业务组分隔符为 /

下面我们着重讲解一下告警规则的各个配置项的含义。

🟢 提示:规则配置页面,各个 form 表单旁边都有 tooltip(就是小问号 icon,鼠标放上去可以看到用法提示),请一定要记得看哪。

基础配置

  • 规则名称:告警规则的名称,比如“机器负载高”,规则名称中可以引用变量,比如 {{ $labels.instance }},但极为不建议这样做,因为这样会导致最终生成的告警事件名称各异,想要对告警事件做聚合查看时非常不方便。
  • 附加标签:在这里配置的附加标签,会追加到生成的告警事件的标签中,后续可以用于告警事件的聚合和过滤。
  • 备注:对告警规则更加详细的描述,支持配置 $labels$value 等变量。

规则配置

  • 数据源:选择数据源类型和筛选条件,用于指定当前这条告警规则生效到哪些数据源,因为很多公司有多套 Prometheus,这样可以方便管理规则。
  • 告警条件:就是配置 Promql,可以在 Promql 中做一些条件筛选和四则运算,比如这个 Promql:http_api_request_success{region="beijing"} / http_api_request_total{region="beijing"} < 0.995 表示:求取 beijing 这个 region 的所有 HTTP 请求的成功率,如果成功率小于 99.5% 就告警。如果告警引擎通过此 Promql 查到了数据,说明有有异常点产生,如果多次查询持续异常,最终满足了持续时间,就会产生一个告警事件。
  • 多告警条件和级别抑制:在一条告警规则中,可以添加多个 Promql 查询条件,此时会自动出现一个 级别抑制 的功能开关,如果打开了级别抑制开关,两个条件同时产生告警的话,只会发送高级别的告警,会对低级别的告警进行抑制,减少打扰。
  • 执行频率和持续时长:这俩配置在页面上都提供了 tooltip,鼠标放上去可以看到用法提示。执行频率就相当于 Prometheus 中的 evaluation_interval,持续时长就相当于 Prometheus 中的 for,如果持续时长为 0,表示只要有一次查询到数据,就生成告警事件。

事件 relabel

这部分页面上提供了说明文档,请自行查阅。在 Prometheus 中有个 relabel 机制,相信很多人都不陌生(如果之前尚未了解,可以自行 Google 一下,挺有用的一个设计),Prometheus 是针对时序数据做 relabel,夜莺这里是针对生成的告警事件做 relabel。

举个场景例子,比如原本有个标签是 instance=10.1.2.3:9090,可以通过 relabel 提取其中的 IP 信息,生成一个新的标签 ident=10.1.2.3,夜莺里的告警自愈功能是需要从告警事件中提取机器信息的,实际就是提取的 ident 标签的值,通过 relabel 提取机器信息写入 ident 标签,方便后续做告警自愈(当前,前提是你在 Categraf 里配置的 hostname="$ip")。

生效配置

这部分也在页面提供了使用说明,请自行查阅。这块最重点的配置是生效时间段,比如某个告警规则只在白天生效,另一个告警规则只在晚上生效,就可以通过生效时间段来配置。

通知配置

夜莺通知配置

老版本是在告警规则里直接配置告警接收人和通知媒介,如果要批量修改则比较费劲。新版本把通知逻辑提取出来,抽象为通知规则,来处理告警事件产生之后的所有逻辑。后面会对通知规则做详细介绍。

通知配置部分,其他各个字段均有 tooltip,鼠标放上去可以看到用法提示,这里就不再赘述了。

告警自愈,即:告警产生之后自动去告警的机器(或指定的特定中控机)执行特定的脚本。所谓的告警的机器,这个信息从哪里取?就是取自告警事件的 ident 标签,那具体执行哪个自愈脚本呢?就是通过通知配置下面的 告警自愈 字段来指定。

附加信息,就类似 Prometheus 告警规则中的 Annotations,告警事件生成之后,夜莺会把这些附加信息追加到告警事件中,后续可以在消息模板中引用,最终在钉钉、飞书、邮件等通知中展示。

实操演示

为了尽快产生告警事件,我这里配置了一个必然会触发的 Promql:

cpu_usage_active > 0

🟢 cpu_usage_active 这个指标是 Categraf 采集的,表示 CPU 利用率,CPU 利用率显然必然会大于 0,所以这个规则很快就可以触发告警事件。如果你没有使用 Categraf,就没有这个指标了,请使用你自己的时序库中的指标来做测试。

夜莺告警规则配置样例

上例中,为了加速产生告警事件,我把执行频率设置为 15s,把持续时长设置为 0,这样一来,夜莺每 15s 就会查询一次数据源,如果查到了数据就会生成告警事件。

稍等片刻,即可发现告警规则左侧的状态字段,变成一个红色的感叹号,表示触发了告警事件,点击之后在侧拉板可以看到这个规则产生的相关告警事件。当然,你也可以在告警事件菜单看到当前的活跃告警(未恢复的告警称为活跃告警)和所有历史告警。

夜莺告警事件

上面的第一条告警事件就是刚刚测试的,其他的事件是之前测试的,不用关心哈。告警事件产生了,说明告警规则配置的没问题,后面就是配置通知规则了,指定什么样的告警事件发给谁,通过什么通知媒介(电话、短信、邮件、飞书、钉钉、企微等,称为通知媒介)来发。

🎯 由于读者水平参差不齐,重口难调,社区小伙伴一直在持续更新优化文档内容,如果您觉得本页文档内容有误或不够完善,欢迎您参与到文档的编写中来,点击下方的 Edit this page on GitHub 即可编辑 👇