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

如何通过PromQL或Grafana获取Prometheus指标最后一次值变更的时间戳?

获取指标最后一次值变更时间戳的解决方案

我来帮你搞定这个问题——用PromQL完全可以实现需求,你之前的查询没成功主要是逻辑没踩对路子,咱们拆解清楚:

一、PromQL的正确实现方式

先说说你之前的查询为啥不行:timestamp(changes(up{job="prometheus"}[1h]) > 0) 里,changes()返回的是指定时间范围内的变更次数,用>0过滤后得到的是布尔值(1或0),而timestamp()取的是这个布尔值的生成时间(也就是最后一次指标采集的时间),自然拿不到真正的变更时刻。

针对不同类型的指标,有对应的正确写法:

1. 针对Gauge类型指标(比如up这类可以上下波动的指标)

要捕捉最后一次值变化的时刻,可以用对比当前值与历史值的方式,结合子查询和last_over_time来定位:

timestamp(last_over_time(
  (up{job="prometheus"} != ignoring() up{job="prometheus"} offset 1m)
  [1d:1m]
)) * 1000

逐段解释下:

  • up != ignoring() up offset 1m:对比当前时刻的指标值和1分钟前的数值,如果不相等,说明这1分钟内发生了变更,返回1;否则返回0
  • [1d:1m]:子查询,过去24小时内每分钟执行一次上面的对比,生成一个由1和0组成的时间序列
  • last_over_time(...):从这个序列里取出最后一个值为1的点(也就是最近一次变更的时刻)
  • timestamp():提取这个点的时间戳,乘以1000转成毫秒(适配Grafana的时间格式)

2. 针对Counter类型指标(单调递增的计数器)

Counter只会递增,所以用increase判断是否有增长即可,逻辑类似:

timestamp(last_over_time(
  (increase(your_counter{job="prometheus"}[1m]) > 0)
  [1d:1m]
)) * 1000

二、Grafana中的优化展示

如果要在Grafana里把这个时间戳展示得更友好,可以做这些调整:

  • 转成可读时间:选择「Stat」或「Text」面板,在「Value options」里把「Unit」设为「Time」,毫秒时间戳会自动转换成YYYY-MM-DD HH:mm:ss格式
  • 处理无变更的情况:如果指标在指定时间范围内没变化,上面的查询会返回空。可以加个兜底逻辑,返回最后一次采集的时间,并配合面板注释说明:
timestamp(last_over_time(
  (up{job="prometheus"} != ignoring() up{job="prometheus"} offset 1m)
  [1d:1m]
)) * 1000
or
timestamp(last_over_time(up{job="prometheus"}[1d])) * 1000

三、额外注意事项

  • 子查询的时间范围(比如[1d:1m])可以根据你的需求调整:第一个值是查询的时间窗口,第二个是采样间隔。如果你的指标采集频率不是1分钟,要把offset 1m和采样间隔改成对应的频率(比如30秒就用offset 30s和[1d:30s])
  • 如果需要更精确的变更时间,可以缩小采样间隔,但注意不要太小,避免Prometheus查询压力过大

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 11:57:29