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

如何基于多日同时间段生成均值与标准差(PromQL实现)

基于Prometheus实现同时间段历史均值与标准差的异常检测

你的需求完全可以通过PromQL的内置函数和offset特性实现,核心是对齐历史同时间段的数据,再结合统计函数计算均值与标准差,进而识别异常。

步骤1:计算历史同时间段的小时均值

方法1:枚举历史天数(直观易理解)

直接枚举过去14天的同时间段数据,用avg()求平均:

groups:
  - name: my_alert_rules
    rules:
    # 记录过去14天同一小时的错误率均值
    - record: error_rate:1h:avg_over_14d
      expr: avg(
        sum(rate(error_count{some_label="some_value"}[1h])) offset 1d,
        sum(rate(error_count{some_label="some_value"}[1h])) offset 2d,
        sum(rate(error_count{some_label="some_value"}[1h])) offset 3d,
        sum(rate(error_count{some_label="some_value"}[1h])) offset 4d,
        sum(rate(error_count{some_label="some_value"}[1h])) offset 5d,
        sum(rate(error_count{some_label="some_value"}[1h])) offset 6d,
        sum(rate(error_count{some_label="some_value"}[1h])) offset 7d,
        sum(rate(error_count{some_label="some_value"}[1h])) offset 8d,
        sum(rate(error_count{some_label="some_value"}[1h])) offset 9d,
        sum(rate(error_count{some_label="some_value"}[1h])) offset 10d,
        sum(rate(error_count{some_label="some_value"}[1h])) offset 11d,
        sum(rate(error_count{some_label="some_value"}[1h])) offset 12d,
        sum(rate(error_count{some_label="some_value"}[1h])) offset 13d,
        sum(rate(error_count{some_label="some_value"}[1h])) offset 14d
      )

方法2:子查询自动对齐(灵活易维护)

先记录每小时错误率,再按小时分组计算14天内的均值:

groups:
  - name: my_alert_rules
    rules:
    # 记录每小时的错误率
    - record: error_rate:1h
      expr: sum(rate(error_count{some_label="some_value"}[1h]))
    # 按小时聚合过去14天的均值
    - record: error_rate:1h:avg_over_14d
      expr: avg_over_time(error_rate:1h[14d]) by (hour())

by (hour())会自动把过去14天中同一小时的所有数据聚合,完美对齐当前时间的对应时段。

步骤2:计算历史同时间段的标准差

用stddev_over_time函数实现,和均值逻辑一致:

# 记录过去14天同一小时的错误率标准差
    - record: error_rate:1h:stddev_over_14d
      expr: stddev_over_time(error_rate:1h[14d]) by (hour())

如果用枚举法,把avg()替换成stddev()即可。

步骤3:编写告警规则

基于均值和标准差设置告警条件,比如当前错误率超过均值+2倍标准差时触发:

- alert: HighErrorRateAnomaly
      expr: |
        sum(rate(error_count{some_label="some_value"}[1h])) 
        > error_rate:1h:avg_over_14d + 2 * error_rate:1h:stddev_over_14d
      for: 5m
      labels:
        severity: critical
      annotations:
        summary: "异常错误率告警"
        description: "当前错误率: {{ $value }}, 历史同小时均值: {{ $values.error_rate:1h:avg_over_14d }}, 标准差: {{ $values.error_rate:1h:stddev_over_14d }}"

关键优化建议

  • 由于错误率和活跃用户数成正比,建议先将错误率归一化:sum(rate(error_count[1h])) / sum(rate(active_users[1h])),再做历史统计,消除用户量波动的干扰。
  • for: 5m用于过滤瞬时波动的误告警,可根据业务实际调整时长。
  • 确保Prometheus存储保留至少14天的历史数据,否则子查询会丢失数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 02:47:46