运维监控系列(20)-PromQL运算符

二元运算符

PromQL支持基本的算术运算和逻辑运算,这类运算支持使用操作符连接两个操作数,因而也称为二元运算符或二元操作符。

支持的运算:

  • 两个标量间运算;
  • 即时向量和标量间的运算:将运算符应用于向量上的每个样本;
  • 两个即时向量间的运算:遵循向量匹配机制;

算术运算符

Prometheus 中存在以下二元算术运算符:

  • (+) (加)
  • (-) (减)
  • (*) (乘)
  • (/ )(除)
  • (%) (取模)
  • (^) (幂运算)

二元运算操作符定义在scalar/scalar(标量/标量)、vector/scalar(向量/标量)、和vector/vector(向量/向量)之间。

在两个标量之间,行为是显而易见的:它们评估另一个标量,这是运算符应用于两个标量操作数的结果。

在瞬时向量和标量之间,将运算符应用于向量中的每个数据样本的值。 例如。 如果时间序列即时向量乘以2,则结果是另一个向量,其中原始向量的每个样本值乘以2。

在两个瞬时向量之间,二进制算术运算符应用于左侧向量中的每个条目及其右侧向量中的匹配元素。 结果将传播到结果向量中,并删除度量标准名称。 可以找到右侧向量中没有匹配条目的条目不是结果的一部分。

比较运算符

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

  • == (相等)
  • != (不相等)
  • (>) (大于)
  • (< )(小于)
  • (>=) (大于或等于)
  • (<= )(小于或等于)

比较二元操作符定义在scalar/scalar(标量/标量)、vector/scalar(向量/标量),和vector/vector(向量/向量)。默认情况下他们过滤。 可以通过在运算符之后提供bool来修改它们的行为,这将为值返回0或1而不是过滤。

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

在瞬时向量和标量之间,将这些运算符应用于向量中的每个数据样本的值,并且从结果向量中删除比较结果为假的向量元素。 如果提供了bool修饰符,则将被删除的向量元素的值为0,而将保留的向量元素的值为1。

在两个瞬时向量之间,这些运算符默认表现为过滤器,应用于匹配条目。 表达式不正确或在表达式的另一侧找不到匹配项的向量元素将从结果中删除,而其他元素将传播到具有其原始(左侧)度量标准名称的结果向量中 标签值。 如果提供了bool修饰符,则已经删除的向量元素的值为0,而保留的向量元素的值为1,左侧标签值为1。

逻辑/聚合运算符

逻辑/集合二元操作符只能作用在即时向量, 包括:

  • and 交集
  • or 并集
  • unless 补集

vector1 and vector2得到一个由vector1元素组成的向量,其中vector2中的元素具有完全匹配的标签集。 其他元素被删除。 度量标准名称和值从左侧向量转移

vector1 or vector2得到包含vector1的所有原始元素(标签集+值)的向量以及vector2中vector1中没有匹配标签集的所有元素。。

vector1 unless vector2得到一个由vector1元素组成的向量,其中vector2中没有元素,具有完全匹配的标签集。 两个向量中的所有匹配元素都被删除。

向量匹配

向量之间的操作尝试在左侧的每个条目的右侧向量中找到匹配元素。 匹配行为有两种基本类型:一对一和多对一/一对多。

一对一向量匹配

一对一从操作的每一侧找到一对唯一条目。 在默认情况下,这是格式为vector1vector2之后的操作。 如果两个条目具有完全相同的标签集和相应的值,则它们匹配。 忽略关键字允许在匹配时忽略某些标签,而on关键字允许将所考虑的标签集减少到提供的列表:

[vector expr] [bin-op] ignoring([label list]) [vector expr]

[vector expr] [bin-op] on([lable list]) [vector expr]

例如样本数据:

 method_code:http_errors:rate5m{
   
     method="get", code="500"} 24
 method_code:http_errors:rate5m{
   
     method="get", code="404"} 30
 method_code:http_errors:rate5m{
   
     method="put", code="501"} 3
 method_code:http_errors:rate5m{
   
     method="post", code="404"} 21

 method:http_requests:rate5m{
   
     method="get"} 600
 method:http_requests:rate5m{
   
     method="delete"} 34
 method:http_requests:rate5m{
   
     method="post"} 120

