PromQL 是 Prometheus 内置的数据查询语言,本文为您介绍 PromQL 的基本使用方法。
Prometheus 通过指标名(metrics name)以及对应的一组标签(labels)唯一定义一条时间序列。指标名反映了监控样本的基本标识,而 labels 则在这个基本特征上为采集到的数据提供了多种特征维度。用户可以基于这些特征维度过滤,聚合,统计从而产生新的计算后的一条时间序列。
PromQL 是 Prometheus 内置的数据查询语言,其提供对时间序列数据丰富的查询,聚合以及逻辑运算能力的支持。并且被广泛应用在 Prometheus 的日常应用当中,包括对数据查询、可视化、告警处理当中。
所有的 PromQL 表达式都必须至少包含一个指标名称(例如:http_request_total),或者一个不会匹配到空字符串的标签过滤器(例如:{code="200"})。
由于 metric name 可以看做一个 key 为 __name__
的标签, 因此,也可以简单的理解为 合格的 PromQL 表达式其过滤条件不能为空。
举例如下:
node_filesystem_free_bytes # Good! {__name__="node_filesystem_free_bytes"} # Good! node_filesystem_free_bytes{mountpoint="/data00"} #Good! {mountpoint="/data00"} # Good {mountpoint=".*"} # Bad! {job=~".+"} # Good! {job=~".*",method="get"} # Good! {job=~".*"} # Bad!
下面是一些注意事项:
bool
、on
、ignoring
和group_left 与 group_right
,如果上报上来的指标名 是上面关键字之一, 需要通过 __name__
的方式代替。on{} # Bad! {__name__="on"} # Good!
node_filesystem_free_bytes{mountpoint="/data00", instance="10.182.16.127:9100"} node_filesystem_free_bytes{instance!="10.182.16.127:9100"} node_filesystem_free_bytes{mountpoint=~"/data00|/data01"} node_filesystem_free_bytes{mountpoint!~"/data00|/data01"}
说明
在 PromQL 中 ,标签过滤器的 key 是可以重复配置的, promQL 最终会解析为 and 的关系,例如: node_filesystem_free_bytes{mountpoint!="/data00", mountpoint!="/data01"}
,其等同于node_filesystem_free_bytes{mountpoint!~"/data00|/data01"}
这个 PromQL 查询的结果将是空值:node_filesystem_free_bytes{mountpoint="/data00", mountpoint="/data02"}
PromQL 支持使用 = 和 != 两种完全匹配模式。
label=value
可以选择那些标签满足表达式定义的时间序列。label!=value
则可以根据标签匹配排除时间序列。例如:我们需要过滤掉所有 code 标签不是 200 的数据。那么 PromQL 表达式可以修改为:http_requests_total{code!=“200”}
。
PromQL 还可以使用正则表达式作为匹配条件,并且可以使用多个匹配条件。
label=~regx
表示选择那些标签符合正则表达式定义的时间序列。label!~regx
表示不选择那些标签符合正则表达式定义的时间序列。例如想查询指标 http_requests_total
中,所有 handler 标签以 /api/v1 开头的记录,那么表达式为:http_requests_total{handler=~"/api/v1/.*"}
。
当直接通过类似 http_requests_total
的 PromQL 表达式查询时间序列时,同一个指标同一标签只会返回一条数据。这样的表达式我们称之为 瞬间向量表达式,而返回的结果称之为 瞬间向量。
而如果我们想查询一段时间范围内的样本数据,那么我们就需要用到 区间向量表达式,其查询出来的结果称之为 区间向量。时间范围通过时间范围选择器 [] 进行定义。例如,通过以下表达式可以选择最近5分钟内的所有样本数据。
http_requests_total[5m]
时间范围选择器中,除了使用 m 表示分钟以外,还支持以下时间单位。
时间单位 | 说明 |
---|---|
s | 秒 |
m | 分钟 |
h | 小时 |
d | 天 |
w | 周 |
y | 年 |
在瞬时向量表达式或者区间向量表达式中,默认都是以 当前时间 为基准,而如果用户想查询 5 分钟前的瞬时样本数据,或昨天一天的区间内的样本数据呢? 这个时候就可以使用 时间位移 操作,时间位移 操作的关键字为 offset。
示例如下:
# 查询当前时间向量 node_filesystem_free_bytes{mountpoint="/data00"} node_filesystem_free_bytes{mountpoint="/data00"}[1h] # 查询的时间范围分别前移 5分钟 node_filesystem_free_bytes{mountpoint="/data00"} offset 5m node_filesystem_free_bytes{mountpoint="/data00"}[1h] offset 5m
结合上述示例,我们可以比较容易想到 offset 的一种典型实用场景,即比对不同时刻的向量。举例如下:
# 查询节点 /data00 挂载点, 5 分钟的变化量 node_filesystem_free_bytes{mountpoint="/data00"} offset 5m - node_filesystem_free_bytes{mountpoint="/data00"}
在某些特殊的场景中, 希望 PromQL 查询语句不再是以当前时间为基准,而是一个指定的时间,这个时候就需要用到 @
符号,@
后面是 一个 unix 标准时间戳。
示例如下,时间戳为:1660404944 = "2022-08-13 23:35:44"
node_filesystem_free_bytes{mountpoint="/data00"} @ 1660404944 node_filesystem_free_bytes{mountpoint="/data00"} @ 1660404944 offset 5m
一般情况下,我们通过 PromQL 查询到的数据都是很多的。PromQL 提供的聚合操作可以用来对这些时间序列进行处理,形成一条新的时间序列。
常用的聚合操作包括:count(计数)和 sum(相加)。例如:
count(http_requests_total)
。sum(http_requests_total)
。说明
聚合操作的详情,请参见 PromQL 聚合操作。