如何在查询中使用选定的时间范围(Prometheus 与 Grafana)
Grafana 用 $__range 表示当前时间范围长度;Prometheus 的 range query、范围向量和 @ 修饰符含义不同。区分面板查询范围、计算窗口、步长与求值时间。
一句话回答:Grafana 在发出查询前替换 $__range 等变量;$__range 是当前范围的时长字符串,不是 PromQL 内置语法。Prometheus 的查询起止时间与 step 决定求值时刻,metric[1h] 定义每次求值使用的样本窗口,@ 则固定选择器的求值时间。三者不能互换。
Grafana:时间选择器 + $__range
Grafana 面板的时间由右上角 Time Picker 控制,查询本身不用关心绝对时间。三种内置变量:
| 变量 | 含义 | 示例 |
|---|---|---|
$__range |
当前选中的时长字符串;秒数用 $__range_s |
increase(http_requests_total[$__range]) |
$__interval |
按时间范围和分辨率估算的分组间隔 | 不宜直接作为 rate 窗口 |
$__rate_interval |
rate 推荐回看窗口(不是查询 step) | rate(metric[$__rate_interval]) |
典型场景——"统计所选时间范围内的总请求数":
sum(increase(http_requests_total[$__range]))
若要单个区间总量,用在结束时刻求值的 Instant 查询;Range 查询会在每个评估时刻计算一遍回看窗口,得到的是滚动增量序列。increase 使用外推估算,不是逐请求精确计数。
Prometheus:范围向量与 @ 运算符
Prometheus 表达式浏览器中手动指定:
http_requests_total[5m] # 以当前时间为终点的 5 分钟窗口
http_requests_total[5m] @ 1696000000 # 以指定 Unix 时间戳为终点的窗口
increase(http_requests_total[1h] @ 1696000000) # 某时刻之前 1 小时的增量
@ 运算符在做"复盘昨晚那个时段"的排障时很有用。
常见误区
- 模板变量属于查询客户端:将表达式移出 Grafana 时,先替换
$__range等变量,再按目标入口指定起止时间;它们不是 PromQL 运算符。 - 固定窗口不等于固定结果:
[5m]的窗口长度不变,但随评估时间移动,查询结果仍会变化。 - rate 与范围:长回看窗口会平滑短期变化,而非自动减少底层样本;常用
$__rate_interval,并核对抓取间隔。 - increase 的小数:边界外推可产生小数;窗口样本不足可能无结果。至少覆盖多个抓取点,4 倍抓取间隔是 rate 窗口常用下限。
常见问题(FAQ)
Q:$__range 在表格(Table)面板里能用吗?
A:能。变量与面板类型无关,表格里做"所选时段汇总"正是 increase(...[$__range]) 的经典用法。
Q:变量在报警规则里能用吗?
A:不能。Grafana 报警规则独立于面板时间,需要在规则里写死评估窗口(如 [5m])。报警要的是确定性的判断窗口,不该跟随查看者的时间选择器。
Q:怎么查"昨天下午 2 点到 3 点"的数据?
A:Prometheus 表达式浏览器用 metric[1h] @ <昨天下午3点的Unix时间戳>;Grafana 直接把 Time Picker 切到自定义绝对时间。
参考资料
本文依据官方资料核对,未进行现场运行测试;代码与配置示例需结合实际版本、权限和环境验证。