查看 Prometheus
Prometheus 提供了一种名为 PromQL 的函数式查询语言,可以让用户实时选择和聚合时间序列数据。表达式的结果可以显示为图形,在 Prometheus 的表达式浏览器中查看为表格数据,也可以通过 HTTP API 由外部系统使用。
表达式语言数据类型
在 Prometheus 的表达式语言中,表达式或子表达式可以计算为以下四种类型之一:
- 即时向量(
instant vector
): 一组时间序列,包含每个时间序列的单个样本,所有时间序列都共享相同的时间戳; - 范围向量(
range vector
): 一组时间序列,包含每个时间序列随时间变化的数据点范围; - 标量(
Scalar
): 一个简单的数字浮点值; - 字符串(
String
): 一个简单的字符串值;目前未使用。
时间序列选择器
即时向量选择器(Instant vector selectors)
即时向量选择器允许在给定的时间戳(即时)选择一组时间序列和单个样本值:在最简单的示例中,只指定一个度量名称。这会产生一个包含所有具有此度量名称的时间序列元素的即时向量。
选择具有
prometheus_http_requests_total
指标名称的所有时间序列1
prometheus_http_requests_total
通过在花括号(
{}
)中附加以逗号分隔的标签匹配器列表,可以进一步过滤这些时间序列。1
prometheus_http_requests_total{job="prometheus", code="200"}
以下是可用的标签匹配运算符
=
: 选择与提供的字符串完全相同的标签;!=
: 选择不等于提供的字符串的标签;=~
: 选择与提供的字符串正则表达式匹配的标签;!~
: 选择与提供的字符串不匹配的标签;
示例,这里选择所有
http_requests_total
时间序列用于暂存,测试和开发环境以及除 GET 之外的 HTTP 方法。1
http_requests_total{environment=~"staging|testing|development", method!="GET"}
匹配空标签值的标签匹配器还会选择根本没有设置特定标签的所有时间序列。正则表达式匹配是完全锚定的。同一个标签名称可以有多个匹配器。
向量选择器必须指定一个名称或至少一个与空字符串不匹配的标签匹配器。以下表达式是错误的:
1
{job=~".*"} # Bad!
相反,这些表达式是有效的,因为它们都有一个不匹配空标签值的选择器。
1
2{job=~".+"} # Good!
{job=~".*",method="get"} # Good!通过与内部
__name__
标签进行匹配,标签匹配器也可以应用于度量标准名称。例如,表达式http_requests_total
等价于{__name__ = "http_requests_total"}
。也可以使用除=(!=,=~,!~)
以外的匹配器。以下表达式选择名称以 prome 开头的所有指标。1
{__name__ =~ "prome.*"}
指标名称不能是关键字
bool
,on
,ignoring
,group_left
和group_right
之一。以下表达式是错误的1
on{} # Bad!
要想使用关键字作为指标名称查询,需要使用
__name__
标签1
{__name__="on"} # Good
范围向量选择器(Range Vector Selectors)
范围向量 literals
的工作方式与即时向量 literals
类似,不同之处在于它们从当前时刻选择了一系列样本。从语法上讲,持续时间在向量选择器的末尾附加在方括号 ([]
) 中,以指定应该为每个结果范围向量元素提取多远的时间值。
在此示例中,我们为所有具有指标名称
prometheus_http_requests_total
和设置为 prometheus 的作业标签的时间序列选择我们在过去 5 分钟内记录的所有值1
prometheus_http_requests_total{job="prometheus"}[5m]
持续时间
持续时间指定为数字,紧随其后的是以下单位之一:
- ms: 毫秒
- s: 秒
- m: 分
- h: 时
- d: 天,一天为 24 小时
- w: 周,一周为 7 天
- y: 年,一年为 365 天
持续时间可以通过串联来组合。单位必须按从最长到最短的顺序排列。给定的单位在一段时间内只能出现一次。以下是一些有效持续时间的示例:
1 | 5h |
偏移和修改
偏移 offset
偏移修饰符允许更改查询中单个瞬时和范围向量的时间偏移。
例如,以下表达式返回相对于当前查询评估时间过去 5 分钟的
http_requests_total
值:1
http_requests_total offset 5m
- 请注意,偏移修饰符始终需要立即跟随选择器,如下
1
sum(http_requests_total{method="GET"} offset 5m) // GOOD.
- 以下内容是错误的
1
sum(http_requests_total{method="GET"}) offset 5m // INVALID.
- 这同样适用于范围向量。这将返回
http_requests_total
一周前的 5 分钟速率
1
rate(http_requests_total[5m] offset 1w)
- 为了与时间上的时间前移进行比较,可以指定负偏移量
1
rate(http_requests_total[5m] offset -1w)
通过设置
--enable-feature = promql-negative-offset
标志来启用此功能。有关此标志的更多详细信息,请参阅禁用的功能。
修改
@
修饰符允许更改查询中单个即时和范围向量的评估时间。提供给 @
修饰符的时间是一个 unix 时间戳并用浮点文字描述。
例如,以下表达式返回
2021-01-04T07:40:00 +00:00
的http_requests_total
的值:1
http_requests_total @ 1609746000
- 请注意,
@
修饰符总是需要立即跟随选择器,即以下是正确的:
1
sum(http_requests_total{method="GET"} @ 1609746000) // GOOD.
- 以下内容是不正确的:
1
sum(http_requests_total{method="GET"}) @ 1609746000 // INVALID.
- 这同样适用于范围向量。这将返回
http_requests_total
在2021-01-04T07:40:00+00:00
的 5 分钟速率:
1
rate(http_requests_total[5m] @ 1609746000)
@
修饰符支持上述 int64 限制内的所有浮点文字表示。它也可以与偏移修饰符一起使用,其中偏移是相对于@
修饰符时间应用的,而不管哪个修饰符首先被写入。这两个查询将产生相同的结果。
1
2
3
4
5# offset after @
http_requests_total @ 1609746000 offset 5m
# offset before @
http_requests_total offset 5m @ 1609746000默认情况下禁用此修饰符,因为它打破了 PromQL 不会提前评估样本的不变性。可以通过设置
--enable-feature=promql-at-modifier
标志来启用它。有关此标志的更多详细信息,请参阅禁用的功能。- 此外,
start()
和end()
也可以用作@
修饰符的值作为特殊值。对于范围查询,它们分别解析为范围查询的开始和结束,并在所有步骤中保持不变。
1
2
3# 对于即时查询, start() 和 end() 都解析为评估时间。
http_requests_total @ start()
rate(http_requests_total[5m] @ end())- 请注意,
子查询
子查询允许您对给定的范围和分辨率运行即时查询。子查询的结果是一个范围向量。语法如下:
1 | <instant_query> '[' <range> ':' [<resolution>] ']' [ @ <float_literal> ] [ offset <duration> ] |
<resolution>
是可选的。默认为全局评估区间。
二元运算符
Prometheus 的查询语言支持基本的逻辑和算术运算符。对于两个瞬时向量之间的操作,可以修改匹配行为。
算术二元运算符
Prometheus 中存在以下二元算术运算符
+
: 加-
: 减*
: 乘/
: 除%
: 取余^
: 求幂
比较二元运算符
Prometheus 中存在以下二元比较运算符:
==
: 等于!=
: 不等于>
: 大于<
: 小于>=
: 大于等于<=
: 小于等于
逻辑/设置二元运算符
这些逻辑/集合二进制运算符仅在即时向量之间定义
and
or
unless
聚合运算符
Prometheus 支持以下内置聚合运算符,可用于聚合单个即时向量的元素,从何生成具有聚合值得更少元素的新向量:
sum
: 计算维度总和min
: 选择最小值max
: 选择最大值avg
: 计算维度的平均值group
: 结果向量中的所有值都是 1stddev
: 计算维度上的总体标准差stdvar
: 计算维度上的总体标准方差count
: 计算向量中元素的数量count_values
: 计算具有相同值的元素的数量bottomk
: 样本值的最小的 k 个元素topk
: 样本值最大的 k 个元素quantile
: 在维度上计算分位数 (0 ≤ φ ≤ 1
)
这些运算符既可用于聚合所有标签维度,也可通过包含 without
或 by
子句来保留不同的维度。这些子句可以在表达式之前或之后使用。如下
1 | <aggr-op> [without|by (<label list>)] ([parameter,] <vector expression>) |
- 标签列表是一个未加引号的标签列表,其中可能包含一个尾随逗号,即 (label1, label2) 和 (label1, label2,) 都是有效的语法。
without
从结果向量中删除列出的标签,而所有其他标签都保留在输出中。by
执行相反的操作并删除未在by
子句中列出的标签,即使它们的标签值在向量的所有元素之间都相同。- 只有
count_values
、quantile
、topk
和bottomk
需要此参数。 count_values
为每个唯一样本值输出一个时间序列。每个系列都有一个附加标签。该标签的名称由聚合参数给出,标签值是唯一的样本值。每个时间序列的值是样本值出现的次数。topk
和bottomk
与其他聚合器的不同之处在于,在结果向量中返回输入样本的子集,包括原始标签。by
和without
仅用于对输入向量进行分桶。quantile
计算φ-quantile
,即在聚合维度的 N 个度量值中排名第φ*N
的值。φ
作为聚合参数提供。例如,quantile(0.5, ...)
计算中位数,quantile(0.95, ...)
计算第 95 个百分位数。
示例
如果指标
http_requests_total
具有按应用程序、实例和组标签扇出的时间序列,我们可以通过以下方式计算每个应用程序和组在所有实例上看到的 HTTP 请求总数:1
sum without (instance) (http_requests_total)
这相等同于以下表达式
1
sum by (application, group) (http_requests_total)
如果我们只对我们在所有应用程序中看到的 HTTP 请求总数感兴趣,我们可以简单地编写
1
sum(http_requests_total)
要计算运行每个构建版本的二进制文件的数量,我们可以编写:
1
count_values("version", build_version)
要在所有实例中获得 5 个最大的 HTTP 请求数,我们可以编写:
1
topk(5, http_requests_total)
二元运算符优先级
下面的列表显示了 Prometheus 中二元运算符的优先级,从高到低
1 | 1. ^ |
相同优先级的运算符是左结合的。例如,
2 * 3 % 2
等价于(2 * 3) % 2
。但是^
是右结合的,所以2 ^ 3 ^ 2
等价于2 ^ (3 ^ 2)
。