跳到主要内容

指标规则

指标规则把阈值写在 PromQL 里,一条规则可带 S1 / S2 / S3 多档级别,查询返回的标签会落到事件上供路由使用。

这页办完你会看得懂、也写得出 Prometheus 类规则的「告警条件」那一步——阈值写在哪儿、 一条规则怎么带多个级别、查询返回的标签里哪些最后会落到事件上。

这是 Prometheus Like 类数据源的规则类型:Prometheus 本身、VictoriaMetrics、Thanos、Mimir。 其他类型见日志规则和 SQL 规则。

查询列表​

第 3 步告警条件下面是一个叫查询与阈值的列表。每一项是一条 PromQL 加一个级别, 用列表下方的虚线按钮加新的一项。

查询 mem_used_percent > 80
级别 S2

每一项每个执行周期以即时查询的方式打到数据源上——和即时查询发的是同一种请求, 不是 range query。

阈值就写在 PromQL 里​

没有单独的阈值输入框。比较写在表达式里,查询返回几条序列就产生几条事件:

mem_used_percent > 80

数据源只会返回大于 80 的那些序列,所以返回的每一条按定义就是异常点。 这和 Prometheus 的告警规则完全一样,也正是判定便宜的原因:过滤是在时序库里做的,不在夜莺里。

由此带来几个实际后果:

  • 一条序列进,一条事件出。 查询返回 30 台越线的机器,就产生 30 条事件, 每条带着那条序列自己的标签。想少一点,就用 sum by (...) 聚合。
  • 查不到东西等于「正常」。 「没有任何东西超阈值」和「exporter 不上报了」在结果上都是空, 区分不了。要对「数据消失」告警,就单写一条规则,用 up == 0 或 target_up == 0。
  • 恢复时拿不到值。 序列不再被返回时事件就恢复了,而恢复时刻的值没有—— 数据库压根什么都没返回,没地方读。

四则运算和条件筛选都能用,毕竟它就是 PromQL:

http_request_success{region="beijing"} / http_request_total{region="beijing"} < 0.995

一条规则里的多个级别​

列表里加多条查询,每条各带自己的级别。常见写法:

disk_used_percent > 85 S2
disk_used_percent > 95 S1

加了第二条查询之后,列表标题旁边会出现级别抑制开关。打开它, 同一条序列同时命中多档时只有最严重的那档产生事件——磁盘到 97% 只按 S1 叫你一次,不会叫两次。

抑制比较的是序列,不是规则:只有指标名和全部标签都完全相同的事件之间才会互相抑制。 S1 压 S2,S2 压 S3。

执行频率与持续时长​

查询列表下面:

字段默认含义
执行频率@every 60s秒级精度的 cron 表达式。下拉里有常用间隔,@every 15s 和标准 cron 写法都收
持续时长 (s)60条件要连续成立多久才产生事件。0 表示第一次命中就报

持续时长是按序列判的:同一条序列要在连续几个周期里都被返回,直到累计时间覆盖了持续时长。 只出现过一次就消失的序列,永远不会产生事件——也就不会有恢复,因为它压根没产生过事件。

执行频率按你负担得起的值来设,不是按下拉里最小的那个。一条匹配十个数据源的规则设成 @every 15s,一小时就是 2400 次查询,还没算任何人打开仪表盘。 详见判定周期与恢复。

保存之前先预览​

每张查询卡片上都有数据预览,把表达式打到选中的数据源上并画成图。它有两个用途:

  • 确认表达式到底返不返回东西——图是空的,那这条规则永远不会触发;
  • 拿数据的真实形态核一下阈值,别在一个常年在 95 的指标上设 80。

预览需要一个具体的数据源,所以哪怕规则最终会匹配好几个,也先在第 2 步里选一个。

想要连标签、模板和通知路由一起验的更严格的检查,用模拟触发。

事件上最后带着什么​

事件的标签来自三个地方,按顺序:

  1. 序列自己的标签,就是查询返回的那些——所以 sum by (service) 和 sum by (instance) 产生的事件形态差别很大;
  2. 规则的附加标签(第 1 步配的),追加到这条规则产生的每一条事件上;
  3. 附加信息,逐事件渲染,那是文本不是标签。

事件的值是序列在触发时刻的值,在模板里是 $value,标签是 $labels.<名字>。 见标签、附加信息与级别。

关于聚合有一点要注意:sum by (service) (...) 会把 instance 和 ident 丢掉。 对服务级别的告警来说通常正是你要的,但也意味着事件没有一台可指的机器—— 而告警自愈是靠 ident 标签找机器的,那样它就无从下手了。

变量:一条规则,逐机器的不同阈值​

一条查询可以带变量,让一条规则覆盖阈值各不相同的机器。在查询卡片上启用变量, 然后在 PromQL 里用 $名字 引用:

mem_used_percent{ident="$hosts"} > $threshold

变量分类型:

类型提供什么
阈值一个数字,直接替换进表达式
枚举值一组标签取值,把查询限制在这些取值上
机器标识一组机器,用和设备列表一样的筛选条件挑

变量集合可以嵌套,子集合对它覆盖的那些机器会覆盖父集合的取值—— 「全部 80%,这三台编译机 95%」就是这么写成一条规则的。

变量是有性能代价的:规则会按组合展开成多条查询。有少数几个例外、 否则就得写几条几乎一样的规则时才用它,别当默认写法。

下一步​