Prometheus Learning Series (seven) Description of Prometheus PromQL

Foreword

This article comes from Prometheus's official website Manual 1 , 2 , 3  and  Prometheus Introduction 1 , 2 , 3

PromQL operator

A binary operator

Prometheus query language support basic logic and arithmetic operations. For two instantaneous vectors,  matching behavior can be changed.

1.1 Arithmetic binary operator

In Prometheus supports the following binary arithmetic operators:

  • + addition
  • - Subtraction
  • * multiplication
  • / division
  • % mold
  • ^ Idempotent

Binary operators operator defined scalar/scalar(标量/标量), vector/scalar(向量/标量)and vector/vector(向量/向量)between.

  • Between two scalar: Evaluation another scalar, which is applied to two operator scalar operands results.
  • Between the instantaneous vector and scalar: The operator is applied to each data sample value in the vector. If the instant in time series vector by 2, the result is another vector, each vector in which the original sample value is multiplied by two.
  • Between the two instantaneous vectors: applied to each entry of the left and right of the vector in the vector matching elements . The results are propagated to the result vector. Part (no matching entry) is not the result of the right vector.

1.2 Comparison of binary operators

Prometheus system in comparison with a binary operator:

  • == equal
  • != not equal to
  • > more than the
  • < Less than
  • >= greater or equal to
  • <= Less than or equal

Comparison of binary operators defined in scalar/scalar(标量/标量), vector/scalar(向量/标量), and vector/vector(向量/向量). Filter by default. It can be provided after the operator boolto modify their behavior, which will return value 0or 1not filtered.

  • Between two scalar: it must provide boolmodifiers, and other such operator produces a scalar, i.e. 0(false) or 1(true), depending on the comparison result.
  • Between the instantaneous vector and scalar: The value of these operators is applied to each data sample vector and deleted from the result of the comparison result vector elements of a vector is false. If a boolmodifier, vector elements will be deleted value 0, but will retain the vector elements is 1.
  • Between the two instantaneous vectors: These operators default filter performance, is applied to the matching entry. Incorrect or missing expression vector elements match the other side of the expression is deleted from the result, while other elements will have propagated to their original (left) measurement results, a standard name tag vector values. If a boolmodifier, vector elements have been deleted value 0value, while retaining the vector elements 1left the label value 1.

 Such as:

3 > 2
# 报错 "comparisons between scalars must use BOOL modifier"
 
. 3 > BOOL  2  
# returns Scalar . 1
 
1 > bool 2 

1.3 Logical / binary operator set

Logic / set only binary operator acting in real time vector, comprising:

  • and Intersection
  • or Union
  • unless Complement

vector1 and vector2: To give a the vector1vector elements, wherein vector2the elements have a full set of matching labels, other elements are deleted.

vector1 or vector2:Obtained it contains vector1all the elements of the original (tag set value +) vector, and vector2the vector1all of the elements there is no matching tag set.

vector1 unless vector2:To give a the vector1vector elements, wherein vector2no element having a matching set of labels exactly. All matching elements in two vectors are deleted.

Second, vector match

Operation tries to find the vector between the matching element vector for each entry on the right side on the left. There are two basic types of behavior match: and many-to-one / many.

The only one find a pair of entries from each side of the operation. By default, this is the format for the vector1<operator>vector2operation after. If two entries have exactly the same set of labels and corresponding values, they match. Ignore keyword allows you to ignore some tags in the match, but onthe keyword tag set will allow the consideration is reduced to the provided list:
[vector expr] [bin-op] ignoring([label list]) [vector expr]

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

For example, the sample data:

 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

Query examples:

method_code:http_errors:rate5m{code="500"} / ignoring(code) method:http_requests:rate5m
This will return a status code of the result vector, wherein the method comprises for each of the HTTP 500 requests part, measured in the past five minutes. No ignoring(code)there is no match, because the metrics do not share the same set of tags. The method putand delthe entry does not match, and does not appear in the results:
{method="get"} 0.04 // 24 / 600
{method="post"} 0.05 // 6 / 120

2.2 Many-to-many and vector match

And many-to-many matching refers to the "a" side of each vector element may be "many" side of the plurality of matching elements. You must use group_leftor group_rightmodifier explicitly requested, which left/rightdetermine which vector has a higher base.

<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(<labels>)可提供所需的结果。

三、聚合操作符

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

  • sum (在维度上求和)
  • max (在维度上求最大值)
  • min (在维度上求最小值)
  • avg (在维度上求平均值)
  • stddev (求标准差)
  • stdvar (求方差)
  • count (统计向量元素的个数)
  • count_values (统计相同数据值的元素数量)
  • bottomk (样本值第k个最小值)
  • topk (样本值第k个最大值)
  • quantile (统计分位数)

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

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

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

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

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

