【0】介绍
Prometheus提供了一种称为PromQL(Prometheus查询语言)的功能查询语言,它使用户可以实时选择和汇总时间序列数据。
表达式的结果可以显示为图形,可以在Prometheus的表达式浏览器中显示为表格数据,也可以由外部系统通过HTTP API使用。
【1】表达式的类型
【1.1】4大基本类型
- Instant vector(向量) -一组时间序列,每个时间序列包含一个样本,所有样本共享相同的时间戳(简单理解:具体的采集指标的值)
- Range vector(向量)-一组时间序列,其中包含每个时间序列随时间变化的一系列数据点(简单理解:查看某个时间范围的数据)
- Scalar(标量) - 一个简单的数字浮点值(简答理解:数字)
- String -一个简单的字符串值;目前未使用
【1.2】Instant vector (即时向量选择器)
本示例选择所有具有 prometheus_http_requests_total 度量标准名称的时间序列:
prometheus_http_requests_total
包含这么多呢
过在花括号({}
)后面加上逗号分隔的标签匹配器列表,可以进一步过滤这些时间序列。
prometheus_http_requests_total{code="302",handler="/",instance="localhost:9090",job="prometheus"}
也可以:node_load1{job='agent_linux'} 是吧
【1.3】等于/不等于匹配符
=
:选择与提供的字符串完全相同的标签。!=
:选择不等于提供的字符串的标签。=~
:选择与提供的字符串进行正则表达式匹配的标签。!~
:选择与提供的字符串不进行正则表达式匹配的标签。
例如,此选择所有http_requests_total
的时间序列staging
, testing
以及development
环境和HTTP比其他方法GET
。
http_requests_total{environment=~"staging|testing|development",method!="GET"}
向量选择器必须指定一个名称或至少一个与空字符串不匹配的标签匹配器。以下表达式是非法的:
{job=~".*"} # Bad!
相反,这些表达式都是有效的,因为它们都具有与空标签值不匹配的选择器。
{job=~".+"} # Good!
{job=~".*",method="get"} # Good!
【1.4】range vector(范围向量选择器)
范围向量文字的工作方式与即时向量文字相同,不同之处在于它们从当前即时中选择了一系列样本。从句法上讲,范围持续时间附加在[]
向量选择器末尾的方括号()中,以指定应为每个结果范围向量元素提取多远的时间值。
持续时间指定为数字,紧随其后的是以下单位之一:
s
-秒m
- 分钟h
- 小时d
- 天w
-周y
-年
在此示例中,我们选择所有时间序列在过去5分钟内记录的所有值,这些时间序列的度量标准名称http_requests_total
和job
标签设置为prometheus
:
http_requests_total{job="prometheus"}[5m]
【1.5】Offset modifier(偏移量修改器)
所述offset
改性剂可以改变时间为查询中的个别时刻和范围矢量偏移。
例如,以下表达式返回http_requests_total
相对于当前查询评估时间的过去5分钟的值 :
http_requests_total offset 5m
请注意,offset
修饰符始终需要立即跟随选择器,即以下内容将是正确的:
sum(http_requests_total{method="GET"} offset 5m) // GOOD.
虽然以下是不正确的:
sum(http_requests_total{method="GET"}) offset 5m // INVALID.
范围向量的工作原理相同。这将返回http_requests_total
一周前的5分钟费率 :
rate(http_requests_total[5m] offset 1w)
【1.6】子查询
子查询允许您针对给定的范围和分辨率运行即时查询。子查询的结果是范围向量。
句法: <instant_query> '[' <range> ':' [<resolution>] ']' [ offset <duration> ]
<resolution>
是可选的。默认值为全局评估间隔
PromQL支持以开头的行注释 # this is a comment
【2】二元运算
【2.1】二元算数运算
Prometheus中存在以下二进制算术运算符:
+
(加成)-
(减法)*
(乘法)/
(师)%
(取模)^
(幂/幂)
(1)标量和向量
【标量】:就是数字 【向量】:就是采集指标得到的值
官网描述:
(我的理解:就是两个数字做操作,得到的也是一个数字)在两个标量之间,其行为显而易见:它们求值另一个标量,这是将运算符应用于两个标量操作数的结果。
(我的理解:就是采集指标下值可能有很多个,如果做 * 2操作,那么所有值都要 * 2)在瞬时向量和标量之间,将运算符应用于向量中每个数据样本的值。例如,如果时间序列瞬时向量乘以2,则结果是另一个向量,其中原始向量的每个样本值都乘以2。
(我的理解:就是两个采集指标下面均可能有多个值,如果相乘,那么就向左边的指标一一匹配相乘,没匹配到的就不显示)在两个即时向量之间,将二进制算术运算符应用于左侧向量中的每个条目,并将其 应用于右侧向量中的匹配元素。结果将传播到结果向量中,并且分组标签成为输出标签集。指标名称已删除。在右侧向量中找不到匹配条目的条目不属于结果。
【2.2】二元比较运算
在Prometheus系统中,比较二元操作符有:
==
等于!=
不等于>
大于<
小于>=
大于等于<=
小于等于
两个数字之间:变成 bool 来做比较,结果返回 0 或者 1,即真 或者 假
数字和指标之间:把这个比较应用于指标中的每个值。
【2.3】二元逻辑运算
逻辑/集合二元操作符只能作用在即时向量, 包括:
and
交集or
并集unless
补集
并交补就不用说了吧。
vector1 and vector2
得到一个由vector1
元素组成的向量,其中vector2
中的元素具有完全匹配的标签集。 其他元素被删除。 度量标准名称和值从左侧向量转移
vector1 or vector2
得到包含vector1
的所有原始元素(标签集+值)的向量以及vector2
中vector1
中没有匹配标签集的所有元素。。
vector1 unless vector2
得到一个由vector1
元素组成的向量,其中vector2
中没有元素,具有完全匹配的标签集。 两个向量中的所有匹配元素
【2.4】聚合操作符
Prometheus支持以下内置聚合运算符,这些运算符可用于聚合单个即时向量的元素,从而生成具有聚合值的较少元素的新向量:
sum
(在维度上求和)max
(在维度上求最大值)min
(在维度上求最小值)avg
(在维度上求平均值)stddev
(求标准差)stdvar
(求方差)count
(统计向量元素的个数)count_values
(统计相同数据值的元素数量)bottomk
(样本值第k个最小值)topk
(样本值第k个最大值)quantile
(统计分位数)
这些运算符可以用于聚合所有标签维度,也可以通过包含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)
【2.5】二元运算符的优先级
以下列表显示了Prometheus中二进制运算符的优先级,从最高到最低。
- ^
- *, /, %
- +, -
- ==, !=, <=, <, >=, >
- and, unless
- or
具有相同优先级的运算符是左关联的。 例如,2 * 3%2
相当于(2 * 3)%2
。但是^
是右关联的,因此2 ^ 3 ^ 2
相当于2 ^(3 ^ 2)
。