K&

数据类型

匹配器

时间单位

算术二元运算符

比较二元运算符

逻辑二元运算符

向量匹配

偏移

API访问

聚合运算符

二元运算符优先级

类型函数

数学函数

时间函数

标签

计数器

改变gauge值

随时间聚合

 

 

Prometheus 提供了一种称为 PromQL(Prometheus Query Language)的函数式查询语言,可以让用户实时选择和聚合时间序列数据。表达式的结果既可以显示为图形,也可以在 Prometheus 的表达式浏览器中查看为表格数据,也可以通过HTTP API由外部系统使用。

 

标签在PromQL很重要那标签是什么

 

类似与下图红框部分

 

 

 

表达式语言数据类型

 

在 Prometheus 的表达式语言中,表达式或子表达式可以计算为以下四种类型之一:

  • 即时向量/瞬时向量- 一组时间序列,每个时间序列包含一个样本,所有时间序列都共享相同的时间戳,为采集指标数据最新的或者说距离上一个采集时间最近的,很抽象那就来个例子

 

 

  • 范围向量- 一组时间序列,包含每个时间序列随时间变化的数据点范围,很抽象那就来个例子

 

 

 

  • 标量- 一个简单的数字浮点值(整数其实也好使),很抽象那就来个例子

 

 

  • String - 一个简单的字符串值,很抽象那就来个例子;目前未使用

 

 

根用户输入的表达式返回的数据类型是否合法取决于用例的不同,例如:瞬时向量表达式返回的数据类型是唯一可以直接绘制成图表的数据类型。

 

PromQL所谓的匹配器有四种:

 

=返回的序列中有没有job=node或者job=""这种可以理解为值精确匹配,示例如下

 

node_cpu_seconds_total{mode="idle"}

 

 

!=是否定的等式就是不等于,示例如下

 

node_cpu_seconds_total{mode!="irq",mode!="iowait",mode!="nice",mode!="softirq",mode!="steal",mode!="system",mode!="user"}

 

 

=~正则匹配,可以理解为模糊匹配,示例如下

 

node_cpu_seconds_total{instance=~"ecs.*"}

 

 

!~反向正则模糊匹配,示例如下

 

node_filesystem_size_bytes{instance=~"ecs.*",mountpoint!~"/run.*",mountpoint!~"/pv.*"}

 

 

PromQL中常用的时间单位

 

ms  毫秒

s  秒,1000ms

m  分钟,60s

h  小时,60m

d  天,24h

w  周,7d

y  年,365d,52w

 

算术二元运算符

 

查询语言支持基本的逻辑运算和算术运算。对于两个瞬时向量, 匹配行为可以被改变。

 

在 Prometheus 系统中支持下面的二元算术运算符:

 

  • + 加法

  • - 减法

  • * 乘法

  • / 除法

  • %

  • ^ 幂等

 

二元运算操作符支持 scalar/scalar(标量/标量)vector/scalar(向量/标量)vector/vector(向量/向量) 之间的操作。

在两个标量之间运算,行为很明显:它们计算另一个标量,该标量是应用于两个标量操作数的运算符的结果。得到的结果也是标量

 

2/2

 

 

向量和标量之间,这个运算符会用于向量中的每个样本值。例如,如果一个时间序列瞬时向量除以 2,操作结果也是一个新的瞬时向量,原度量瞬时向量的每个样本值除以 2,并删除度量名称(因为样本值变了,成了一个新的度量)

 

etcd_db_total_size_in_bytes / (1024 ^ 3)

 

如果在两个瞬时向量之间作用于左侧向量中的每个条目及其右侧向量中的样本值 。结果传播到结果向量中,分组标签成为输出标签集(by中的标签或者是去掉without选中的标签)。指标名称被删除。在右侧向量中找不到匹配条目的条目不输出(匹配条件是两侧向量中的标签要完全一直那么可以计算)

 

sum(kubelet_docker_operations_duration_seconds_sum / kubelet_docker_operations_duration_seconds_count) by (node)

 

 

 

比较二元运算符

 

存在以下二元比较运算符:

 

  • == (平等的)
  • != (不相等)
  • > (比...更棒)
  • < (少于)
  • >= (大于或等于)
  • <= (小于或等于)

 

比较运算符在标量/标量、向量/标量和向量/向量值对之间定义。默认情况下,它们会过滤(根据时间序列样本值对时间序列过滤)。它们的行为,可以在运算符之后通过bool修饰符的布尔运算修改默认行为,该运算将返回01的值而不是过滤。

 