查询例子:

method_code:http_errors:rate5m{
   
     code=“500”} / ignoring(code) method:http_requests:rate5m

这将返回一个结果向量,其中包含每个方法的状态代码为500的HTTP请求部分,在过去的5分钟内进行测量。 没有ignoring(code)就没有匹配,因为度量标准不共享同一组标签。 方法put和del的条目没有匹配,并且不会显示在结果中:

{
   
     method=“get”} 0.04 // 24 / 600

{
   
     method=“post”} 0.05 // 6 / 120

多对一和一对多向量匹配

多对一和一对多匹配指的是“一”侧的每个向量元素可以与“多”侧的多个元素匹配的情况。 必须使用group_left或group_right修饰符明确请求,其中left/right确定哪个向量具有更高的基数。

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

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

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

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

随组修饰符提供的标签列表包含来自“一”侧的其他标签,以包含在结果度量标准中。 对于标签,只能出现在其中一个列表中。 每次结果向量的序列必须是唯一可识别的。

分组修饰符只能用于比较和算术。 默认情况下,操作as和除非和或操作与右向量中的所有可能条目匹配。

示例查询:

method_code:http_errors:rate5m / ignoring(code) group_left method:http_requests:rate5m

在这种情况下,左向量每个method标签值包含多个条目。 因此,我们使用group_left表明这一点。 右侧的元素现在与多个元素匹配,左侧具有相同的method标签:

{
   
     method=“get”, code=“500”} 0.04 // 24 /600
{
   
     method=“get”, code=“404”} 0.05 // 30 /600

{
   
     method=“post”, code=“500”} 0.05 // 6 /600

{
   
     method=“post”, code=“404”} 0.175 // 21 /600

多对一和一对多匹配是高级用例,应该仔细考虑。 通常正确使用忽略ignoring()可提供所需的结果。

聚合运算符

Prometheus 支持以下内置聚合运算符,可用于聚合单个即时向量的元素,从而生成具有聚合值的更少元素的新向量:

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

这些运算符可以用于聚合所有标签维度,也可以通过包含without或by子句来保留不同的维度。

<aggr-op>([parameter,] <vector expr>) [without | by (<label list>)] [keep_common]

parameter仅用于count_values,quantile,topk和bottomk。不从结果向量中删除列出的标签,而所有其他标签都保留输出。 by相反并删除未在by子句中列出的标签,即使它们的标签值在向量的所有元素之间是相同的。

count_values输出每个唯一样本值的一个时间序列。每个系列都有一个额外的标签。该标签的名称由聚合参数给出,标签值是唯一的样本值。每个时间序列的值是样本值存在的次数。

topk和bottomk与其他聚合器的不同之处在于,输入样本的子集(包括原始标签)在结果向量中返回。 by和without仅用于存储输入向量。

例:

如果度量标准http_requests_total具有按应用程序,实例和组标签扇出的时间序列,我们可以通过以下方式计算每个应用程序和组在所有实例上看到的HTTP请求总数:

sum(http_requests_total) without (instance)

等价于:

sum(http_requests_total)

要计算运行每个构建版本的二进制文件的数量,我们可以编写:

count_values(“version”, build_version)

要在所有实例中获取5个最大的HTTP请求计数,我们可以编写:

topk(5, http_requests_total)

二元运算符优先级

以下列表显示了Prometheus中二进制运算符的优先级,从最高到最低:

  • ^
  • *, /, %
  • +, -
  • ==, !=, <=,<, >=, >
  • and, unless
  • or

具有相同优先级的运算符是左关联的。 例如,2 * 3%2相当于(2 * 3)%2。但是^是右关联的,因此2 ^ 3 ^ 2相当于2 ^(3 ^ 2)。

文档来源

https://prometheus.io/docs/prometheus/latest/querying/operators/

版权声明:本文不是「本站」原创文章,版权归原作者所有 | 原文地址: