5-PromQL

prometheus

PromQL

从之前中3-Prometheus数据学习了Prometheus的四种数据类型。
PromQL中使用 # 进行注释

基础内容

瞬时向量(Instant vector): 一组时间序列,每个时间序列包含一个样本,都共享相同的时间戳
范围向量(Range vector): 一组时间序列,其中包含每个时间序列随时间变化的数据点范围,即 node_cpu_seconds_total[5m]此类查询 ,在 Prometheus页面查询无法使用此类查询展现图表,必须是即时向量或者标量
标量(Scalar ): 一个简单的数字浮点值

标签选择器

node_cpu_seconds_total{mode!="idle"},其中mode为node_cpu_seconds_total指标的一个标签,可以通过标签选择器进行过滤。
= :与字符串匹配
!= :与字符串不匹配
=~ :与正则匹配,匹配为全锚定。=~"foo"相当于=~"^foo$".
!~ :与正则不匹配

时间范围选择器

时间范围有以下单位:
ms- 毫秒
s- 秒
m- 分钟
h- 小时
d- 天
w- 周
y- 年
使用方式node_cpu_seconds_total[5m]

偏移修饰符

更改查询即时向量范围向量的时间偏移量
node_cpu_seconds_total offset 5m :表示5分钟前的值
node_cpu_guest_seconds_total[5m] offset 1d表示一天前5分钟的值

@修饰符

通过@ 直接跳转到某个uinx时间戳,
node_cpu_guest_seconds_total @ 1667137698:查询指标时间戳为1667137698,即时间为2022-10-30 21:48:18的值
node_cpu_guest_seconds_total[5m] @ 1667137698:查询2022-10-30 21:48:18前5分钟的值

运算

运算符

+ (加法)
- (减法)
* (乘法)
/ (除法)
% (取模)
^ (幂)
使用运算符的结果与原指标的意义不再一样,输出的结果没有指标名称,只包含标签、值。
实际运算中不同的指标的标签名以及标签数量不一致,运算时有以下运算原则。

  1. 运算时按照标签相同的值进行运算,例如: node_cpu_seconds_total + node_cpu_seconds_total ,标签全部相同的值相加
  2. 两个瞬时向量的数量不同,结果数量与数量少的一致,node_cpu_guest_seconds_total + node_cpu_seconds_total,结果为 mode=”nice”、mode=”user”的两个向量相加

逻辑比较

== :相等判断,相等为1(true),不相等为0(false)
!= :判断是否不相等,输出结果类似==
>= :输出结果类似==
<= :输出结果类似==
> :输出结果类似==
< :输出结果类似==

逻辑运算

and :对多个指标的数据集进行标签判断,获取两个指标集具有共同的标签的值 (优先展示or左边的指标)
or :对多个指标集数据进行展示,如果有标签重复,则仅显示其中一个标签的值 (优先展示or左边的指标)
unless :对多个指标的数据集进行标签判断,获取两个指标集不具有共同的标签的值 (优先展示or左边的指标)

向量匹配

1
2
3
4
5
6
7
8
9
test1{method="get", code="500"}  24
test1{method="get", code="404"} 30
test1{method="put", code="501"} 3
test1{method="post", code="500"} 6
test1{method="post", code="404"} 21

test2{method="get"} 600
test2{method="del"} 34
test2{method="post"} 120

两个指标test1与test2的标签以及数量不一致们可以使用ignoring忽略不共有的标签。

1
2
3
4
5
6
7
test1{ code="500"} / ignoring(code) test2   # 
# test1{ code="500"} 可以过滤出以下两条
# test1{method="get", code="500"} 24
# test1{method="post", code="500"} 6
# 然后 ignoring(code) 将过滤出的两条的code标签忽略,进行运算
{method="get"} 0.04 # 24 / 600
{method="post"} 0.05 # 6 / 120

在以上的例子中test1{ code="500"} / ignoring(code) test2等同于test1{ code="500"} / on(method) test2,on 与 ignoring相反,意思为只考虑提供的列表中的标签。ignoring与on 结果的数目都与左边的指标数量相同,可以使用group_right以右边数量为准

1
2
3
4
5
6
test1/ ignoring(code) group_left test2

{method="get", code="500"} 0.04 // 24 / 600
{method="get", code="404"} 0.05 // 30 / 600
{method="post", code="500"} 0.05 // 6 / 120
{method="post", code="404"} 0.175 // 21 / 120

函数

聚合函数