过滤示例:

 

kubelet_docker_operations_duration_seconds_sum == 12.818770544999998

 

 

修改默认行为示例:

 

kubelet_docker_operations_duration_seconds_sum == bool 12.818770544999998

 

 

在两个标量之间,bool必须提供修饰符(不提供会报错),这些运算符会产生另一个标量,即0false) 或1 ( true),具体取决于比较结果。

 

示例:2 > bool 1

 

 

 

在瞬时向量和标量之间,这些运算符应用于向量中每个数据样本的值,并且从结果向量中删除其间比较结果为false的向量元素或者说是时序序列(就是过滤原则没有加bool值)。如果提供了bool修饰符则将被删除的时序序列的值改为0,而将保留的时序序列的值改为1。如果提供了bool修饰符,则指标名称将被删除

 

示例:

 

kubelet_docker_operations_duration_seconds_sum == bool 12.818770544999998

 

 

两个瞬时向量之间,这些运算符默认充当过滤器(就是没有bool修饰符)应用于匹配条目(相同规则标签一致算匹配)表达式不为真或在表达式的另一侧找不到匹配项的向量元素从结果中删除,而其他元素则传播到结果向量中,分组标签成为输出标签集。如果bool提供了修饰符,则将被删除的时序序列value的值0,并且将保留的时序序列的value改为1,分组标签再次成为输出标签集。如果bool提供了修饰符,则指标名称将被删除

 

示例:

 

kubelet_docker_operations_duration_seconds_sum == kubelet_docker_operations_duration_seconds_sum{node="ecs2"}

 

示例:

 

kubelet_docker_operations_duration_seconds_sum == bool kubelet_docker_operations_duration_seconds_sum{node="ecs2"}

 

 

 

逻辑/设置二元运算符

 

唯一一个处理多对多运算符

 

使用瞬时向量表达式能够获取到一个包含多个时间序列的集合,我们称为瞬时向量。通过集合运算,可以在两个瞬时向量与瞬时向量之间进行相应的集合操作。支持以下集合运算符:

 

这些逻辑/集合二元运算符仅在即时向量之间定义:

 

 

  • and (交集)

  • or (并集)

  • unless (交集取反)

 

 

 

vector1 and vector2产生一个向量,该向量由具有完全匹配标签集的vector1元素组成vector2。其他元素被丢弃。度量名称和值从左侧向量结转。

 

and示例:

 

kubelet_docker_operations_duration_seconds_sum and kubelet_docker_operations_duration_seconds_sum{node="ecs3"}

 

 

 

vector1 or vector2产生一个向量,其中包含所有的原始元素(标签集 + 值)vector1以及所有在vector2 中没有匹配标签集的元素vector1。有一个细节,当右侧为空,那么返回左侧的值。

 

or示例:

 

kubelet_docker_operations_duration_seconds_sum or kubelet_docker_operations_duration_seconds_sum{node="ecs3"}

 

就是左侧的瞬时向量的查询结果

 

 

vector1 unless vector2产生一个向量,该向量由 vector1没有vector2完全匹配标签集的元素组成。两个向量中的所有匹配元素都被删除。读者懵逼的,实际就是vector1-vector2的值

 

unless示例:

 

kubelet_docker_operations_duration_seconds_sum unless kubelet_docker_operations_duration_seconds_sum{node="ecs2"}

 

 

向量匹配

 

向量之间的操作尝试默认策略为左侧的每个条目在右侧向量中依次找到(标签完全一致)匹配元素,如果没找到匹配元素,则直接丢弃

 

匹配行为有两种基本类型:一对一和多对一/一对多。

 

一对一向量匹配

 

一对一,从操作的每一侧找到一对唯一的条目(衡量标准还是标签)。在默认情况下,这是一个遵循格式的操作

 

vector1 <operator> vector2

 

先来个有问题的示例:

 

node_cpu_seconds_total{mode="idle"} / node_cpu_seconds_total{mode="irq"}

 

 

再来个无问题的示例:

 

node_cpu_seconds_total{mode="idle"} / node_cpu_seconds_total或node_cpu_seconds_total / node_cpu_seconds_total{mode="idle"}

标签在那侧无所谓,只有标签一致就可以匹配出来类似于过滤

 

 

 

如果两个条目具有完全相同的一组标签和相应的值,则它们匹配ignoring(label list)的关键字允许忽略匹配时某些标签,而 on(label list)关键字是将匹配的标签限定为提供的值:

 

