PromQL(Prometheus Query Language)是 Prometheus 自己开发的表达式语言,语言表现力很丰富,内置函数也很多。使用它可以对时序数据进行筛选和聚合。

1- PromQL 语法

1.1- 数据类型

PromQL 表达式计算出来的值有以下几种类型:

  1. 瞬时向量 (Instant vector): 一组时序,每个时序只有一个采样值
  2. 区间向量 (Range vector): 一组时序,每个时序包含一段时间内的多个采样值
  3. 标量数据 (Scalar): 一个浮点数
  4. 字符串 (String): 一个字符串,暂时未用

1.2- 时序选择器

1.2.1- 瞬时向量选择器

瞬时向量选择器用来选择一组时序在某个采样点的采样值。

最简单的情况就是指定一个度量指标,选择出所有属于该度量指标的时序的当前采样值。比如下面的表达式:

http_requests_total

可以通过在后面添加用大括号包围起来的一组标签键值对来对时序进行过滤。比如下面的表达式筛选出了 job 为 prometheus,并且 group 为 canary 的时序:

http_requests_total{job="prometheus", group="canary"}

匹配标签值时可以是等于,也可以使用正则表达式。总共有下面几种匹配操作符:

  1. =:完全相等
  2. !=: 不相等
  3. =~: 正则表达式匹配
  4. !~: 正则表达式不匹配

下面的表达式筛选出了 environment 为 staging 或 testing 或 development,并且 method 不是 GET 的时序:

http_requests_total{environment=~"staging|testing|development",method!="GET"}

度量指标名可以使用内部标签 name 来匹配,表达式 http_requests_total 也可以写成 {name="http_requests_total"}。表达式 {name=~"job:.*"} 匹配所有度量指标名称以 job: 打头的时序。

1.2.2- 区间向量选择器

区间向量选择器类似于瞬时向量选择器,不同的是它选择的是过去一段时间的采样值。可以通过在瞬时向量选择器后面添加包含在 [] 里的时长来得到区间向量选择器。比如下面的表达式选出了所有度量指标为 http_requests_total 且 job 为 prometheus 的时序在过去 5 分钟的采样值。

http_requests_total{job="prometheus"}[5m]
说明:时长的单位可以是下面几种之一:
  1. s:seconds
  2. m:minutes
  3. h:hours
  4. d:days
  5. w:weeks
  6. y:years

1.2.3- 偏移修饰器

前面介绍的选择器默认都是以当前时间为基准时间,偏移修饰器用来调整基准时间,使其往前偏移一段时间。偏移修饰器紧跟在选择器后面,使用 offset 来指定要偏移的量。比如下面的表达式选择度量名称为 http_requests_total 的所有时序在 5 分钟前的采样值。

http_requests_total offset 5m

下面的表达式选择 http_requests_total 度量指标在 1 周前的这个时间点过去 5 分钟的采样值。

http_requests_total[5m] offset 1w

2- PromQL 操作符

2.1- 二元操作符

PromQL 的二元操作符支持基本的逻辑和算术运算,包含算术类、比较类和逻辑类三大类。

2.1.1- 算术类二元操作符

算术类二元操作符有以下几种:

  1. +:加
  2. -:减
  3. *:乘
  4. /:除
  5. %:求余
  6. ^:乘方

算术类二元操作符可以使用在标量与标量、向量与标量,以及向量与向量之间。

二元操作符上下文里的向量特指瞬时向量,不包括区间向量。

  1. 标量与标量之间,结果很明显,跟通常的算术运算一致。
  2. 向量与标量之间,相当于把标量跟向量里的每一个标量进行运算,这些计算结果组成了一个新的向量。
  3. 向量与向量之间,会稍微麻烦一些。运算的时候首先会为左边向量里的每一个元素在右边向量里去寻找一个匹配元素(匹配规则后面会讲),然后对这两个匹配元素执行计算,这样每对匹配元素的计算结果组成了一个新的向量。如果没有找到匹配元素,则该元素丢弃。

2.1.2- 比较类二元操作符

比较类二元操作符有以下几种:

  1. == (equal)
  2. != (not-equal)
  3. > (greater-than)
  4. < (less-than)
  5. >= (greater-or-equal)
  6. <= (less-or-equal)

比较类二元操作符同样可以使用在标量与标量、向量与标量,以及向量与向量之间。默认执行的是过滤,也就是保留值。

也可以通过在运算符后面跟 bool 修饰符来使得返回值 0 和 1,而不是过滤。

  1. 标量与标量之间,必须跟 bool 修饰符,因此结果只可能是 0(false) 或 1(true)。
  2. 向量与标量之间,相当于把向量里的每一个标量跟标量进行比较,结果为真则保留,否则丢弃。如果后面跟了 bool 修饰符,则结果分别为 1 和 0。
  3. 向量与向量之间,运算过程类似于算术类操作符,只不过如果比较结果为真则保留左边的值(包括度量指标和标签这些属性),否则丢弃,没找到匹配也是丢弃。如果后面跟了 bool 修饰符,则保留和丢弃时结果相应为 1 和 0。

