Prometheus 查询语言
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Prometheus 查询语言相关的知识,希望对你有一定的参考价值。
参考技术A[TOC]
PromQL(Prometheus Query Language)是 Prometheus 自己开发的表达式语言,语言表现力很丰富,内置函数也很多。使用它可以对时序数据进行筛选和聚合。
PromQL 表达式计算出来的值有以下几种类型:
瞬时向量选择器用来选择 一组时序在某个采样点的采样值 。
最简单的情况就是指定一个度量指标,选择出所有属于该度量指标的时序的当前采样值。比如下面的表达式:
可以通过在后面添加用大括号包围起来的一组标签键值对来对时序进行过滤。比如下面的表达式筛选出了 job 为 prometheus ,并且 group 为 canary 的时序:
匹配标签值时可以是 等于 ,也可以 使用正则表达式 。总共有下面几种匹配操作符:
下面的表达式筛选出了 environment 为 staging 或 testing 或 development,并且 method 不是 GET 的时序:
度量指标名可以使用内部标签 __name__ 来匹配,表达式 http_requests_total 也可以写成 __name__="http_requests_total" 。表达式 __name__=~"job:.*" 匹配所有度量指标名称以 job: 打头的时序。
区间向量选择器类似于瞬时向量选择器,不同的是它选择的是 过去一段时间的采样值 。可以通过在瞬时向量选择器后面添加包含在 [] 里的时长来得到区间向量选择器。比如下面的表达式选出了所有度量指标为 http_requests_total 且 job 为 prometheus 的时序在过去 5 分钟的采样值。
说明:时长的单位可以是下面几种之一:
前面介绍的选择器默认都是以当前时间为基准时间,偏移修饰器用来调整基准时间,使其往前偏移一段时间。偏移修饰器紧跟在选择器后面,使用 offset 来指定要偏移的量。比如下面的表达式选择度量名称为 http_requests_total 的所有时序在 5 分钟前的采样值。
下面的表达式选择 http_requests_total 度量指标在 1 周前的这个时间点过去 5 分钟的采样值。
PromQL 的二元操作符支持基本的逻辑和算术运算,包含 算术类 、 比较类 和 逻辑类 三大类。
算术类二元操作符有以下几种:
算术类二元操作符可以使用在标量与标量、向量与标量,以及向量与向量之间。
二元操作符上下文里的向量特指瞬时向量,不包括区间向量。
比较类二元操作符有以下几种:
比较类二元操作符同样可以使用在标量与标量、向量与标量,以及向量与向量之间。默认执行的是过滤,也就是保留值。
也可以通过在运算符后面跟 bool 修饰符来使得返回值 0 和 1,而不是过滤。
逻辑操作符仅用于向量与向量之间。
具体运算规则如下:
PromQL 的各类二元操作符运算优先级如下:
前面算术类和比较类操作符都需要在向量之间进行匹配。共有两种匹配类型, one-to-one 和 many-to-one / one-to-many 。
这种匹配模式下,两边向量里的元素如果其标签键值对组合相同则为匹配,并且只会有一个匹配元素。可以使用 ignoring 关键词来忽略不参与匹配的标签,或者使用 on 关键词来指定要参与匹配的标签。语法如下:
比如对于下面的输入:
执行下面的查询:
得到的结果为:
也就是每一种 method 里 code 为 500 的请求数占总数的百分比。由于 method 为 put 和 del 的没有匹配元素所以没有出现在结果里。
这种匹配模式下,某一边会有多个元素跟另一边的元素匹配。这时就需要使用 group_left 或 group_right 组修饰符来指明哪边匹配元素较多,左边多则用 group_left ,右边多则用 group_right 。其语法如下:
组修饰符只适用于算术类和比较类操作符。
对于前面的输入,执行下面的查询:
将得到下面的结果:
也就是每种 method 的每种 code 错误次数占每种 method 请求数的比例。这里匹配的时候 ignoring 了 code,才使得两边可以形成 Many-to-one 形式的匹配。由于左边多,所以需要使用 group_left 来指明。
Many-to-one / one-to-many 过于高级和复杂,要尽量避免使用。很多时候通过 ignoring 就可以解决问题。
PromQL 的聚合操作符用来将向量里的元素聚合得更少。总共有下面这些聚合操作符:
聚合操作符语法如下:
其中 without 用来指定不需要保留的标签(也就是这些标签的多个值会被聚合),而 by 正好相反,用来指定需要保留的标签(也就是按这些标签来聚合)。
下面来看几个示例:
http_requests_total 度量指标带有 application、instance 和 group 三个标签。上面的表达式会得到每个 application 的每个 group 在所有 instance 上的请求总数。效果等同于下面的表达式:
下面的表达式可以得到所有 application 的所有 group 的所有 instance 的请求总数。
Prometheus 内置了一些函数来辅助计算,下面介绍一些典型的。
Prometheus学习系列之Prometheus 查询说明
前言
本文来自Prometheus官网手册和 Prometheus简介
Prothetheus查询
一、例子
本文档仅供参考, 对于学习,从几个例子开始可能更容易。
二、表达式语言数据类型
在Prometheus的表达式语言中,任何表达式或者子表达式都可以归为四种类型:
instant vector
瞬时向量:它是指在同一时刻,抓取的所有度量指标数据。这些度量指标数据的key都是相同的,也即相同的时间戳range vector
范围向量:它是指在任何一个时间范围内,抓取的所有度量指标数据scalar
标量:一个简单的浮点值string
字符串:一个当前没有被使用的简单字符串
三、字面量
3.1 字符串字面量
字符串可以用单引号,双引号或反引号指定为文字。PromQL遵循与Go相同的转义规则。在单引号,双引号中,反斜杠成为了转义字符,后面可以跟着a
,b
, f
, n
, r
, t
, v
或者。 可以使用八进制(
nn
)或者十六进制(xnn
, unnnn
和Unnnnnnnn
)提供特定字符。在反引号内不处理转义字符。与Go不同,Prometheus不会丢弃反引号中的换行符。例如:
"this is a string" ‘these are unescaped: \ ‘ `these are not unescaped: ‘ " "‘`
3.2 浮点数字面量
标量浮点值可以直接写成形式[-](digits)[.(digits)]
。
-2.43
四、时间序列选择器
4.1 瞬时向量选择器
瞬时向量选择器允许在给定时间戳(即时)为每个选择一组时间序列和单个样本值:在最简单的形式中,仅指定度量名称。 这会生成包含具有此度量标准名称的所有时间序列的元素的即时向量。
下面这个例子选择所有时间序列度量名称为http_requests_total
的样本数据:
http_requests_total
通过在度量指标后面增加{}一组标签可以进一步地过滤这些时间序列数据。
此示例仅选择具有http_requests_total
度量标准名称的时间系列,该名称也将job标签设置为prometheus
,并将其group
标签设置为canary
:
http_requests_total{job="prometheus",group="canary"}
可以采用不匹配的标签值也是可以的,或者用正则表达式不匹配标签。标签匹配操作如下所示:
=
: 精确地匹配标签给定的值!=
: 不等于给定的标签值=~
: 正则表达匹配给定的标签值!~
: 给定的标签值不符合正则表达式
例如:度量指标名称为http_requests_total
,正则表达式匹配标签environment
为staging, testing, development
的值,且http请求方法不等于GET
。
http_requests_total{environment=~"staging|testing|development",method!="GET"}
匹配空标签值的标签匹配器也可以选择没有设置任何标签的所有时间序列数据。正则表达式完全匹配。 可以为同一标签名称提供多个匹配器。
向量选择器必须指定一个名称或至少一个与空字符串不匹配的标签匹配器。 以下表达式是非法的:
{job=~".*"} # Bad!
相反,这些表达式是有效的,因为它们都有一个与空标签值不匹配的选择器。
{job=~".+"} # Good! {job=~".*",method="get"} # Good!
__name__
标签筛选度量指标名称。例如:表达式http_requests_total
等价于{__name__="http_requests_total"}
。 其他的匹配器,如:= ( !=, =~, !~)
都可以使用。下面的表达式选择了度量指标名称以job:
开头的时间序列数据:{__name__=~"job:.*"}
Prometheus中的所有正则表达式都使用RE2语法。
4.2 范围向量选择器
范围向量的工作方式与即时向量相同,不同之处在于它们从当前即时选择回采样范围。 在语法上,范围持续时间附加在向量选择器末尾的方括号([]
)中,指定为每个结果范围向量元素提取多长时间值。持续时间指定为数字,单位为:
s
- secondsm
- minutesh
- hoursd
- daysw
- weeksy
- years
在此示例中,我们选择在过去5分钟内为度量标准名称为http_requests_total
且job
标签设置为prometheus
的所有时间序列记录的所有值:
http_requests_total{job="prometheus"}[5m]
4.3 偏移修饰符
这个offset
偏移修饰符允许在查询中改变单个瞬时向量和范围向量中的时间偏移。例如,以下表达式返回过去相对于当前查询评估时间5分钟的http_requests_total
值:
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)
五、子查询
子查询允许针对给定范围和分辨率运行即时查询。 子查询的结果是范围向量。
语法:<instant_query>‘[‘<range>‘:‘[<resolution>]‘]‘[offset <duration>]
<resolution>
是可选的。 默认值是全局评估间隔。
六、操作符
Prometheus支持二元和聚合操作符。详见表达式语言操作符
七、函数
Prometheus提供了一些函数列表操作时间序列数据。详见表达式语言函数
八、注释
PromQL支持以#开头的行注释。 如:
#这是一条评论
九、陷阱
9.1 旧数据
运行查询时,独立于当前时间序列的数据选择采样数据的时间戳。这主要是为了支持聚合(总和,平均等)这样的情况,其中多个聚合时间序列在时间上不完全对齐。由于它们的独立性,Prometheus需要在每个相关时间序列的时间戳上分配值。它只需在此时间戳之前采用最新的样本即可。
如果目标抓取或规则评估不再返回先前存在的时间序列的样本,则该时间序列将被标记为旧数据。如果目标被移除,之前很快就会将其先前返回的时间序列标记为旧数据。
如果在时间序列标记为过时后,在采样时间戳处评估查询,则不会为该时间系列返回任何值。如果随后在该时间序列中摄取新样本,它们将照常返回。
如果在采样时间戳前5分钟未找到任何样本(默认情况下),则此时间点不返回该时间序列的值。这实际上意味着时间序列在其最新收集的样本超过5分钟或标记为旧数据之后从图表“消失”。对于在其抓取中包含时间戳的时间序列,不会标记旧数据。在这种情况下,仅应用5分钟的阈值。
9.2 避免慢查询和过载
如果查询需要对大量数据进行操作,则绘制图表可能会超时或使服务器或浏览器过载。因此,在构建对未知数据的查询时,始终在Prometheus表达式浏览器的表格视图中开始构建查询,直到结果集看起来合理(最多数百个,而不是数千个时间序列)。只有在您充分过滤或汇总数据后,才能切换到图表模式。如果表达式仍然需要很长时间来绘制ad-hoc图形,请通过录制规则预先录制它。
这与Prometheus的查询语言尤其相关,其中像api_http_requests_total
这样的简单度量标准名称选择器可以扩展到具有不同标签的数千个时间序列。还要记住,即使输出只是少量的时间序列,聚合在许多时间序列上的表达式也会在服务器上产生负载。这类似于在关系数据库中对列的所有值求和的速度很慢,即使输出值只是一个数字。
以上是关于Prometheus 查询语言的主要内容,如果未能解决你的问题,请参考以下文章
#yyds干货盘点#Prometheus 之 PromQL 介绍