<vector expr> <bin-op> ignoring(<label list>) <vector expr>
<vector expr> <bin-op> on(<label list>) <vector expr>

 

先说为什么用on或者ignoring

 

如果我把上面正确示例变更一下,变成(node_cpu_seconds_total{mode="idle"}) / sum without(mode)(node_cpu_seconds_total)输出会返回空。

为什么?

 

原因:因为前半段返回的输出中含有mode标签,而右侧输出却因为使用了without把mode标签删除掉了。而向量匹配是从左到右根据标签依次核对,右侧标签与左侧一致,那么就可以匹配到,但是反之那么就不行了。还有一个隐藏的意思,返回的是以右侧ignoring或or筛选后的标签为准。

 

说着可能不懂,那么还用例子辅助一下

 

(node_cpu_seconds_total{mode="idle"}) /  ignoring(mode) sum without(mode)(node_cpu_seconds_total)或

(node_cpu_seconds_total{mode="idle"}) /  on(container,job,service,cpu,endpoint,instance,cpu,namespace) sum without(mode)(node_cpu_seconds_total)

 

1、ignoring作用就是忽略mode,让其满足右含左标签规则。

2、标签以右侧标签为条件,因为左侧有mode,而右侧与输出均没有mode标签。

3、经过测试还有很细节的一点。当两侧标签一致满足匹配需求的时候,只要能保证时序数据唯一(一对一),那么用ignoring或on的都可以,只不过一个是忽略另一个是保留,而标签的输出就是根据ignoring或on筛选后的为准

 

我们把从无值变化的标签逐一删除

 

下面是示例:

 

(node_cpu_seconds_total{mode="idle"}) /  on(container,job,service,cpu,endpoint,instance,namespace) sum without(mode)(node_cpu_seconds_total)

(node_cpu_seconds_total{mode="idle"}) /  on(container,job,cpu,endpoint,instance,namespace) sum without(mode)(node_cpu_seconds_total)

(node_cpu_seconds_total{mode="idle"}) /  on(container,job,cpu,endpoint,instance) sum without(mode)(node_cpu_seconds_total)

(node_cpu_seconds_total{mode="idle"}) /  on(container,job,cpu,instance) sum without(mode)(node_cpu_seconds_total)

(node_cpu_seconds_total{mode="idle"}) /  on(container,cpu,instance) sum without(mode)(node_cpu_seconds_total)

(node_cpu_seconds_total{mode="idle"}) /  on(cpu,instance) sum without(mode)(node_cpu_seconds_total)

 

以上都正常执行没问题

 

下面继续删除,但是,是值有变化的了

 

示例如下:

 

(node_cpu_seconds_total{mode="idle"}) /  on(instance) sum without(mode)(node_cpu_seconds_total)

 

直接报错

很清晰直接告诉了原因,时序不再是一对一了

 

以上就是一对一部分

 

多对一和一对多向量匹配

 

多对一和一对多匹配是指“一”端的每个向量元素可以与多侧的多个向量元素匹配的情况。这必须使用group_leftorgroup_right修饰符明确请求,其中左/右确定哪个向量具有更高的基数(就是那侧标签更多)。

 

左侧多用left右侧多用right

 

多对一与一对多两种模式一定出现在两侧表达式标签不一致的情况下,而不一致就需要用ignoring或者on来排除或者限定一下匹配的标签列表

 

左侧标签多示例:

node_cpu_seconds_total{mode="idle"} / on(container,job,service,cpu,endpoint,instance,namespace,pod) group_left sum without(mode) (node_cpu_seconds_total)

 

 

 

右侧标签多示例:

 

sum without(pod)(node_cpu_seconds_total{mode="idle"}) / on(container,job,service,cpu,endpoint,instance,namespace,mode) group_right node_cpu_seconds_total

 

 

与组修饰符一起提供的标签列表(group_left<label> or group_right<label>),被加入到结果指标中“一”的那侧,成为附加标签。因为on一个标签只能出现在其中一个列表中。结果向量的每个时间序列都必须是唯一可识别的。

 

把左侧标签加入到输出结果中(实际就是左侧比右侧多标签)

 

示例如下:

 

node_cpu_seconds_total{mode="idle"} / ignoring(mode) group_right sum without(mode)(node_cpu_seconds_total)