2.1.3- 逻辑类二元操作符

逻辑操作符仅用于向量与向量之间。

  1. and:交集

  2. or:合集

  3. unless:补集

    具体运算规则如下:

  4. vector1 and vector2 的结果由在 vector2 里有匹配(标签键值对组合相同)元素的 2. vector1 里的元素组成。

  5. vector1 or vector2 的结果由所有 vector1 里的元素加上在 vector1 里没有匹配(标签键值对组合相同)元素的 vector2 里的元素组成。

  6. vector1 unless vector2 的结果由在 vector2 里没有匹配(标签键值对组合相同)元素的 vector1 里的元素组成。

2.1.4- 二元操作符优先级

PromQL 的各类二元操作符运算优先级如下:

  1. ^
  2. *, /, %
  3. +, -
  4. ==, !=, <=, <, >=, >
  5. and, unless
  6. or

2.2- 向量匹配

前面算术类和比较类操作符都需要在向量之间进行匹配。共有两种匹配类型,one-to-one 和 many-to-one / one-to-many。

2.2.1- One-to-one 向量匹配

这种匹配模式下,两边向量里的元素如果其标签键值对组合相同则为匹配,并且只会有一个匹配元素。可以使用 ignoring 关键词来忽略不参与匹配的标签,或者使用 on 关键词来指定要参与匹配的标签。语法如下:

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

比如对于下面的输入:

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="500"} 6
method_code:http_errors:rate5m{method="post", code="404"} 21 method:http_requests:rate5m{method="get"} 600
method:http_requests:rate5m{method="del"} 34
method:http_requests:rate5m{method="post"} 120

执行下面的查询:

method_code:http_errors:rate5m{code="500"} / ignoring(code) method:http_requests:rate5m

得到的结果为:

{method="get"}  0.04            //  24 / 600
{method="post"} 0.05 // 6 / 120

也就是每一种 method 里 code 为 500 的请求数占总数的百分比。由于 method 为 put 和 del 的没有匹配元素所以没有出现在结果里。

2.2.2- Many-to-one / one-to-many 向量匹配

这种匹配模式下,某一边会有多个元素跟另一边的元素匹配。这时就需要使用 group_left 或 group_right 组修饰符来指明哪边匹配元素较多,左边多则用 group_left,右边多则用 group_right。其语法如下:

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

组修饰符只适用于算术类和比较类操作符。

对于前面的输入,执行下面的查询:

method_code:http_errors:rate5m / ignoring(code) group_left method:http_requests:rate5m

将得到下面的结果:

{method="get", code="500"}  0.04            //  24 / 600
{method="get", code="404"} 0.05 // 30 / 600
{method="post", code="500"} 0.05 // 6 / 120
{method="post", code="404"} 0.175 // 21 / 120

也就是每种 method 的每种 code 错误次数占每种 method 请求数的比例。这里匹配的时候 ignoring 了 code,才使得两边可以形成 Many-to-one 形式的匹配。由于左边多,所以需要使用 group_left 来指明。

Many-to-one / one-to-many 过于高级和复杂,要尽量避免使用。很多时候通过 ignoring 就可以解决问题。

2.3- 聚合操作符

PromQL 的聚合操作符用来将向量里的元素聚合得更少。总共有下面这些聚合操作符:

  1. sum:求和
  2. min:最小值
  3. max:最大值
  4. avg:平均值
  5. stddev:标准差
  6. stdvar:方差
  7. count:元素个数
  8. count_values:等于某值的元素个数
  9. bottomk:最小的 k 个元素
  10. topk:最大的 k 个元素
  11. quantile:分位数

聚合操作符语法如下:

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

其中 without 用来指定不需要保留的标签(也就是这些标签的多个值会被聚合),而 by 正好相反,用来指定需要保留的标签(也就是按这些标签来聚合)。

下面来看几个示例:

sum(http_requests_total) without (instance)

http_requests_total 度量指标带有 application、instance 和 group 三个标签。上面的表达式会得到每个 application 的每个 group 在所有 instance 上的请求总数。效果等同于下面的表达式:

sum(http_requests_total) by (application, group)

下面的表达式可以得到所有 application 的所有 group 的所有 instance 的请求总数。

sum(http_requests_total)

3- 函数

Prometheus 内置了一些函数来辅助计算,下面介绍一些典型的。

  1. abs():绝对值
  2. sqrt():平方根
  3. exp():指数计算
  4. ln():自然对数
  5. ceil():向上取整
  6. floor():向下取整
  7. round():四舍五入取整
  8. delta():计算区间向量里每一个时序第一个和最后一个的差值
  9. sort():排序