聚合函数可以与 withoutby 一起使用
without:表示计算结果中移除列举的标签
by:表示计算结果中只保留列出的标签
通过without和by可以按照样本的问题对数据进⾏聚合

sum()

求和函数,可以使用without、by根据标签进行聚合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sum by(handler) (prometheus_http_requests_total)

{handler="/-/ready"} 3
{handler="/api/v1/label/:name/values"} 4
{handler="/api/v1/labels"} 3
{handler="/api/v1/metadata"} 27
{handler="/api/v1/query"} 123
{handler="/api/v1/query_range"} 8
{handler="/api/v1/rules"} 1
{handler="/api/v1/series"} 3
{handler="/api/v1/status/config"} 1
{handler="/api/v1/targets"} 1
{handler="/favicon.ico"} 2
{handler="/graph"} 3
{handler="/metrics"} 403
{handler="/static/*filepath"} 11
{handler="/"} 1

avg()

所有值的平均值

1
2
avg(prometheus_http_requests_total)
{} 43.06249999999999

count()

返回分组中的时间序列数

1
2
3
4
5
6
7
count(prometheus_http_requests_total)
{} 16

count by (code) (prometheus_http_requests_total)
{code="200"} 14
{code="302"} 1
{code="400"} 1

count_values()

计算具有相同值的元素个数

1
2
3
4
5
6
7
8
9
10
11
12
count_values ("handler",prometheus_http_requests_total)
{handler="3"} 2 #这表示值为3的有2条
{handler="4"} 1
{handler="8"} 2
{handler="47"} 1
{handler="153"} 1
{handler="1"} 4
{handler="5"} 1
{handler="2"} 1
{handler="553"} 1
{handler="11"} 1
{handler="14"} 1

min()、max()

组内最小值、最大值

1
2
3
4
5
max by (instance,job)(prometheus_http_requests_total)
{instance="localhost:9090", job="prometheus"} 575

min by (instance,job)(prometheus_http_requests_total)
{instance="localhost:9090", job="prometheus"} 1

stddev()、stdvar()

stddev():标准差
stdvar():方差
方差与标准差可以反应数据集离散程度,例如:{2,4,6}与{3,4,5}的平均值都是4,但是两组数据的方差与标准差确不一样。
以以上两组数据计算方差:
{2,4,6}: ((2-4)^2+(4-4)^2+(6-4)^2)/3=(4+0+4)/3=2.666
{3,4,5}: ((3-4)^2+(4-4)^2+(5-4)^2)/3=(1+0+1)/3= 0.666
标准差计算方式就是将方差开根号
{2,4,6}标准差:1.632
{3,4,5}标准差:0.816

topk()、bottomk()

topk():最大的K个元素
bottomk():最小的K个元素

1
2
3
4
5
6
7
topk (2,node_cpu_seconds_total)
node_cpu_seconds_total{cpu="0", instance="192.168.27.7:9100", job="node", mode="idle"} 331997.49
node_cpu_seconds_total{cpu="0", instance="192.168.27.7:9100", job="node", mode="user"} 3076.4

bottomk (2,node_cpu_seconds_total)
node_cpu_seconds_total{cpu="0", instance="192.168.27.7:9100", job="node", mode="irq"} 0
node_cpu_seconds_total{cpu="0", instance="192.168.27.7:9100", job="node", mode="steal"} 0

quantile()

计算指定分位数

1
2
quantile (0.5,node_cpu_seconds_total)  #计算中位数,即二分位数
{} 34.685

类型函数

vector()

vector( scalar )函数,参数为一个scalar数值,作为一个没有标签的向量返回

1
2
vector(100)
{} 100

scalar()

scalar(instant-vector),参数为一个单元素瞬时向量,返回其唯一的时间序列值作为一个标量
如果元素不为1(大于1或者为0),则返回NaN

1
2
scalar(vector(100))
scalar 100

数学函数

abs()

abs(instant-vector),返回输入向量的所有值的绝对值

1
2
abs(vector(-100))
{} 100

In()

In(instant-vector),返回输入向量的所有值的自然对数(即以自然常数e为底数的对数)

log2()

log2(instant-vector),返回输入向量的所有值的以2为底数的对数

log10()

log10(instant-vector),返回输入向量的所有值的以10为底数的对数

exp()

exp(instant-vector),返回输入向量的所有值的e的指数值

sqrt()

sqrt(instant-vector),返回输入向量的所有的值的平方根

ceil()

