开始使用PromQL

首先

这篇文章是根据 Prometheus 的 “QUERING PROMETHEUS” 一章进行的日本语翻译,并结合了 Prometheus 入门的内容以及实际尝试的内容进行了补充。

更具实际应用价值的例子可以在《Kubernetes(GKE)实用小技巧:便捷的Prometheus技巧集》一书中找到。

PromQL 是一种查询语言。

PromQL(Prometheus Query Language)是用于获取和聚合Prometheus时间序列数据的查询语言。

查询结果可以在Prometheus的表达式浏览器中以表格形式或图表形式进行显示。

当使用像Grafana这样的图表绘制工具进行图表显示时,我们会使用查询语言来向Prometheus发送查询请求。

以下是中文的同义短语:

度量衡

Prometheus所参考的时序数据称为指标(metric)。
例如,表征内存使用量的 process_resident_memory_bytes 就是一个指标。

通常情况下,对于某个度量指标,存在多个时间序列数据。例如,度量指标 process_resident_memory_bytes 可能会有 Prometheus 的内存使用量和主机的内存使用量这两个时间序列数据。

数据类型

PromQL 可处理的数据类型包括以下几种。

    • Instant vector

 

    • Range vector

 

    • Scalar

 

    String

即时向量是一种类似于内存使用量的时序数据。
范围向量是过去一段时间内即时向量值的聚合数据,从某个时间点开始计算。
标量和字符串指的是不是时序的简单值,比如1和”string”。

可以在图表中显示的是即时向量,其他数据类型则用于在计算值或在特定时间段内汇总值时使用。

時系列数据选择器

公式

最简单的选择器形式是使用指标名称。

例如,process_resident_memory_bytes将选择所有具有”进程驻留内存字节”指标的即时向量。

image.png

上面的是在 Prometheus 的 Grafana 浏览器中展示 process_resident_memory_bytes 的图形结果。可以看到选择了具有两个标签的 instant vector:{instance=”localhost:9100″, job=”node”} 和 {instance=”localhost:9090″, job=”prometheus”}。

标签匹配器(基本版)

用标签来过滤指标的部分被称为标签匹配器。

如果我们正在提取 Prometheus 进程(job=”prometheus”)和主机(job=”node”)的两个内存使用量,那么可以通过使用 process_resident_memory_bytes{job=”node”} 来获取仅主机的内存使用量。

image.png

在这个例子中,{job=”node”} 是一个标签匹配器。
只有标签的 job 完全匹配 “node” 的数据才能被过滤出来。

你也可以使用正则表达式来匹配 “n” 开头的任何工作。

オペレータ説明=指定した文字列と完全一致するラベルを選択する!=指定した文字列と異なるラベルを選択する=~指定した正規表現に合致するラベルを選択する!~指定した正規表現に合致しないラベルを選択する

在这种情况下,比如指定了 hoge=”” ,将会选择所有不存在标签 hoge 的时间序列数据。

标签匹配器(应用)

标签匹配器可以应用于指标名称。

由于 metric 名称内部附有 __name__ 标签,因此可以为该标签指定匹配器以选择多个 metric。例如,使用 {__name__=~”.*_count”},可以选择以 _count 结尾的多个 metric。

无效的选择器

在选择时序数据时,需要指定指标名称或无标签匹配的标签选择器。

因此,如果未指定指标名称为 {job=~”.*”} 或者 {hoge=””},则在表达式浏览器中会显示错误。

执行查询时出错:Y:X:解析错误:向量选择器必须包含至少一个非空匹配器。

范围向量选择器

区间向量是在某个时间点到过去一段时间内的实例向量值聚集的数据。

在这段时间内 [1m] 表示为类似的方式,并且这是一个范围向量选择器。
可用的单位如下所示。

s – seconds

m – minutes

h – hours

d – days

w – weeks

y – years

如果在表达式浏览器中显示 process_resident_memory_bytes[1m],将显示以下数据。
(由于范围向量无法在图表中显示,因此需要在控制台选项卡中查看)。

image.png
ElementValueprocess_resident_memory_bytes{instance=”localhost:9090″,job=”prometheus”}117702656 @1595670216.99
117702656 @1595670231.989
117702656 @1595670246.991
117702656 @1595670261.991process_resident_memory_bytes{instance=”localhost:9100″,job=”node”}22122496 @1595670213.37
22122496 @1595670228.369
22122496 @1595670243.368
22122496 @1595670258.368

可以看出,该值被赋予了一个时间戳为~@1595670216.99的值。
在一个Range vector中,数值的形式是Value @ Value被抓取的时间。
这里有4个数值是因为抓取间隔被设置为15秒,所以在1分钟内获取了4次值。

Range vector 的用途包括了例如了解每小时的平均内存使用量等。
※ 有关详细信息,请参阅 Range vector 的聚合函数。

偏移修饰符 zhě)

偏移修饰符是指将Instant vector或Range vector的时间向过去推移指定的时间量的修饰符。

<instant_query / sub_query> offset <duration>

如果使用 `process_resident_memory_bytes offset 1m`,那么前1分钟的`process_resident_memory_bytes`的值将会显示为当前时间。
从图表上看,如果没有指定offset,指定offset后会将其向右偏移1分钟。
换句话说,对于时间序列数据,每个时间点上都会加上由offset指定的值的影像。

使用偏移修饰符的情况包括在需要确定进程是否重新启动时,比较过去和现在的进程启动时间等。详细请参考示例。

子查询

通过在返回即时向量的查询中添加子查询,可以将查询转换为指定时间范围和指定分辨率的范围向量。

<instant_query> '[' <range> ':' [<resolution>] ']' [ offset <duration> ]

在以下场景中可以使用子查询:当需要知道在过去1天内进程重新启动了多少次时。
※详细信息请参考示例。

评论 (Paraphrase: 评论)

PromQL 支持注释功能。

# This is a comment

操作员

数学运算符

+ (addition)

– (subtraction)

* (multiplication)

/ (division)

% (modulo)

^ (power/exponentiation)

这些运算符的行为取决于左侧和右侧的数据类型。

    1. 只需一个选项,以下是中文的原生解释:

当两个操作数都是标量 (` `) 时,它的行为是如何的。
当一个操作数是瞬时向量,另一个操作数是标量 (` `) 时,它的行为是如何的。
当两个操作数都是瞬时向量 (` `) 时,它的行为是如何的。

当两侧为标量的情况下的行为

对于两个标量值,将进行算术运算。

举例来说,1加1等于2。

当一个边是瞬时向量,另一个边是标量时的行为。

即时向量的所有时间点的值都与标量值进行算术运算。

如果以 process_resident_memory_bytes / 1000 作为例,那么内存使用量将以 KB 而非字节作为单位。

当左右两边为瞬时向量时的行为。

对于左侧每个时间序列数据,将对与右侧匹配的元素执行算术操作。

从时间序列数据中得出的结果将删除指标名称,并为用于算术分组的标签添加到结果中。

例如,假设以 node_filesystem_avail_bytes 乘以 100 再除以 node_filesystem_size_bytes ,可以计算出磁盘使用率。

比较运算符

== (equal)

!= (not-equal)

> (greater-than)

< (less-than) >= (greater-or-equal)

<= (less-or-equal)

这些运算符的行为取决于左侧和右侧的数据类型。

    1. 当两边都是标量时的行为(<标量> <算术二元运算符> <标量>)

 

    1. 当一边是瞬时向量,另一边是标量时的行为(<瞬时向量> <算术二元运算符> <标量>)

 

    当两边都是瞬时向量时的行为(<瞬时向量> <算术二元运算符> <瞬时向量>)

无论哪种情况,基本行为都是过滤,但是通过在比较运算符后加上 bool 可以将值变为0或1。
(如果比较结果为假,则为0;如果为真,则为1)

<comparison_binary_operator> [bool]

当两边为标量时的行为

必须添加bool。

例如,当1 == 布尔值1时,结果为1;当1 != 布尔值1时,结果为0。

当一个边是瞬时向量,另一边是标量时的行为。

比较将在即时向量的所有时间点上进行,只有真值保留下来,假值将被删除。

如果把 process_resident_memory_bytes 设定为 89.1MB(即89.1 * 1000 * 1000),只有内存使用量大于89.1MB的时候才会被过滤掉。

image.png

当两边都是“即时向量”时的行为

在向量匹配中,对于进行匹配的元素进行比较。

逻辑运算符 / 集合运算符

    • and (intersection)

 

    • or (union)

 

    unless (complement)

这些运算符只能在瞬时向量之间使用。

在instant_vector1和instant_vector2的结果中,只有与instant_vector1的元素完全匹配以及与instant_vector2的元素的标签集完全匹配的元素会被保留下来。在这种情况下,指标名称和值将保留为instant_vector1的。

或者 的结果由 的所有元素以及 的元素中不具有与 匹配的标签集的元素组成。

除非 的结果是从 的元素中删除了与 元素和标签集匹配的部分。

在矢量匹配中,将对匹配的元素进行比较。

向量匹配

对于两个向量的操作,会查找匹配右侧元素的左侧元素。
匹配操作有两种行为:一对一匹配和一对多/多对一匹配。

一对一 (yī duì yī)

一对一的情况下,对每个标签进行标签匹配,匹配成功的标签将被匹配。

可以通过在on上对标签列表进行限制来忽略在ignoring上的标签。

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

请参考 Examples 来了解详情。

N对1 / 1对N

在N对1/1对N中,将某个标签进行分组,对其他所有标签进行标签匹配,找出匹配的标签。

<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>

请参考 Examples 来获取详细信息。

集約修飾子 means “intensive modifier” in Chinese.

sum (calculate sum over dimensions)

min (select minimum over dimensions)

max (select maximum over dimensions)

avg (calculate the average over dimensions)

group (all values in the resulting vector are 1)

stddev (calculate population standard deviation over dimensions)

stdvar (calculate population standard variance over dimensions)

count (count number of elements in the vector)

count_values (count number of elements with the same value)

bottomk (smallest k elements by sample value)

topk (largest k elements by sample value)

quantile (calculate φ-quantile (0 ≤ φ ≤ 1) over dimensions)

这些修饰符仅适用于即时向量。

如果没有指定「by」,结果中的所有标签都会被丢失。
对于通过指定标签进行过滤的元素,「by」会对它们分别进行聚合。
对于通过指定除了某个标签以外的其他标签进行过滤的元素,「without」会对它们分别进行聚合。

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

函数

在中文中,有定义了针对即时向量(instant vector)、范围向量(range vector)和标量执行处理的函数。

请参考此处的函数列表。

数学函数

関数名書式説明abs()abs(v instant-vector)全ての値を絶対値に変えるceil()ceil(v instant-vector)全ての値を、より大きく最も近い整数に変えるfloor()floor(v instant-vector)全ての値を、より小さく最も近い整数に変えるround()round(v instant-vector, to_nearest=1 scalar)全ての値を最も近い数値に変える。近さが等しい場合は大きい方になる。to_nearestを指定すると、その値の倍数で丸められる。clamp_max()clamp_max(v instant-vector, max scalar)max より大きい値を削除するclamp_min()clamp_min(v instant-vector, min scalar)min より小さい値を削除するln()ln(v instant-vector)全ての値の自然対数を計算するlog2()log2(v instant-vector)全ての値の 2 進対数を計算するlog10()log10(v instant-vector)全ての値の 10 進対数を計算するexp()exp(v instant-vector)全ての値の指数関数を計算するsqrt()sqrt(v instant-vector)全ての値の平方根を計算する

解析函数

関数名書式説明delta()delta(v range-vector)指定された範囲の最初と最後の値の差をもつ instant vector を返すidelta()idelta(v range-vector)指定された範囲の最後の2つの値の差をもつ instant vector を返すincrease()increase(v range-vector)指定した範囲の増加量をもつ instant vector を返すrate()rate(v range-vector)指定した範囲の1秒当たりの増加率をもつ instant vector を返すirate()irate(v range-vector)指定した範囲の末尾2つの値に基づき、1秒当たりの増加率をもつ instant vector を返すderiv()deriv(v range-vector)線形回帰を用いて秒単位での微分を返すpredict_linear()predict_linear(v range-vector, t scalar)線形回帰を用いて t 秒後の予測値を返すhistogram_quantile()histogram_quantile(φ float, b instant-vector)ヒストグラムのバケットbからφ-四分位(0 ≤ φ ≤ 1)を計算するholt_winters()holt_winters(v range-vector, sf scalar, tf scalar)Holt-Winters 法による平滑化値を生成する

集合向量的聚合函数

avg_over_time(range-vector): the average value of all points in the specified interval.

min_over_time(range-vector): the minimum value of all points in the specified interval.

max_over_time(range-vector): the maximum value of all points in the specified interval.

sum_over_time(range-vector): the sum of all values in the specified interval.

count_over_time(range-vector): the count of all values in the specified interval.

quantile_over_time(scalar, range-vector): the φ-quantile (0 ≤ φ ≤ 1) of the values in the specified interval.

stddev_over_time(range-vector): the population standard deviation of the values in the specified interval.

stdvar_over_time(range-vector): the population standard variance of the values in the specified interval.

排序函数

関数名書式説明sort()sort(v instant-vector)要素を値で昇順ソートするsort_desc()sort_desc(v instant-vector)要素を値で降順ソートする

判断函数

関数名書式説明absent()absent(v instant-vector)もし1つでも要素があれば空を返し、何も要素がなければ値が1の要素を返す。これは指定された条件の時系列データがないことを検知する場合に使う。absent_over_time()absent_over_time(v range-vector)もし1つでも要素があれば空を返し、何も要素がなければ値が1の要素を返す。これは指定された条件の時系列データがないことを検知する場合に使う。changes()changes(v range-vector)値の変化が起こった回数を返すresets()resets(v range-vector)指定された範囲内でのカウンタリセット回数をinstant vectorとして返す

补助系统函数

関数名書式説明days_in_month()days_in_month(v=vector(time()) instant-vector)値をUTC時刻とみなし、その月が何日あるか(28-31 の値)を返すminute()minute(v=vector(time()) instant-vector)値をUTC時刻とみなし、その時点が何分であるか(0-59 の値)を返すhour()hour(v=vector(time()) instant-vector)値をUTC時刻とみなし、その時点が何時であるか(0-23 の値)を返すmonth()month(v=vector(time()) instant-vector)値をUTC時刻とみなし、その時点が何月であるか(1-12 の値)を返すday_of_week()day_of_week(v=vector(time()) instant-vector)値を UTC 時刻とみなし、その週の曜日(0-6 の値)を返すday_of_month()day_of_month(v=vector(time()) instant-vector)値を UTC 時刻とみなし、その日の日付(1-31 の値)を返すyear()year(v=vector(time()) instant-vector)値を UTC 時刻とみなし、その時点が何年であるかを返すtime()time()UNIX time を返すtimestamp()timestamp(v instant-vector)timestamp を返すlabel_join()label_join(v instant-vector, dst_label string, separator string, src_label_1 string, src_label_2 string, …)src_label_X の各値を separator で結合した新しいラベル dst_label を追加するlabel_replace()label_replace(v instant-vector, dst_label string, replacement string, src_label string, regex string)src_label の値に対して正規表現 regex によるマッチングを行い、replacement で評価した値をもつ dst_label を追加するscalar()scalar(v instant-vector)1つの要素を与えた場合、その値の Scalar を返す。複数の要素が与えられた場合は NaN を返す。vector()vector(s scalar)Scalar の値をもつ instant vector を返す

例子

在可实施的例子中,Kubernetes(GKE)和便利的Prometheus小技巧集被介绍。

内存使用量

process_resident_memory_bytes

节点重新启动的发生与否

changes(node_boot_time_seconds[1m])

磁盘可用空间的比例

node_filesystem_avail_bytes * 100 / node_filesystem_size_bytes

气温

node_hwmon_temp_celsius * ignoring(label) group_left(label) node_hwmon_sensor_label

CPU的I/O等待比率

sum without(cpu)(rate(node_cpu_seconds_total{mode="iowait"}[5m])) # 1
/ ignoring(mode)                                                  # 2
sum without(mode, cpu)(rate(node_cpu_seconds_total[5m]))          # 3

1的结果中包含了标签mode.

{实例=”localhost:9100″,作业=”node”,模式=”iowait”}:1.9954526794454766

第三个结果中不包含标签“mode”。

{实例=”localhost:9100″,任务=”节点”}:1.998273690267743

因此,在使用「そのため」進行计算时,需要使用「ignoring」来排除mode标签。

结果不包括模式标签。

在一个小时内, 平均负载超过1的次数。

count_over_time((node_load1 > 1)[1h:])

考试准备

你怎么样检查度量标准?

让我们来研究一下出口商的规格要求。

如果已经有一个构建好的Prometheus,我们可以通过查看Targets来确定使用了哪个Exporter。

bannerAds