You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Prometheus中基于Z分数配置异常检测告警规则?

Prometheus指标异常检测表达式与告警规则说明

现有表达式的问题

你写的PromQL存在核心问题,无法直接用于触发告警:

  • 运算逻辑错误:当前表达式的计算逻辑是5分钟窗口均值 - (48小时均值 / 48小时标准差),不符合基于标准差的异常检测(Z-score)的标准公式。正确的偏离度计算应该是(当前值 - 历史基线均值) / 历史基线标准差,你漏了给分子部分加括号,运算优先级错误,返回的结果完全不代表指标偏离基线的程度。
  • 缺少异常判定与告警配置:就算修正了计算逻辑,这个表达式本身只会返回一个数值,没有定义“偏离到什么程度算异常”的阈值,也没有配套的告警规则配置,Prometheus无法直接基于这个裸表达式触发通知。
  • 存在边界错误:如果48小时窗口内指标完全无波动,标准差为0时,表达式会触发除以零错误,返回空值导致漏检。

修正后的可落地告警方案

第一步:修正核心异常检测逻辑

使用Z-score方法计算偏离度,同时补全边界处理,修正后的核心计算PromQL如下:

(
  avg_over_time(my_metrics{service_name="aService"}[5m])
  - avg_over_time(my_metrics{service_name="aService"}[48h])
) / clamp_min(stddev_over_time(my_metrics{service_name="aService"}[48h]), 0.001)

这里用clamp_min将标准差的最小值限制为0.001,彻底避免除以零的问题。

第二步:编写完整告警规则

将以下规则写入Prometheus的告警规则配置文件,即可实现异常自动触发:

groups:
- name: service_anomaly_detection
  rules:
  - alert: AServiceMyMetricsAbnormal
    expr: |
      abs(
        (
          avg_over_time(my_metrics{service_name="aService"}[5m])
          - avg_over_time(my_metrics{service_name="aService"}[48h])
        ) / clamp_min(stddev_over_time(my_metrics{service_name="aService"}[48h]), 0.001)
      ) > 3
    for: 2m
    labels:
      severity: warning
    annotations:
      summary: "aService服务my_metrics指标异常"
      description: "指标近5分钟均值偏离48小时基线超过3个标准差,当前偏离度为{{ $value | humanize }}"

关键配置说明:

  • abs() > 3:取偏离度的绝对值,覆盖指标突增、突降两种异常场景,阈值3是3σ原则的经验值,对应正态分布下99.7%的置信度,误报率低;如果需要更高检测敏感度可以调低到2,需要更低误报可以调高到4。
  • for: 2m:要求异常状态持续2分钟才触发告警,过滤瞬时毛刺导致的误报,可根据指标波动特性调整时长。
  • labels/annotations:定义告警级别、通知展示内容,会被Alertmanager读取用于路由和渲染通知内容。

生效步骤

  1. 保存规则文件后,执行promtool check rules <你的规则文件路径>校验语法正确性。
  2. 调用Prometheus reload接口或重启服务,加载新的告警规则。
  3. 在Alertmanager中配置好对应告警级别的接收渠道(邮件、企业微信、钉钉等),异常触发后就会自动发送通知。

内容的提问来源于stack exchange,提问作者panza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 15:45:48