Prometheus中如何实现图表仅展示Gauge指标的持续递增无断点趋势
问题定位与可落地方案
核心问题本质
你现在遇到的不是监控查询语法问题,而是作为Gauge类型上报的累计请求计数指标,因为进程重启、上报链路断开重连、缓存刷新等原因,出现了非业务预期的数值跳降(跳降后上报值远低于历史最高值),需要对原始序列做修正,让最终展示的图表全程保持持续递增的趋势,没有断点和下跌段。
已尝试方案的问题说明
- 执行
sum by (job) (increase(requests{job="CDN",exported_instance="push_19"} [1h]))得到结果偏差极大:increase函数原生是针对Counter类型指标设计的,不会对Gauge类型的跳降做自动补偿,计算时会把跳降产生的负差值直接从总增量里扣减,所以实际2.4亿的总请求量,会被多次跳降的差值抵扣到只剩1万左右的结果。 - 执行
sum by (job) (sum_over_time (requests{job="CDN",exported_instance="push_19"}[1h]))结果不符合预期:这个函数的逻辑是把时间窗口内所有采样点的原始值直接累加,既不会修正跳降,算出的总数值本身也远超过实际请求量,完全和展示需求不匹配。 - 执行
sum(running_sum(increase(requests))) by (job)报解析错误:running_sum是较新版本Prometheus才内置的序列累计函数,你当前使用的Prometheus版本过旧,没有内置这个函数,所以会抛出未知函数名的解析错误。
适配需求的实现方法
完全匹配你提出的“原始序列10、12、9、10,输出10、12、13持续递增序列”要求的逻辑是:逐点计算相邻采样值的差值,遇到差值为负(即跳降)时,直接把该段差值修正为0,再把所有修正后的非负差值做累计,最终得到的序列只会持续向上,不会出现下跌。
兼容全版本Prometheus的写法(无函数依赖,不会报解析错)
sum by (job) ( max_over_time( requests{job="CDN",exported_instance="push_19"}[10000y] ) )
这个写法的逻辑是每个时间点的输出值,取从最早历史到当前时刻的所有采样点的最大值,从根源上避免出现后一个点比前一个点低的情况,不会出现跳降断点。缺点是如果跳降后指标的新增增长还没超过历史最高值,图表会暂时走平,不会立刻往上抬。
新版本Prometheus的精准匹配写法
如果你的Prometheus版本支持running_sum函数,可以用下面的语句,完全匹配你举的序列修正效果:
sum by (job) ( running_sum( clamp_min( increase(requests{job="CDN",exported_instance="push_19"}[15s]), 0 ) ) )
这个写法的逻辑是:
- 先取15秒窗口内的增量,用
clamp_min把所有小于0的增量(也就是跳降产生的负增长)替换为0 - 再把这些修正后的非负增量逐点累计,最终得到的序列就会按照你期望的逻辑,把跳降的部分补上,全程保持持续递增的趋势。
无代码改造成本的兜底方案
如果不想调整Prometheus查询语句,可以直接在Grafana面板里用内置的“系列修正”转换规则,遍历原始序列的每个采样点,当当前值低于上一个展示值时,自动把差值叠加到当前值上,实现持续递增的展示效果,不需要修改后端的查询逻辑。
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

