核心概念
告警引擎支持三种核心判定模式:阈值判定
查询返回原始指标数值,由告警引擎在内存中进行阈值比对
数据存在
查询语句包含过滤条件,仅返回异常数据,查到数据即告警
数据缺失
用于监控数据上报中断的场景
阈值判定模式
此模式适用于需要对同一指标进行多级告警(如 Info/Warning/Critical)或需要获取精确恢复值的场景。配置方式
- 查询语句 (PromQL):编写 不包含 比较运算符的 PromQL,只返回指标数值。
- 示例:查询内存使用率
- 示例:查询内存使用率
- 阈值条件:在规则配置中定义不同严重级别的阈值表达式。变量
$A代表查询结果的值。- Critical:
$A > 90(内存使用率超过 90% 触发严重告警) - Warning:
$A > 80(内存使用率超过 80% 触发警告告警)
- Critical:
多查询支持与数据关联
Monitors 支持在一个告警规则中配置多条查询语句(分别命名为 A、B、C 等),并支持在阈值表达式中同时引用这些查询结果(如$A > 90 and $B < 50)。
- 自动关联:告警引擎会自动根据 标签 对不同查询语句返回的结果进行关联。
- 对齐要求:只有当两条查询语句返回的数据包含 完全相同 的标签集时,它们才能被关联到同一组上下文中进行计算。
- 示例:查询 A 返回
cpu_usage_percent{instance="host-1", job="node"},查询 B 返回mem_usage_percent{instance="host-1", job="node"},则$A和$B可以成功关联。 - 注意:如果查询 A 多了一个标签(如
disk="/"),而查询 B 没有,则无法关联。建议在 PromQL 中使用sum by (...)或avg by (...)等聚合操作,显式控制返回的标签,确保多条查询结果的标签一致。
- 示例:查询 A 返回
- 表达式引用:启用阈值判定时,Critical、Warning、Info 的表达式合计必须引用每个查询。每个级别不必引用全部查询,例如 Critical 使用 A、Warning 使用 B 是允许的。
工作原理
告警引擎周期性执行 PromQL,获取所有 Series 的当前值。随后,引擎遍历每个 Series,依次匹配 Critical、Warning、Info 条件。一旦满足某个级别的条件,即产生对应级别的告警事件。恢复逻辑
支持多种恢复策略:恢复查询语句支持嵌入变量(格式为
${label_name}),会被自动替换为告警事件中对应的标签值,实现针对具体告警对象的精确检测。数据存在模式 (Data Exists)
此模式与 Prometheus 原生告警规则(Alerting Rules)的行为一致。适用于习惯直接在 PromQL 中定义阈值的用户,或需要高性能处理大量 Series 的场景。配置方式
- 查询语句:编写 包含 比较运算符的 PromQL,仅筛选出异常数据。
- 示例:查询内存使用率超过 90% 的节点
- 示例:查询内存使用率超过 90% 的节点
- 判定规则:无需额外配置阈值表达式。引擎只要查询到结果,即认为触发告警,查到几条数据就生成几个告警事件。
恢复逻辑
- 数据消失即恢复:引擎周期性查询,如果某些数据查不到了,引擎判定对应的告警恢复。注意:数据的标识是基于标签集的。
- 恢复查询(可选):可配置一个独立的查询语句用于判定恢复(例如查询
up{instance="${instance}"} == 1来确认服务恢复),查到数据才算恢复。这个 QL 中引入了变量${instance},会被替换为告警事件中的具体标签值。 - 手工关闭:告警保持活动,直到用户手工关闭。
优缺点分析
- 优点
- 缺点
- 性能更优:过滤逻辑下推至 Prometheus 服务端,减少了传输到告警引擎的数据量
- 迁移成本低:可直接复用现有的 Prometheus Rule 语句
数据缺失模式 (No Data)
此模式专门用于监控监控对象是否存活或数据上报链路是否正常。配置方式
- 查询语句:编写预期应该一直存在的指标查询。
- 示例:
up{job="my-service"}
- 示例:
- 判定规则:如果连续 N 个周期无法查询到该 Series 的数据(注意:是完全查不到数据,而不是值为 0),则触发”数据缺失”告警。
- 引擎重启:如果告警引擎(monitedge)重启,内存中的状态丢失,如果重启之前可以查到的数据重启之后恰好查不到了,则无法告警。重启之后会重新开始统计缺失周期。
典型应用
- 监控 Exporter 宕机。
- 监控埋点上报服务中断。
- 监控批处理任务未按时执行。
子模式一:按 Series 监控(Per-Series)
当某个 Series 曾经可以查到数据,后来连续 N 次查不到时触发告警。这是默认的数据缺失检测模式。- 要求:目标 Series 必须至少被引擎观测到一次,才能建立基线。
- 局限:如果某个监控对象从来没有上报过数据(例如:Exporter 安装后从未成功采集到一条指标),此模式无法触发告警。
- 字段:
enabled: true,severity(Critical | Warning | Info)。
子模式二:全空结果告警(Alert on Empty Result)
当所有查询在连续 N 次检查中均返回空结果时触发告警。此模式专门覆盖”数据从未上报过”的场景,弥补按 Series 模式的盲区。- 适用场景:新部署的 Exporter 从未成功采集到指标;批处理任务从未产生过输出;希望在目标完全不存在时立即告警。
- 字段:
alert_on_empty_result: true,alert_on_empty_result_severity(Critical | Warning | Info)。 - 恢复逻辑:一旦任意查询返回非空结果,经过连续
recovery_check_times次确认后自动恢复。
两个子模式可以同时开启,并且相互独立运行。
恢复方式
恢复方式(字段end_mode)只出现在子模式一(按 Series 监控,即界面上“之前查到过数据,现在查不到了,就告警”那张检测卡)内部,只对这张卡里的判定生效。子模式二的恢复方式不可配置,固定为“任一查询重新查到数据后自动恢复”,界面以只读文本展示,没有下拉框。
子模式一内可选的恢复方式:
恢复方式属于单个判定、不是页签级共享设置,因此它不在“触发与恢复条件”卡里——那张卡只放所有已启用判定共用的字段(
触发方式、触发条件、恢复条件)。
对比 Prometheus 原生的 absent() 函数
高级配置
保存时校验
创建或更新告警规则时,以下字段中的查询语句会在保存前进行语法校验,校验不通过则保存被拒绝,并返回包含具体解析错误的提示(如invalid Prometheus-compatible query: PromQL: ...; MetricsQL: ...):
- 主查询:规则中配置的所有查询语句(Queries)。
- 关联查询:所有关联查询语句(Relate Queries)。
- 阈值恢复查询:阈值判定模式下,恢复方式为“查询语句”时的恢复查询。
- 数据存在/数据缺失恢复查询:对应模式下,恢复方式为“查询语句”时的恢复查询。
- 变量必须闭合:查询语句中的
${label_name}变量必须正确闭合,未闭合(如${host)会报错query contains an unterminated label variable。 - 变量不能为空:
${}这类空变量会报错query contains an empty label variable。 - 长度限制:单条查询语句最长 64KB,超限同样无法保存。
保存时校验只做语法层面的保守检查,通过校验不代表数据源(Prometheus/VictoriaMetrics 实例)一定能执行该语句。
标签与变量
Monitors 会自动解析 Prometheus 返回的 Labels。在 恢复查询 或 关联查询 中,可以使用${label_name} 引用标签值。
比如某个告警规则查询语句返回的结果包含标签 instance="host-1" 和 job="node",则在恢复查询中可以这样写:
${instance} 替换为 host-1,${job} 替换为 node,也就是告警事件标签中的具体值。
Go 模板变量
除${label_name} 外,恢复查询 与 关联查询 的表达式还接受 Go 模板语法 {{ $labels.<标签名> }}。同一条表达式只能选用其中一种写法:表达式内同时出现 ${...} 与 {{...} 时保存会被拒绝,报 query expression mixes ${label} placeholders with Go template; use {{ $labels.name }} only;不同表达式之间互相独立,可以各写一种。
下面三类字段支持模板,主查询不支持——告警引擎不会对主查询做变量渲染,写在主查询里的 {{ ... }} 会被当作查询文本本身(在 PromQL 中会因语法非法而在保存时被拒绝):
- 关联查询:规则中配置的所有关联查询语句。
- 阈值恢复查询:阈值判定模式下,恢复方式为”查询语句”时的恢复查询。
- 数据存在/数据缺失恢复查询:对应模式下,恢复方式为”查询语句”时的恢复查询。
$labels(当前告警实例的标签):恢复查询与关联查询在告警事件组装之前执行,因此 $values、$relates 等变量在这里不可用。可用的函数只有 len、index、regexQuoteMeta、replace、eq、ne、lt、le、gt、ge、and、or、not,并支持 if/else 控制结构;printf 等格式化函数、Sprig 函数集、range 循环、define/block,以及 ./.Field 写法都会被拒绝(. 写法报 use $labels to access instance labels)。
标签名本身含点号时(如 service.name)不能写成 $labels.service.name,需改用 index $labels "service.name"。
假设告警实例带有 host="host-1",恢复查询可以这样写:
up{host=~"host-1"} == 1。注意模板产出的值要由表达式自己加引号:上例里的 " 属于 PromQL 字符串,{{ ... }} 只负责产出值本身。
渲染时机与失败处理
模板由 monit-edge 按告警实例逐条渲染:每个实例用自己那份标签渲染一次,同一条规则对不同实例会得到不同的查询语句。 表达式自己负责引号与转义。 模板输出会原样插入,不做转义——{{ $labels.host }} 只产出标签值本身,引号要由表达式自己写(如上例的 host=~"{{ ... }}");标签值可能含引号等特殊字符时,请自行用 regexQuoteMeta 或 replace 处理。这与 ${label_name} 不同:恢复查询里的 ${label_name} 由引擎转义后放进查询的引号字面量中,而关联查询里的 ${label_name} 是原样替换,且未匹配到的占位符会保留原样。
渲染失败:关联查询渲染失败时(例如引用了告警事件里不存在的标签、模板语法非法),该条关联查询会被跳过、其余关联查询照常执行,同时引擎记录一条 render related query 规则上下文错误,并带上 query_ref="<关联查询名称>"。恢复查询表达式只要含 {{ 就会被当作”含变量”,按实例渲染后执行,而不是作为静态表达式只执行一次。
关联查询 (Enrichment)
为了丰富告警通知的内容,可以配置”关联查询”。关联查询不参与告警判定,仅用于获取额外信息。- 场景:CPU 告警时,同时查询该机器的
mem_usage_percent负载情况,展示在告警详情中,辅助排查。 - 变量:关联查询中支持
${label_name}变量,也支持 Go 模板{{ $labels.<标签名> }}(需 monit-edgev0.75.4或以上),用于针对具体告警对象查询;两种写法的限制与渲染规则见上文「标签与变量」。 - 渲染失败:某条关联查询表达式渲染失败时,该条查询被跳过、其余关联查询继续执行,并记录
render related query规则上下文错误。 - 结果展示:关联查询的结果可以在告警规则的备注描述中引用,其变量是
$relates,您可以查看 备注描述 的详细使用说明。