跳过正文
  1. 博客/

promQL 按 Label 排序的函数

·115 字·1 分钟·
Prometheus

最近给 Grafana 的 Node Exporter Full 这个公开仪表盘提了一个 PR. 主要是解决与新版的 Grafana 9 的兼容问题。

这个仪表盘中的 CPU 面板图中,需要按顺序精心配置 6 个相差不大的对应每个 CPU 模式的查询。为什么说相差不大,因为其实都是在查同一个指标:node_cpu_seconds_total,只是 mode 不同而已。这样做的目的是需要保证 mode="idle" 这个查询的展示排在最后,因为这个面板的 stack series 渲染逻辑需要如此。今天突然想到是否能只配置一次查询来做到一样的效果,只要保证 API 查询返回的结果中,idle 标签的相关数据被排序在最后就可以。

结果搜了下,发现官方的 promQL 根本没有这样的 sort by label 之类的函数。在 2014 年 Prometheus 自己团队的人就提了一个 Consider supporting sorting by label value 的 issue,觉得应该加入根据 label value 的排序功能,但是一直没什么下文。

到了 2016 年,直接有人实现了它并提交了 PR,但是被拒了,理由是:

拒绝的理由

概述一下就是要维护 promQL 的 纯洁性

嚯,看看这 👎 数量。

然而隔壁的 VictoriaMetrics 的 MetricsQL 却实现了 4 个函数 1

  • sort_by_label
  • sort_by_label_desc
  • sort_by_label_numeric
  • sort_by_label_numeric_desc

无奈的评论

在 PR 的评论中,这条评论算是说出了大家的心声。生态中的两方互相推诿这个实现,社区用户迫切需要的功能总是卡在 promQL 这里。而且现在 Prometheus 的生态确实让人有点无语,功能特性上,官方只有两个不做: 这也不做,那也不做。搞的现在 CortexThanosVictoriaMetrics 等无一不是选择将 Prometheus 这个单实例程序肢解成一个个模块来超越官方的功能局限。

最后,如果官方的 promQL 支持 sort_by_label_desc 的话,CPU 面板的配置就简洁多了,配置一条查询语句即可:

sort_by_label_desc(
    sum by(instancemode) (
        irate(node_cpu_seconds_total{instance="$node"job="$job"}[1m])
    ) 
    / on (instance) group_left
    sum by (instance) (
        irate(node_cpu_seconds_total{instance="$node"job="$job"}[1m])
    ),
    "mode"
)

基于上面这个美好的假设,使用 VictoriaMetrics 作为数据源测试,可以看见效果一切正常。

美好的假设