Prometheus的查询语法是PromQL基本语法的更多相关文章

  1. .NET Core使用EF分页查询数据报错:OFFSET语法错误问题

    在Asp.Net Core MVC项目中使用EF分页查询数据时遇到一个比较麻烦的问题,系统会报如下错误: 分页查询代码: ) * condition.PageSize).Take(condition. ...

  2. LINQ语法类似于SQL的语法

    LINQ语法类似于SQL的语法如下, Models.BookStoreEntities 是从添加新建项中的数据--->ADO.NET实体数据模型--->从数据库生成--->使用5.0 ...

  3. 7.prometheus之查询API

    一.格式概述 二.表达式查询 2.1 Instant queries(即时查询) 2.2 范围查询 三.查询元数据 3.1 通过标签匹配器找到度量指标列表 3.2 获取标签名 3.3 查询标签值 四. ...

  4. MySQL(九)之数据表的查询详解(SELECT语法)二

    上一篇讲了比较简单的单表查询以及MySQL的组函数,这一篇给大家分享一点比较难得知识了,关于多表查询,子查询,左连接,外连接等等.希望大家能都得到帮助! 在开始之前因为要多表查询,所以搭建好环境: 1 ...

  5. MySQL(九)之数据表的查询详解(SELECT语法)一

    这一篇是MySQL中的重点也是相对于MySQL中比较难得地方,个人觉得要好好的去归类,并多去练一下题目.MySQL的查询也是在笔试中必有的题目.希望我的这篇博客能帮助到大家! 重感冒下的我,很难受!k ...

  6. jpa 联表查询 返回自定义对象 hql语法 原生sql 语法 1.11.9版本

    -----业务场景中经常涉及到联查,jpa的hql语法提供了内连接的查询方式(不支持复杂hql,比如left join ,right join).  上代码了 1.我们要联查房屋和房屋用户中间表,通过 ...

  7. sql查询语句for xml path语法

    [原地址] for xml path作用:将多行的查询结果,根据某一些条件合并到一行. 例:现有一张表 执行下面语句 select Department, (SELECT Employee+',' F ...

  8. Promql基础语法2

    数据样本 直方图类型 delta函数 运算操作 数学运算 node_disk_info / 100 当瞬时向量与标量之间进行数学运算时,数学运算符会依次作用域瞬时向量中的每一个样本值,从而得到一组新的 ...

  9. Prometheus监控学习笔记之PromQL简单示例

    0x00 简单的时间序列选择 返回度量指标 http_requests_total 的所有时间序列样本数据: http_requests_total 返回度量指标名称为 http_requests_t ...

随机推荐

  1. Python中zip()函数的解释和可视化

    zip()的作用 先看一下语法: zip(iter1 [,iter2 [...]]) -> zip object Python的内置help()模块提供了一个简短但又有些令人困惑的解释: 返回一 ...

  2. Github 小白简单教学

    Git和Github简单教程   原文链接:Git和Github简单教程 网络上关于Git和GitHub的教程不少,但是这些教程有的命令太少不够用,有的命令太多,使得初期学习的时候需要额外花不少时间在 ...

  3. 新的征程TestOps

    TestOps 概念是什么时候提出来的没有去考察,知道TestOps测试运维是在DevOps这个概念下抽象的结果. DevOps,现在几乎每家公司都在谈DevOps,都已经实施,在实施,或者在准备实施 ...

  4. 手把手带你阅读Mybatis源码(一)构造篇

    前言 今天会给大家分享我们常用的持久层框架——MyBatis的工作原理和源码解析,后续会围绕Mybatis框架做一些比较深入的讲解,之后这部分内容会归置到公众号菜单栏:连载中…-框架分析中,欢迎探讨! ...

  5. Python 高级网络操作 - Python Advanced Network Operations

    Python 高级网络操作 - Python Advanced Network Operations Half Open Socket, 一个单向的 socket 被称为 half open sock ...

  6. 11-MyBatis01

    今日知识 1. MyBatis简介 2. MyBatis入门 3. 全局配置文件其他配置 4. MyBatis的映射文件 5. 动态SQL 6. mybatis和hibernate区别 MyBatis ...

  7. 十篇笔记走向Python测试开发之路四(字典)

    字典 字典(dict)是Python的一种内置的数据结构.在其他语言中也称为map,使用键-值(key-value)存储,可以通过查找某个特定的词语(键 key),从而找到他的定义(值 value) ...

  8. 容器监控工具WeaveScope

    最近一段时间整了一些docker容器,弄了一些基于docker的微服务通信,弄好一套服务系统之后,对于服务的性能,基础数据的监控就显的很重要, 不然就是两眼一抹黑了,要不就是维护成本很高,这些都不符合 ...

  9. Centos 7 使用(Service iptables stop/start)关闭/打开防火墙 Failed to stop iptables.service: Unit iptables.service not loaded.

    背景: 测试部署NetCore 项目到linux 系统时,窗口显示项目部署成功:但是本机无法访问(linux 在虚拟机上[ centos 7.6] );  如下图↓ 能够相互ping  通,(Xshe ...

  10. java开发JSP+Servlet+bootstrap开发电影院购票系统 源码

    基于JSP+Servlet+bootstrap开发电影院购票系统:开发环境: Windows操作系统开发工具: MyEclipse+Jdk+Tomcat+Mysql数据库 程序要求:电影院订票系统 用 ...