ceil(instant-vector),将输入向量所有值向上取整

1
2
ceil(vector(2.232323))
{} 2

floor()

与ceil()函数相反,floor()函数为向下取整

round()

round(instant-vector),将输入向量所有值四舍五入至整数

clamp()

clamp(instant-vector,min,max),将输入向量所有值限制在min-max之间,小于min的修改为min,大于max的修改为max

1
2
3
4
5
6
7
8
9
10
clamp(node_cpu_seconds_total,1,100)

{cpu="0", instance="192.168.27.7:9100", job="node", mode="idle"} 100
{cpu="0", instance="192.168.27.7:9100", job="node", mode="iowait"} 24.13
{cpu="0", instance="192.168.27.7:9100", job="node", mode="irq"} 1
{cpu="0", instance="192.168.27.7:9100", job="node", mode="nice"} 4
{cpu="0", instance="192.168.27.7:9100", job="node", mode="softirq"} 45.67
{cpu="0", instance="192.168.27.7:9100", job="node", mode="steal"} 1
{cpu="0", instance="192.168.27.7:9100", job="node", mode="system"} 100
{cpu="0", instance="192.168.27.7:9100", job="node", mode="user"} 100

clamp_mix()、clamp_max()

clamp_min(instant-vector,min)、clamp_max(instant-vector,max),限制输入向量的最小值、最大值

时间函数

time()

time()函数,返回当前时间的时间戳

1
2
time()
scalar 1668010014.605

minute()

mintue(instant-vector),参数为一个瞬时向量的时间戳,返回给定时间戳的分钟(0-59)

1
2
minute(vector(time()))
{} 10

hour()

hour(instant-vector),参数为一个瞬时向量的时间戳,返回给定时间戳的小时(0-23)

month()

month(instant-vector),参数为一个瞬时向量的时间戳,返回给定时间戳的月份(1-12)

year()

year(instant-vector),参数为一个瞬时向量的时间戳,返回给定时间戳的年份

day_of_month()

day_of_month(instant-vector),参数为一个瞬时向量的时间戳,返回给定时间戳所在月份的第几天

day_of_week()

day_of_week(instant-vector),参数为一个瞬时向量的时间戳,返回给定时间戳所在星期的第几天

day_of_year()

day_of_year(instant-vector),参数为一个瞬时向量的时间戳,返回给定时间戳所在年份的第几天

days_in_month()

days_in_month(instant-vector),参数为一个瞬时向量的时间戳,返回给定时间戳所在月份一共有几天

timestamp()

查看样本的时间戳

1
2
3
4
5
6
7
8
9
10
timestamp(node_cpu_seconds_total)

{cpu="0", instance="192.168.27.7:9100", job="node", mode="idle"} 1668010938.442
{cpu="0", instance="192.168.27.7:9100", job="node", mode="iowait"} 1668010938.442
{cpu="0", instance="192.168.27.7:9100", job="node", mode="irq"} 1668010938.442
{cpu="0", instance="192.168.27.7:9100", job="node", mode="nice"} 1668010938.442
{cpu="0", instance="192.168.27.7:9100", job="node", mode="softirq"} 1668010938.442
{cpu="0", instance="192.168.27.7:9100", job="node", mode="steal"} 1668010938.442
{cpu="0", instance="192.168.27.7:9100", job="node", mode="system"} 1668010938.442
{cpu="0", instance="192.168.27.7:9100", job="node", mode="user"} 1668010938.442

缺失与排序函数

absent()

absent(instant-vector),当给定向量为空时返回1,有样本数据则返回空

1
2
3
4
5
absent(up)
Empty query result

absent(up_not_existent)
{} 1

sort()

sort(instant-vector),按照值进行排序,从上到下依次变大。

sort_desc()

sort_desc(instant-vector),按照值进行排序,从上到下依次变小。

计数器

rate()

rate(range-vector),计算计数器区间向量平均增长速率。rate会取指定时间范围内所有数据点,算出一组速率,然后取平均值作为结果。rate适合缓慢变化的计数器(counter)。

irate()

rate(range-vector),计算计数器区间向量平均增长速率。irate取的是在指定时间范围内的最近两个数据点来算速率。irate适合快速变化的计数器(counter)。

gauge类型处理函数

changes()

changes(range-vector),返回区间内每个样本数据值的变化次数

delta()

delta(range-vector),返回区间中每个元素第一个值与最后一个值的差

idelta()

idelta(range-vector),返回区间中最新的两个值的差