node_cpu_seconds_total{mode="idle"} / ignoring(mode) group_right(mode) sum without(mode)(node_cpu_seconds_total)

 

group_right(mode)结果:

 

 

group_right结果:

 

 

 

把右侧标签加入到输出结果中(实际就是右侧比左侧多标签)

 

 

示例如下:

 

sum without(pod)(node_cpu_seconds_total{mode="idle"}) / ignoring(pod) group_left node_cpu_seconds_total

sum without(pod)(node_cpu_seconds_total{mode="idle"}) / ignoring(pod) group_left(pod) node_cpu_seconds_total

 

group_left(pod) 结果:

 

 

group_left结果:

 

 

分组修饰符只能用于比较运算符和算数运算符。默认情况下and、unless和 or操作与右侧向量中的所有可能条目匹配。

 

 

偏移

 

改变时间为查询中的个别时刻和范围矢量偏移。

 

什么意思举个栗子

 

以下表达式返回 node_cpu_seconds_total过去 5 分钟相对于当前查询评估时间的值

 

node_cpu_seconds_total offset 1h

 

 

 

简单说一下API访问方式HTTP接口

 

 

  • query=<string>: Prometheus 表达式查询字符串。
  • start=<rfc3339 | unix_timestamp>: 开始时间戳。
  • end=<rfc3339 | unix_timestamp>: 结束时间戳。

 

 

即时查询返回的结果是vector

 

http://39.106.212.175:30180/api/v1/query?query=node_cpu_seconds_total

 

 

 

status: success表示查询成功,如果失败的话为status: error

 

也可以带范围向量查询

 

http://39.106.212.175:30180/api/v1/query?query=node_cpu_seconds_total[5m]

 

 

 

标量返回是scalar

 

http://39.106.212.175:30180/api/v1/query?query=1

 

 

 

范围查询返回的是范围向量 matrix

 

http://39.106.212.175:30180/api/v1/query_range?query=rate(node_cpu_seconds_total[5m])&start=1627371180&end=1627371210&step=15s

 

 

https://tool.lu/timestamp/可用这个去转换时间戳

 

 

两个注意点start开始时间end结束时间与step,step时间要大于rate的范围时间不然会因为采集时间超过rate范围时间而忽略百分之80的样本,为了防止这种状况,使用至少一个或者两个抓取间隔并且大于step的范围

 

具体api查询可参照官网:https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries

 

正文:

 

聚合运算符

 

这些操作符作用域瞬时向量。可以将瞬时表达式返回的样本数据进行聚合,形成一个具有较少样本值的新的时间序列。

 

 

  • sum (求和)
  • min (最小值)
  • max (最大值)
  • avg (平均值)
  • group (结果向量中的所有值都是 1)
  • stddev (标准偏差)
  • stdvar (标准方差)
  • count (计算向量中元素的数量)
  • count_values (计算具有相同值的元素数)
  • bottomk (样本值的最小 k 个元素)
  • topk (样本值最大的 k 个元素)
  • quantile (在维度上计算 φ-分位数 (0 ≤ φ ≤ 1)

 

 

聚合运算符有11个,可选子句有两个without与by

 

without是去除你选中的标签,而by却是保留你选中的标签.同一个聚合中by与without不能同时使用,只能二选一。

 

知道明确使用的标签用by会很方便,或者知道那个标签不用可以用without。

 

聚合函数count_values、quantile、topk 和 bottomk才需要参数

 

quantile 计算 φ-分位数,即在聚合维度的 N 个度量值中排名第 φ*N 的值。φ 作为聚合参数提供。例如,quantile(0.5, ...)计算中位数, quantile(0.95, ...)即第 95 个百分位数。

 

sum示例:

将分组中的所有值相加将其作为组的值返回。

 

sum without(mode,cpu)(node_cpu_seconds_total)

 

 

min示例:

将取分组内最小的值作为组的返回值。

 

min(node_cpu_seconds_total)

 

 

max示例:

将取分组内最大的值作为组的返回值。

 

max(node_cpu_seconds_total)

 

 

avg示例:

将返回组中时间序列所有值的平均数来作为数组的值。

 

avg(node_cpu_seconds_total)

 

 

stddev示例:

标准差是对一组数字的离散程度统计测量。多数用来检测异常值。(推荐折线图使用)

样本值/样本平均值,这种n项相加除以项数减1,开方即得

 

stddev(node_cpu_seconds_total)

 

 

stdvar示例:

标准方差多数用于找高出两个标准差的所有实例

样本值/平均数^2

 

stdvar(node_cpu_seconds_total)

 

 

count示例:

统计分组中的时间序列总数。

 

count(node_cpu_seconds_total)

 

 

 

count_values示例:

计算筛选标签的值数量"dockerVersion",累加相同值的个数然后返回。(只能计算整数)

 

count_values("dockerVersion",cadvisor_version_info)

 

 

bottomk示例:

瞬时向量中前多少,升序排序

 

bottomk(5,node_cpu_seconds_total)

 

 

topk示例:

瞬时向量中前多少,降序排序

 

topk(5,node_cpu_seconds_total)

 

 

quantile示例:

将组内指定分位数的值作为组的返回值。

 

quantile without(cpu)(0.9,rate(node_cpu_seconds_total{mode="idle"}[5m]))

 

 

 

二元运算符优先级

 

下面的列表显示了 Prometheus 中二元运算符的优先级,从高到低。

 

  1. ^
  2. */,%
  3. +-
  4. ==!=<=<>=,>
  5. andunless
  6. or

 

相同优先级的运算符是左结合的。例如, 2 * 3 % 2相当于(2 * 3) % 2。然而^是右结合的,所以2 ^ 3 ^ 2等价于2 ^ (3 ^ 2)

 

函数

 

改变类型

 

vector()

 

输入为标量,转换为一个没有标签的瞬时向量返回

 

scalar()

 

给定一个单元素输入向量,scalar(v instant-vector)返回该单个元素的样本值作为标量。如果输入向量不只有一个元素,scalar则返回NaN

 

数学函数(个别几个用过)

 

abs()

 

abs(v instant-vector) 返回所有样本值转换为其绝对值(输入可以是向量也可以是标量)。

 

abs(vector(-9))

 

abs(node_cpu_seconds_total)

 

abs(deriv(process_resident_memory_bytes[1d]))

 

ln()

 

ln(v instant-vector)计算 中所有元素的自然对数v。特殊情况是:

 

  • ln(+Inf) = +Inf
  • ln(0) = -Inf
  • ln(x < 0) = NaN
  • ln(NaN) = NaN

 

log2()

 

log2(v instant-vector)计算 中所有元素的二进制对数v。特殊情况等价于ln.

 

log10()

 

log10(v instant-vector)计算 中所有元素的十进制对数v。特殊情况等价于ln.

 

exp()

 

exp(v instant-vector)计算 中所有元素的指数函数v。特殊情况是:

 

  • Exp(+Inf) = +Inf
  • Exp(NaN) = NaN

 

sqrt()

 

sqrt(v instant-vector)计算 中所有元素的平方根v

 

ceil()

 

ceil(v instant-vector)将所有元素的样本值v向上舍入到最接近的整数。

 

ceil(vector(4))

 

 

floor()

 

floor(v instant-vector)将所有元素的样本值v向下舍入到最接近的整数。

 

floor(vector(4.9))

 

 

round()

 

round(v instant-vector, to_nearest=1 scalar)将所有元素的样本值四舍五入为v最接近的整数。通过四舍五入解决。可选to_nearest参数允许指定样本值为四舍五入最接近的倍数。这个倍数也可以是分数。

 

round(node_cpu_seconds_total)

 

4舍5入

 

 

 

clamp()

 

clamp(v instant-vector, min scalar, max scalar) 将所有元素的样本值钳制在v下限为min和上限为max

 

特殊情况: - 返回空向量 if min > max - 返回NaN if  min 或 max is  NaN

 

就是把下限改为min,上限改为max中间值不变。直白的说就是小于min的改为min,大于max改为max

 

clamp(node_cpu_seconds_total,23,234)

 

 

clamp_max()

 

clamp_max(v instant-vector, max scalar)将所有元素的样本值钳制在v上限为max.

 

上限改为max

 

clamp_max(node_cpu_seconds_total,234)

 

 

clamp_min()

 

clamp_min(v instant-vector, min scalar)将所有元素的样本值钳制在v下限为min

 

下线改为min

 

clamp_min(node_cpu_seconds_total,23)

 

 

 

时间函数

 

 

Timestamp可以查看实际的瞬时向量时间戳就是采集那一次的真是时间

 

Time采集的是那个执行命令的时间

 

time()

 

time()返回自 UTC 时间 1970 年 1 月 1 日以来的秒数。请注意,这实际上并不返回当前时间,而是要计算表达式的时间。

 

常用于查看程序运行了多久

 

timestamp()

 

timestamp(v instant-vector) 返回给定向量的每个样本的时间戳,作为自 UTC 时间 1970 年 1 月 1 日以来的秒数

 

这个功能是在 Prometheus 2.0 中添加的

 

hour()

 

hour(v=vector(time()) instant-vector)以 UTC 格式返回每个给定时间的一天中的小时。返回值从 0 到 23

 

minute()

 

minute(v=vector(time()) instant-vector)以 UTC 格式返回每个给定时间的小时中的分钟数。返回值从 0 到 59

 

month()

 

month(v=vector(time()) instant-vector)以 UTC 格式返回每个给定时间的年份中的月份。返回值从 1 到 12,其中 1 表示一月等

 

year()

 

year(v=vector(time()) instant-vector) 以 UTC 格式返回每个给定时间的年份。

 

day_of_month()

 

day_of_month(v=vector(time()) instant-vector)以 UTC 格式返回每个给定时间的月份中的第几天。返回值从 1 到 31 

 

day_of_week()

 

day_of_week(v=vector(time()) instant-vector)以 UTC 格式返回每个给定时间的星期几。返回值从 0 到 6,其中 0 表示星期日等

 

days_in_month()

 

days_in_month(v=vector(time()) instant-vector)返回每个给定时间的 UTC 月份中的天数。返回值是从 28 到 31

 

标签函数

 

 

Sort与sort_desc都是按照瞬时向量值排序nan值在最后

 

label_join()

 

对于 中的每个时间序列vlabel_join(v instant-vector, dst_label string, separator string, src_label_1 string, src_label_2 string, ...)连接所有src_labels using的所有值separator并返回带有dst_label包含连接值的标签的时间序列。src_labels在这个函数中可以有任意数量。

 

 

类似于metrics_relabel_configs的重新修改标签

 

作用把两个标签的值链接到一起,combined是你的标签-是分隔符namespace与job就是你要链接的标签,链接输出值按照输入namespace与job的先后顺序(不推荐,尽量使用metrics_relabel_configs)

 

 

label_join(node_disk_read_bytes_total,"combined","-","namespace","job")

 

 

label_replace()

 

对于 中的每个时间序列vlabel_replace(v instant-vector, dst_label string, replacement string, src_label string, regex string) 将正则表达式regex与标签的值进行匹配src_label。如果匹配,则dst_label返回的时间序列中标签的值将是 的扩展replacement,以及输入中的原始标签。正则表达式中的捕获组可以用$1$2等引用。如果正则表达式不匹配,则返回时间序列不变。

 

就是把标签job,device换成dev与name,而且这个函数输入的是一个瞬时向量输出的是一个指标名称,所以他不会删除指标名称。如果正则与给定样本不匹配那么保持不变

 

label_replace(node_memory_MemFree_bytes,"name","${1}","job","(.*)")

 

 

absent()

 

absent(v instant-vector) 如果传递给它的向量有任何元素,则返回一个空向量,如果传递给它的向量没有元素,则返回值为 1 的 1 元素向量。

 

简单来说就是输入的向量有返回值经过函数作用会返回空,反之会返回输入值就是把values置为1。

 

这对于在给定指标名称和标签组合不存在时间序列时发出警报非常有用。

 

absent(node_cpu_seconds_total{mode="1"})

absent(node_cpu_seconds_total{mode="idle"})

 

absent_over_time()

 

absent_over_time(v range-vector) 如果传递给它的范围向量有任何元素,则返回一个空向量,如果传递给它的范围向量没有元素,则返回一个值为 1 的 1 元素向量。与absent用法一致不过它是针对范围向量。

 

这对于在给定的指标名称和标签组合在一定时间内不存在时间序列时发出警报非常有用。

 

absent_over_time(node_cpu_seconds_total{mode="idle"}[5m])

absent_over_time(node_cpu_seconds_total{mode="1"}[5m])

 

sort()

 

sort(v instant-vector) 返回按样本值升序排序的向量元素。

 

sort_desc()

 

与相同sort,但按降序排序。

 

sgn()

 

sgn(v instant-vector) 返回一个向量,其中所有样本值都转换为其符号,定义如下:如果 v 为正,则为 1,如果 v 为负,则为 -1,如果 v 等于零,则为 0。

 

histogram_quantile()

 

histogram_quantile(φ scalar, b instant-vector)从直方图的桶b中 计算 φ-分位数 (0 ≤ φ ≤ 1) 。(有关φ 分位数的详细说明和直方图度量类型的一般用法,请参阅 直方图和摘要。)中的样本是每个桶中的观察计数。每个样本必须有一个标签,其中标签值表示桶的包含上限。(没有这种标签的样本将被默默忽略。)直方图度量类型 自动提供带有后缀和适当标签的时间序列。ble_bucket

 

使用该rate()函数指定分位数计算的时间窗口。

 

示例:直方图度量称为prometheus_http_request_duration_seconds_bucket。要计算过去 10m 中请求持续时间的第 90 个百分位数,请使用以下表达式:

 

histogram_quantile(0.9, rate(prometheus_http_request_duration_seconds_bucket[10m]))

 

分位数是每个标签组合计算的 http_request_duration_seconds。要聚合,请sum()rate()函数周围使用聚合器。由于le需要保留 histogram_quantile(),因此它必须包含在by子句中。以下表达式将第 90 个百分位数聚合为job

 

histogram_quantile(0.9, sum by (job, le) (rate(prometheus_http_request_duration_seconds_bucket[10m])))

 

要聚合所有内容,请仅指定le标签:

 

histogram_quantile(0.9, sum by (le) (rate(prometheus_http_request_duration_seconds_bucket[10m])))

 

histogram_quantile()函数通过假设桶内的线性分布来插入分位数值。最高存储桶的上限必须为+Inf(无穷大)。(否则,NaN返回。)如果分位数位于最高桶中,则返回第二高桶的上限。如果最低桶的上限大于 0,则假定最低桶的下限为 0。在这种情况下,在该桶内应用通常的线性插值。否则,为位于最低存储桶中的分位数返回最低存储桶的上限。

 

如果b有 0 个观察值,NaN则返回。如果b包含少于两个桶, NaN则返回。对于 φ < 0,-Inf返回。对于 φ > 1,+Inf返回。

 

 

计数器

 

 

rate()

 

rate(v range-vector)计算范围向量中时间序列的每秒平均增长率。单调性中断(例如由于目标重新启动导致计数器重置)会自动调整。此外,计算外推到时间范围的末端,允许遗漏刮擦或刮擦周期与范围时间段的不完美对齐。

 

以下示例表达式返回过去10 分钟内测量 cpu 请求每秒平均增长率:

 

rate(node_cpu_seconds_total[10m])

 

 

 

rate应该只与计数器一起使用。它最适合用于警报和缓慢移动计数器的图形。

 

 

 

请注意,当rate()与聚合运算符(例如sum())或随时间聚合的函数(以结尾的任何函数_over_time)组合时,始终rate()先进行聚合,然后进行聚合。否则rate()当您的目标重新启动时无法检测计数器重置。

 

increase()

 

increase(v range-vector)计算范围向量中时间序列的增加率。单调性中断(例如由于目标重新启动导致计数器重置)会自动调整。外推增加以覆盖范围向量选择器中指定的整个时间范围,因此即使计数器仅以整数增量增加,也可以获得非整数结果。

 

 

此函数和 rate() 完全一样,只是它没有将最终单位转换为 “每秒”(1/s)。每个规定的采样周期就是它的最终单位。

 

 

例如:increase(node_cpu_seconds_total[5m]) 得出的是5分钟的采样周期内处理完成的cpu总增长量(单位1/5m)。在作除法就切成了每秒



获取时间序列最近1小时的所有样本,increase计算出最近1小时的增长量,最后除以时间3600秒得到样本在最近1小时的平均增长率

 

rate(node_cpu_seconds_total[1h]) / 3600 等于increase(node_cpu_seconds_total[1h])测算1h内的平均增长率

 

increase应该只与计数器一起使用。它是rate(v)乘以指定时间范围窗口下的秒数的语法糖,主要用于人类可读性。rate在记录规则中使用,以便每秒一致地跟踪增加。

 

irate()

 

irate(v range-vector)计算范围向量中时间序列的每秒即时增长​​率。这是基于最后两个数据点。单调性中断(例如由于目标重新启动导致计数器重置)会自动调整。

 

irate则适用于每秒的增长率,但是不适用与告警

 

以下示例表达式返回范围向量中每个时间序列的两个最近数据点的 HTTP 请求的每秒速率,该请求最多可回溯 5 分钟

 

irate(node_cpu_seconds_total[5m])

 

irate只应在绘制易变、快速移动的计数器时使用

 

请注意,当irate()与聚合运算符(例如sum())或随时间聚合的函数(任何以_over_time结尾的函数)组合时,始终irate()先进行计算,然后进行聚合。否则irate()当您的目标重新启动时无法检测计数器重置。

 

 

resets()

 

 

对于每个输入时间序列,resets(v range-vector)返回提供的时间范围内的计数器重置次数作为即时向量。两个连续样本之间的任何值减少都被解释为计数器重置。

 

计算进程重启cpu重置次数,也就是进程重启了,可以用这个判断进程问题

 

resets(process_start_time_seconds[1h])

 

resets 应该只与计数器一起使用。

 

 

改变gauge值

 

changes()

 

对于每个输入时间序列,changes(v range-vector)返回其值在提供的时间范围内作为即时向量发生变化的次数。

 

change 意味着变化,多数用于检测程序是否异常,因为带时间范围内多次重启意味着程序有问题

 

changes(process_start_time_seconds[1w])

 

 

deriv()

 

deriv(v range-vector)v使用简单线性回归计算范围向量中时间序列的每秒变化。

 

可以根据这个判断gauge值变化速度进行告警

 

这个意思是根据过去一小时的样本计算每秒常驻内存的变化速度

 

deriv(process_resident_memory_bytes[1h])

 

deriv 只能与仪表一起使用。

 

 

predict_linear()

 

predict_linear(v range-vector, t scalar)t基于范围向量v,使用简单线性回归预测从现在开始的时间序列的值。

 

根据这一个小时的样本预测未来四个小时内每个文件系统剩余可用空间,prometheus都是秒为单位所以是4 * 3600

 

predict_linear(node_filesystem_free_bytes{job="node-exporter"}[1h], 4 * 3600)

 

predict_linear 只能与仪表一起使用。

 

delta()

 

delta(v range-vector)计算范围向量中每个时间序列元素的第一个和最后一个值之间的差异v,返回具有给定增量和等效标签的即时向量。delta 被外推以覆盖范围向量选择器中指定的整个时间范围,因此即使样本值都是整数,也有可能获得非整数结果。

 

以下示例表达式返回现在和 1 小时前之间常驻内存的差异:

 

delta(process_resident_memory_bytes[1h])

 

delta 只能与仪表一起使用。

 

idelta()

 

idelta(v range-vector)计算范围向量中最后两个样本之间的差异v,返回具有给定增量和等效标签的即时向量。

 

Idelta采集时间范围内最后两个值返回他们的差

 

idelta(process_resident_memory_bytes[1h])

 

idelta 只能与仪表一起使用。

 

holt_winters()

 

holt_winters(v range-vector, sf scalar, tf scalar)根据范围向量中的时间序列生成平滑值v。平滑因子越低sf,旧数据就越重要。趋势因子越高tf,数据中的趋势被考虑的越多。二者sftf必须在0和1之间。

 

这东西个人感觉来衡量以前到以后的机器性能或者计算业务整体增长状况应该挺好用

 

holt_winters(process_resident_memory_bytes{job="alertmanager-main",pod="alertmanager-main-0"}[1h],0.1,0.5)

 

holt_winters 只能与仪表一起使用。

 

 

随时间聚合函数

 

over_time的都是随时间聚合的,指在一定时间内取函数样本。所以第一个词就是随时间聚合函数的意思与作用

 

<aggregation>_over_time()

 

以下函数允许随时间聚合给定范围向量的每个系列,并返回具有每个系列聚合结果的即时向量:

 

  • avg_over_time(range-vector):指定区间内所有点的平均值。
  • min_over_time(range-vector):指定区间内所有点的最小值。
  • max_over_time(range-vector):指定区间内所有点的最大值。
  • sum_over_time(range-vector):指定区间内所有值的总和。
  • count_over_time(range-vector):指定区间内所有值的计数。
  • quantile_over_time(scalar, range-vector):指定区间内值的 φ 分位数 (0 ≤ φ ≤ 1)。
  • stddev_over_time(range-vector):指定区间内值的总体标准差。
  • stdvar_over_time(range-vector):指定区间内值的总体标准方差。
  • last_over_time(range-vector):指定时间间隔内的最近点值。

 

请注意,指定间隔中的所有值在聚合中都具有相同的权重,即使这些值在整个间隔中的间隔不等。

 

 

到这基本PromQL基本结束,其他就看用法了

posted on 2021-07-27 11:14  K&  阅读(1582)  评论(0)    收藏  举报