Prometheus语法PromQL介绍

Prometheus语法PromQL

1.PromQL语法初体验

PromQL Web UI 的 Graph 选项卡提供了简单的用于查询数据的入口,对于 PromQL 的编写和校验都可以在此位置,如图所示:

输入 up,然后点击 Execute,就能查到监控正常的 Target:

通过标签选择器过滤出job 为node-exporter 的监控,语法为:**up{job=”node-exporter”}**,如果条件有多个使用逗号分隔:

注意此时是 **up{job=”node-exporter”}**属于绝对匹配,PromQL 也支持如下表达式:

  • !=:不等于;
  • =~:表示等于符合正则表达式的指标;
  • !:和=类似,=表示正则匹配,!表示正则不匹配。

如果想要查看主机监控的指标有哪些,可以输入 node,会提示所有主机监控的指标:

假 如 想 要 查 询 Kubernetes 集 群 中 每 个 宿 主 机 的 磁 盘 总 量 , 可 以 使 用node_filesystem_size_bytes

查询指定分区大小 **node_filesystem_size_bytes{mountpoint=”/“}**:

或者是查询分区不是/boot,且磁盘是/dev/开头的分区大小:

1
node_filesystem_size_bytes{device=~'/dev/.*',mountpoint!='/boot'}

查询主机 k8s-master01 在最近 5 分钟可用的磁盘空间变化:

1
node_filesystem_avail_bytes{instance="k8s-master01",mountpoint='/',device='/dev/mapper/rl-root}[5m]

目前支持的范围单位如下:

  • s:秒
  • m:分钟
  • h:小时
  • d:天
  • w:周
  • y:年

查询10分钟之前磁盘可用空间,只需要指定offset参数即可:

1
node_filesystem_avail_bytes{instance="k8s-master01",mountpoint='/',device='/dev/mapper/rl-root'}offset 10m

查询 10 分钟之前,5 分钟区间的磁盘可用空间的变化:

1
node_filesystem_avail_bytes{instance="k8s-master01",mountpoint='/',device='/dev/mapper/centos_k8s--master01-root'}[5m] offset 10m

2.PromQL操作符

通过 PromQL 的语法查到了主机磁盘的剩余空间数据,查询结果如下:

可以通过以下命令将字节转换为 GB 或者 MB:

1
node_filesystem_avail_bytes{mountpoint='/'}/1024/1024/1024

也可以将 1024 / 1024 / 1024 改为**(1024 ^ 3)**:

可以看到5个节点的/分区剩余空间都不足5G

1
node_filesystem_avail_bytes{mountpoint='/'}/(1024^3)

上述使用的“/”为数学运算的“除”,“^”为幂运算,同时也支持如下运算符:

  • +: 加
  • -: 减
  • *: 乘
  • /: 除
  • ^: 幂运算
  • %: 求余

查询 k8s-master01 根区分磁盘可用率(剩余空间/总空间=可用率),可以通过如下指令进行计算:

1
2
node_filesystem_avail_bytes{mountpoint='/',instance='k8s-master01'}/node_filesystem_size_bytes{mountpoint='/',instance='k8s-master01'}
#通过下图可以看到可用率大概22%左右


在宿主机上执行df -h 可以看到 Use%使用率78%,所有可用率22%,上面计算的准确

查询所有主机根分区的可用率:

1
node_filesystem_avail_bytes{mountpoint='/'}/node_filesystem_size_bytes{mountpoint='/'}

也可以将结果乘以 100 直接得到百分比:

1
(node_filesystem_avail_bytes{mountpoint='/'}/node_filesystem_size_bytes{mountpoint='/'})*100

找到集群中根分区空间可用率小于25%的主机:

1
(node_filesystem_avail_bytes{mountpoint='/'}/node_filesystem_size_bytes{mountpoint='/'})*100 <25

PromQL也支持如下判断:

  • ==: (相等)
  • != :(不相等)
  • >:(大于)
  • < :(小于)
  • >= :(大于等于)
  • <= :(小于等于)

磁盘可用率大于 25%小于等于 60%的主机:

1
25 < ((node_filesystem_avail_bytes{mountpoint='/'}/node_filesystem_size_bytes{mountpoint='/'})*100)<=50

也可以用 and 进行联合查询:(磁盘可用率大于 25%小于等于 60%的主机:)

1
node_filesystem_avail_bytes{mountpoint='/'}/node_filesystem_size_bytes{mountpoint='/'}*100>25 and node_filesystem_avail_bytes{mountpoint='/'}/node_filesystem_size_bytes{mountpoint='/'}*100<=50

除了支持 and 外,也支持 orunless

  • and:并且,条件都满足
  • or:或者,满意一个条件即可
  • ubless:排除

查询主机磁盘剩余空间,并且排除掉shm和tmpfs的磁盘:

1
node_filesystem_size_bytes unless node_filesystem_size_bytes{device=~'shm|tmpfs'}

3.PromQL常用函数

使用 sum 函数统计当前监控目标所有主机根分区剩余的空间:

1
sum(node_filesystem_size_bytes{mountpoint='/'})/1024^3

也可以用同样的方式计算所有的请求总量:以grafana_http_request_duration_seconds_count指标为例

1
2
#统计请求总数
sum(grafana_http_request_duration_seconds_count)

根据 statuscode 字段进行统计请求数据:

1
sum(grafana_http_request_duration_seconds_count) by (status_code)

根据 statuscode 和 handler 两个指标进一步统计:

1
sum(grafana_http_request_duration_seconds_count) by (handler,status_source)

根据上述的结果,找到排名前五的:topk

1
topk(5,sum(grafana_http_request_duration_seconds_count) by (handler,status_source))

取最后三个数据:bottomk

1
bottomk(3,sum(grafana_http_request_duration_seconds_count) by (handler,status_source))

找出统计结果中最小的数据:

1
min(node_filesystem_avail_bytes{mountpoint="/"})

最大的数据:

1
max(node_filesystem_avail_bytes{mountpoint="/"})

平均值:

1
avg(node_filesystem_avail_bytes{mountpoint="/"})

四舍五入,向上取最接近的整数,2.79 ==》3:

1
ceil(node_filesystem_files_free{mountpoint="/"} / 1024 / 1024)

向下取整数, 2.79 ==》 2:

1
floor(node_filesystem_files_free{mountpoint="/"} / 1024 / 1024)

对结果进行正向排序:

1
sort(sum(http_request_total) by (handler, statuscode))

对结果进行逆向排序:

1
sort_desc(sum(http_request_total) by (handler, statuscode))

函数 predict_linear 可以用于预测分析和预测性告警,比如可以根据一天的数据,预测 4 个小时后,磁盘分区的空间会不会小于 0:

1
predict_linear(node_filesystem_files_free{mountpoint="/"}[1d], 4*3600) < 20

除了上述的函数,还有几个比较重要的函数,比如 increase、rate、irate。其中 increase 是计算在一段时间范围内数据的增长(只能计算 count 类型的数据),rate 和 irate 是计算增长率。比如查询某个请求在 1 小时的时间增长了多少:

1
increase(grafana_http_request_duration_seconds_count{handler="/api/datasources/uid/:uid/resources/*", method="GET"}[1h])

将 1h 增长的数量除以该时间即为增长率:(除以3600秒,即每秒增长率)

1
increase(grafana_http_request_duration_seconds_count{handler="/api/datasources/uid/:uid/resources/*", method="GET"}[1h])/3600

相对于 increase,rate 可以直接计算出某个指标在给定时间范围内的增长率,比如还是计算1h 的增长率,可以用 rate 函数进行计算:

1
rate(grafana_http_request_duration_seconds_count{handler='/api/health'}[1h] )

如果需要计算瞬间增长率,可以使用irate(irate是计算最接近当前时间的两个数据点之间的增长率,即瞬时增长率)

1
irate(grafana_http_request_duration_seconds_count{handler='/api/health'}[1h] )