参考文章:
什么是 PromQL
Prometheus 提供了一种名为 PromQL(Prometheus Query Language)的函数式查询语言,可以让用户实时选择和聚合时间序列数据。表达式的结果可以显示为图形,在 Prometheus 的表达式浏览器中查看为表格数据,也可以通过 HTTP API 由外部系统使用。PromQL Web UI 的 Graph 选项卡提供了简单的用于查询数据的入口,对于 PromQL 的编写和校验都可以在此位置。
PromQL 查询示例
如下图所示,输入 up,单后点击 Execute,就能查到监控正常的 Target:
可以通过标签选择器过滤出 job 为 node-exporter 的监控,标签选择器的语法为
up{job="node-exporter"}
:
注意此时是
up{job="node-exporter"}
属于绝对匹配,PromQL也支持如下表达式:!=
: 不等于=~
: 正则表达式匹配!~
: 正则表达式取反,即不匹配正则表达式的内容
查询 k8s-master-01 主机在最近 5 分钟可用的磁盘空间变化
1
node_filesystem_avail_bytes{instance="k8s-master-01", mountpoint="/",device="/dev/mapper/centos-root"}[5m]
目前支持的时间范围单位如下:
- s: 秒
- m: 分
- h: 时
- d: 天
- w: 周
- y: 年
查询 10 分钟之前的磁盘可用空间,只需要指定 offset 参数既可:
1
node_filesystem_avail_bytes{instance="k8s-master-01", mountpoint="/",device="/dev/mapper/centos-root"}[5m] offset 10m
如果查询指标时,不加上时间范围,查询的是瞬时向量(vector),瞬时向量调用的是 Prometheus 的
query
API,如果加上时间范围,则查询的是范围向量(matrix),范围向量调用的是 Prometheus 的query_range
API。不管是在瞬时向量表达式或者范围向量表达式中,都是以 Prometheus 当前的系统时间为基准进行查询。如果想要查询指定时间之前的数据,可以使用位移符offset
,如上示例所示。
PromQL 操作符
除了能够方便的查询和过滤时间序列以外,PromQL 还支持丰富的操作符,用户可以使用这些操作符进一步的对事件序列进行二次加工。这些操作符包括:数学运算符,逻辑运算符,布尔运算符等等。
数学运算符
PromQL 支持的所有数学运算符如下所示
+
: 加法-
: 减法*
: 乘法/
: 除法%
: 取余^
: 幂运算
操作数可以是一个常数,也可以是一个查询表达式,比如:通过 PromQL 的语法查到了主机磁盘的空间数据,查询结果如下:
1 | node_filesystem_avail_bytes{device="/dev/sdb1", instance="192.168.55.11", mountpoint="/data"} 295313203200 |
可以通过以下方式将字节转换为 GB 或者 MB:
1
node_filesystem_avail_bytes{instance="192.168.55.11",mountpoint="/data"} / 1024 / 1024 / 1024
也可以将
1024 / 1024 / 1024
改成 (1024^3)1
node_filesystem_avail_bytes{instance="192.168.55.11",mountpoint="/data"} / (1024^3)
要查询主机的根分区的可用率,可以使用以下方式进行计算
1
node_filesystem_avail_bytes{instance="192.168.55.11",mountpoint="/"} / node_filesystem_size_bytes{instance="192.168.55.11", mountpoint="/"}
查询所有主机根分区的可用率
1
node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}
也可以将结果乘以 100 得到百分比
1
(node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100
布尔运算符
通过布尔运算可以对时间序列进行过滤。目前,Prometheus支持以下布尔运算符如下:
==
: 等于!=
: 不等于>
: 大于<
: 小于>=
: 大于等于<=
: 小于等于
例如,使用以下命令找到根分区可用率大于 80% 的主机
1
(node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 > 80
磁盘可用率大于 60% 小于等于 70% 的主机:
1
60 < (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 <= 70
也可以用 and, or, unless 进行联合查询:
- and: 并且
- or: 或者
- unless: 排除
以上示例可以使用 and 联合查询实现同样的效果,如下所示:
1
(node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 > 60 and (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 < 70
- 查询主机磁盘剩余空间,并且排除掉 shm 和 tmpfs 的磁盘
1
node_filesystem_free_bytes unless node_filesystem_free_bytes{device=~"shm|tmpfs"}
- 以下查询与上面结果一致
1
node_filesystem_free_bytes{device !~ "shm|tmpfs"}
PromQL 常用函数
聚合运算符
Prometheus 支持以下内置聚合运算符,可用于聚合单个即时向量的元素,从而生成具有聚合值的更少元素的新向量
sum(求和)
sum函数非常常用,因为常常不知道查询到时间序列究竟又多少条,注意不要再误认为 sum 是求指标在某个时间段的和。
使用 sum 函数统计当前监控目标所有主机根分区剩余的空间
1
sum(node_filesystem_free_bytes{mountpoint="/"}) / 1024^3
也可以用同样的方式,计算所有请求总量
1
sum(prometheus_http_requests_total)
或者根据 code 字段进行统计请求数据
1
sum(prometheus_http_requests_total) by (code)
根据 code 和 handler 两个指标进一步统计
1
sum(prometheus_http_requests_total) by (code, handler)
topk(最大的 k 个元素)
示例: 找到排名前 5 的数据
1
topk(5, sum(prometheus_http_requests_total) by (code, handler))
bottomk(最小的 k 个元素)
示例: 取最后三个数据
1
bottomk(3, sum(prometheus_http_requests_total) by (code, handler))
min(最小值)
示例: 查询所有主机根分区可用空间的最小值
1
min(node_filesystem_avail_bytes{mountpoint="/"})
max(最大值)
示例: 查询所有主机根分区可用空间的最大值
1
max(node_filesystem_avail_bytes{mountpoint="/"})
avg(平均值)
示例: 查询所有主机根分区可用空间的平均值
1
avg(node_filesystem_avail_bytes{mountpoint="/"})
ceil(四舍五入,向上取最接近的整数,2.79 -> 3)
示例: 查询所有主机根分区的剩余容量
1
ceil(node_filesystem_free_bytes{mountpoint="/"} / 1024^3)
floor(四舍五入,向下取最接近的整数,2.79 -> 2)
示例: 查询所有主机根分区的剩余容量
1
floor(node_filesystem_free_bytes{mountpoint="/"} / 1024^3)
sort(对结果进行正向排序)
示例: 对查询出来的结果进行正向排序
1
sort(sum(prometheus_http_requests_total) by (code, handler))
sort_desc(对结果进行逆向排序)
示例: 对查询出来的结果进行逆向排序
1
sort_desc(sum(prometheus_http_requests_total) by (code, handler))
predict_linear(用于预测分析和预测性告警)
示例: 查询预测4个小时后,磁盘根分区的空间小于 0 的数据
1
predict_linear(node_filesystem_files_free{mountpoint="/"}[1d], 4*3600) < 0
increase(计算在一段时间范围内数据的增长,只能计算 count 类型的数据)
示例: 比如查询某个请求在1小时的时间增长了多少
1
increase(grafana_http_request_duration_seconds_count{handler="/api/datasources/proxy/:id/*", method="GET", namespace="monitoring",service="grafana",status_code="200"}[1h])
将1h增长的数量除以该时间即为增长率
1
increase(grafana_http_request_duration_seconds_count{handler="/api/datasources/proxy/:id/*", method="GET", namespace="monitoring",service="grafana",status_code="200"}[1h]) / 3600
rate & irate(计算增长率)
相对于 increase,rate 可以直接计算出某个指标在给定时间范围内的增长率。irate 和 rate 都会用于计算某个指标在一定时间间隔内的变化速率。但是它们的计算方法有所不同:
irate 取的是在指定时间范围内的最近两个数据点来算速率,
rate 会取指定时间范围内所有数据点,算出一组速率,然后取平均值作为结果
示例: 比如还是计算1h的增长率,可以用 rate 函数进行计算:
1
rate(grafana_http_request_duration_seconds_count{handler="/api/datasources/proxy/:id/*", method="GET", namespace="monitoring",service="grafana",status_code="200"}[1h])
以上函数式最常用的几个函数,更多的函数请查看官方文档。