如果度量标准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)

PromQL函数

一些函数有默认的参数,例如:year(v=vector(time()) instant-vector)。意思是有一个参数v是一个瞬时向量,如果没有提供,它将默认为表达式vector(time())的值。

一、abs()

abs(v instant-vector)返回输入向量,所有样本值都转换为其绝对值

二、absent()

absent(v instant-vector)如果传递给它的向量具有任何元素,则返回空向量;如果传递给它的向量没有元素,则返回值为1的1元素向量。这对于在给定度量标准名称和标签组合不存在时间序列时发出警报非常有用。

absent(nonexistent{job="myjob"})  
# => {job="myjob"}
absent(nonexistent{job="myjob", instance=~".*"}) 
# => {job="myjob"}
absent(sum(nonexistent{job="myjob"})) 
# => {}

在第二个例子中,absent()试图从输入向量中导出1元素输出向量的标签。

三、ceil()

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

四、changes()

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

五、clamp_max()

clamp_max(v instant-vector, max scalar) 将v中所有元素的样本值设为最大。

六、clamp_min()

clamp_min(v instant-vector, min scalar)将v中所有元素的样本值设为最小。

七、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。

十、delta()

delta(v range-vector)计算范围向量v中每个时间系列元素的第一个和最后一个值之间的差值,返回具有给定增量和等效标签的即时向量。 以下示例表达式返回现在和2小时之前CPU温度的差异:

delta(cpu_temp_celsius{host="zeus"}[2h])

delta应仅用于gauges

十一、deriv()

deriv(v range-vector)函数,计算一个范围向量v中各个时间序列二阶导数,使用简单线性回归
deriv应仅用于gauges。

十二、exp()

exp(v instant-vector)计算v中所有元素的指数函数:

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

十三、floor()

floor(v instant-vector)v中所有元素的样本值舍入为最接近的整数。

十四、histogram_quantile()

histogram_quatile(φ float, b instant-vector) 计算b向量的φ-直方图 (0 ≤ φ ≤ 1) 。(有关φ-分位数的详细解释和直方图度量类型的使用,请参见直方图和摘要。)b中的样本是每个桶中的观察计数。 每个样本必须具有标签le,其中标签值表示桶的包含上限。 (没有这种标签的样本会被忽略。)直方图度量标准类型自动提供带有_bucket后缀和相应标签的时间序列。使用rate()函数指定分位数计算的时间窗口。

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

histogram_quantile(0.9, rate(http_request_duration_seconds_bucket[10m]))
http_request_duration_seconds中为每个标签组合计算分位数。 要聚合,请在rate()函数周围使用sum()聚合器。 由于histogram_quantile()需要le标签,因此必须将其包含在by子句中。 以下表达式按作业聚合第90个百分点:
histogram_quantile(0.9, sum(rate(http_request_duration_seconds_bucket[10m])) by (job, le))

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

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

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

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

十五、holt_winters()

holt_winters(v range-vector, sf scalar, tf scalar)根据v中的范围产生时间序列的平滑值。平滑因子sf越低,对旧数据的重要性越高。 趋势因子tf越高,则考虑的数据趋势越多。 sftf都必须介于0和1之间。

holt_winters只能用于gauges。

十六、hour()

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

十七、idelta()

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

idelta只能用于gauges。

十八、increase()

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

以下示例表达式返回范围向量中每个时间系列在过去5分钟内测量的HTTP请求数

increase(http_requests_total{job="api-server"}[5m])

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

十九、irate

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

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

irate(http_requests_total{job="api-server"}[5m])

只应在绘制易失性快速移动计数器时使用irate。 警报和缓慢移动计数器的使用率,因为速率的简短更改可以重置FOR子句,并且难以阅读完全由稀有峰值组成的图形。

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

二十、label_join()

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

此示例将返回一个向量,每个时间序列都有一个foo标签,其中添加了值a,b,c

label_join(up{job="api-server",src1="a",src2="b",src3="c"}, "foo", ",", "src1", "src2", "src3")

二十一、label_replace()

对于v中的每个时间序列,label_replace(v instant-vector, dst_label string, replacement string, src_label string, regex string) 将正则表达式正则表达式与标签src_label相匹配。 如果匹配,则返回时间序列,标签dst_label替换为替换扩展。 $1替换为第一个匹配的子组,$2替换为第二个等。如果正则表达式不匹配,则返回时间序列不变。

此示例将返回一个向量,每个时间序列都有一个foo标签,其值为a

label_replace(up{job="api-server",service="a:c"}, "foo", "$1", "service", "(.):.")

二十二、ln()

ln(v instance-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中所有元素的10进制对数。特殊情况等同于ln中的特殊情况。

二十五、minute()

minute(v=vector(time()) instant-vector)以UTC为单位返回每个给定时间的分钟。 返回值为0到59。

二十六、month()

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

二十七、predict_linear()

predict_linear(v range-vector, t scalar)根据范围向量v使用线性回归预测从现在起t秒的时间序列值。

predict_linear只能与gauges一起使用。

二十八、rate()

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

以下示例表达式返回范围向量中每个时间系列在过去5分钟内测量的每秒HTTP请求率:

rate(http_requests_total{job="api-server"}[5m])

rate应仅用于计数器。 它最适用于警报和缓慢移动计数器的图形。

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

二十九、resets()

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

resets()只能与counter一起使用。

三十、round()

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

三十一、scalar()

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

三十二、sort()

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

三十三、sort_desc()

sort(v instant-vectorsort相同,但按降序排序。

三十四、sqrt()

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

三十五、time()

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

三十六、timestamp()

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

此功能已添加到Prometheus 2.0中

三十七、vector()

vector(s scalar)将标量s作为没有标签的向量返回。

三十八、year()

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

三十九、<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): 范围向量内每个度量指标的样本数据值分位数,φ-quantile (0 ≤ φ ≤ 1)
  • stddev_over_time(range-vector): 范围向量内每个度量指标的总体标准偏差。
  • `stdvar_over_time(range-vector): 范围向量内每个度量指标的总体标准方差。

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

PromQL例子

一、简单的时间序列选择

使用度量标准http_requests_total返回所有时间序列: 

http_requests_total

使用度量标准http_requests_total以及给定的jobhandler标签返回所有时间系列:

http_requests_total{job="apiserver", handler="/api/comments"}

返回相同向量的整个时间范围(在本例中为5分钟),使其成为范围向量:

http_requests_total{job="apiserver", handler="/api/comments"}[5m]

请注意,导致范围向量的表达式不能直接绘制,而是在表达式浏览器的表格("Console")视图中查看。

使用正则表达式,您只能为名称与特定模式匹配的作业选择时间序列,在本例中为所有以server结尾的作业。 请注意,这会进行子字符串匹配,而不是完整的字符串匹配:

http_requests_total{job=~"server$"}

要选择除4xx之外的所有HTTP状态代码,您可以运行:

http_requests_total{status!~"^4..$"}

二、子查询

此查询返回过去30分钟的5分钟 http_requests_total指标率,分辨率为1分钟:
rate(http_requests_total[5m])[30m:1m]

这是嵌套子查询的示例。 deri函数的子查询使用默认分辨率。 请注意,不必要地使用子查询是不明智的。

max_over_time(deriv(rate(distance_covered_total[5s])[30s:5s])[10m:])

三、使用函数,操作符等

使用http_requests_total指标名称返回所有时间序列的每秒速率,在过去5分钟内测量:

rate(http_requests_total[5m])
假设http_requests_total时间序列都有标签job(按作业名称扇出)和instance(按作业实例扇出),我们可能想要总结所有实例的速率,因此我们得到的输出时间序列更少,但仍然 保留job维度
sum(rate(http_requests_total)[5m]) by (job)
如果我们有两个具有相同维度标签的不同指标,我们可以对它们应用二元运算符,并且两侧具有相同标签集的元素将匹配并传播到输出。 例如,此表达式为每个实例返回MiB中未使用的内存(在虚构的群集调度程序上公开它运行的实例的这些度量标准):
(instance_memory_limit_byte - instant_memory_usage_bytes) / 1024 / 1024

相同的表达式,但由应用程序总结,可以这样写:

sum( instance_memory_limit_bytes - instance_memory_usage_bytes) by (app, proc) / 1024 / 1024

如果相同的虚构集群调度程序为每个实例公开了如下所示的CPU使用率指标:

instance_cpu_time_ns{app="lion", pro="web", rev="34d0f99", env="prod", job="cluster-manager"}
instance_cpu_time_ns{app="elephant", proc="worker", rev="34d0f99", env="prod", job="cluster-manager"}
instance_cpu_time_ns{app="turtle", proc="api", rev="4d3a513", env="prod", job="cluster-manager"}
...

我们可以按应用程序(app)和进程类型(proc)分组排名前3位的CPU用户:

topk(3, sum(rate(instance_cpu_time_ns[5m])) by(app, proc))

假设此度量标准包含每个运行实例的一个时间系列,您可以计算每个应用程序运行实例的数量,如下所示:

count(instance_cpu_time_ns) by (app)

 

Guess you like

Origin www.cnblogs.com/zhoujinyi/p/11951965.html