title: 4.1.PromQL 基础使用
order: 24
icon: lightbulb
PromQL (Prometheus Query Language) 是 Prometheus 自己开发的数据查询 DSL 语言,语言表现力非常丰富,内置函数很多,在日常数据可视化(Grafana)以及rule 告警中都会使用到它。
1、PromQL数据类型
在Prometheus的表达式语言中,PromQL数据类型归类为以下四种:
瞬时向量(instant vector),是指同一时刻的一组时间序列,每个时间序列包含一个样本,所有样本共享相同的时间戳,即每个时序只有一个点。
区间向量(range vector),是指在任何一个时间范围内的一组时间序列,包含每个时间序列随时间变化的一系列数据点,这时每个时序有多个点。
标量(scalar),即纯量数据,一个简单的数字浮点值,只有一个数字,没有时序。
字符串(string),一个目前未被使用的简单字符串值。
瞬时向量(Instant vector)
我们在Prometheus的查询页面输入指标 node_memory_Active_bytes
进行查询。
返回如下的结果:
区间向量(Range vector)
我们在Prometheus的查询页面输入一个查询语句 node_memory_Active_bytes[1m]
进行查询。
返回如下的结果:
以上的查询语句是查询 最近一分钟数据,因为采集的周期是 15s 所以[1m]每一个时序会有4个数据。
区间向量(Range vector)类型数据是指时序有一个时间区间的数据,这种类型的数据成为区间向量(Range vector)。
标量(Scalar)
标量只有一个数字,没有时序。
例如:
1024
需要注意的是,当使用表达式count(http_requests_total),返回的数据类型,依然是瞬时向量。用户可以通过内置函数scalar()将单个瞬时向量转换为标量。
字符串(String)
直接使用字符串,作为PromQL表达式,则会直接返回字符串。(目前未被使用)
"this is a string"
'these are unescaped:
\ '
`these are not unescaped:
' " `
2、时间序列过滤器
瞬时向量过滤器
瞬时向量过滤器允许在指定的时间戳内选择一组时间序列和每个时间序列的单个样本值。在最简单的形式中,近指定指标(metric)名称。这将生成包含此指标名称的所有时间序列的元素的瞬时向量。
例如:选择指标名称为 node_cpu_seconds_total
的所有时间序列:
node_cpu_seconds_total
可以通过向花括号{}
里附加一组标签来进一步过滤时间序列。
例如:选择指标名称为 node_cpu_seconds_total
,instance
标签值为 Prometheus服务器
,mode
标签值为 idle
的时间序列:
node_cpu_seconds_total{ instance="Prometheus服务器", mode="idle"}
PromQL 还支持用户根据时间序列的标签匹配模式来对时间序列进行过滤,目前主要支持两种匹配模式:完全匹配和正则匹配。总共有以下几种标签匹配运算符:
=
: 选择与提供的字符串完全相同的标签。!=
: 选择与提供的字符串不相同的标签。=~
: 选择正则表达式与提供的字符串(或子字符串)相匹配的标签。!~
: 选择正则表达式与提供的字符串(或子字符串)不匹配的标签。
例如:选择指标名称为 node_cpu_seconds_total
,mode为 idle
、user
或 system
,cpu!=0
的时间序列:
node_cpu_seconds_total{mode=~"idle|user|system",cpu!="0"}
没有指定标签的标签过滤器会选择该指标名称的所有时间序列。
Prometheus 中的所有正则表达式都使用 RE2语法。
所有的 PromQL 表达式必须至少包含一个指标名称,或者一个不会匹配到空字符串的标签过滤器。
除了使用 <metric name>{label=value}
的形式以外,我们还可以使用内置的 __name__
标签来指定监控指标名称。例如:表达式 node_cpu_seconds_total
等效于 {__name__="node_cpu_seconds_total"}
区间向量过滤器
区间向量与瞬时向量的工作方式类似,唯一的差异在于在区间向量表达式中我们需要定义时间选择的范围,时间范围通过时间范围选择器 []
进行定义,以指定应为每个返回的区间向量样本值中提取多长的时间范围。
时间范围通过数字来表示,单位可以使用以下其中之一的时间单位:
s
- 秒m
- 分钟h
- 小时d
- 天w
- 周y
- 年
例如:选择在过去 5 分钟内指标名称为 node_cpu_seconds_total
,job
标签值为 prometheus
的所有时间序列:
node_cpu_seconds_total{ instance="Prometheus服务器", mode="idle"}[1m]
时间位移操作
在瞬时向量表达式或者区间向量表达式中,都是以当前时间为基准:
node_cpu_seconds_total{} # 瞬时向量表达式,选择当前最新的数据
node_cpu_seconds_total{}[5m] # 区间向量表达式,选择以当前时间为基准,5分钟内的数据
而如果我们想查询,5 分钟前的瞬时样本数据,或昨天一天的区间内的样本数据呢? 这个时候我们就可以使用位移操作,位移操作的关键字为 offset
。
例如,以下表达式返回相对于当前查询时间过去 5 分钟的 node_cpu_seconds_total
值:
node_cpu_seconds_total{ instance="Prometheus服务器", mode="idle"} offset 5m
注意:offset
关键字需要紧跟在选择器{}
后面。以下表达式是正确的:
sum(node_cpu_seconds_total{ instance="Prometheus服务器", mode="idle"} offset 5m)
下面的表达式是不合法的:
sum(node_cpu_seconds_total{ instance="Prometheus服务器", mode="idle"}) offset 5m
该操作同样适用于区间向量。以下表达式返回指标 node_cpu_seconds_total
一周前的 5 分钟之内的 cpu 空闲率:
rate(node_cpu_seconds_total{ instance="Prometheus服务器", mode="idle"}[5m] offset 1w)
sum是聚合运算符,rate是内置函数,后面会讲
评论区