PromQL操作符
PromQL操作符
使用PromQL除了能够方便的按照查询和过滤时间序列以外,PromQL还支持丰富的操作符,用户可以使用这些操作符对进一步的对事件序列进行二次加工。这些操作符包括:数学运算符,逻辑运算符,布尔运算符等等。
数学运算
例如,我们可以通过指标node_memory_free_bytes_total获取当前主机可用的内存空间大小,其样本单位为Bytes。这是如果客户端要求使用MB作为单位响应数据,那只需要将查询到的时间序列的样本值进行单位换算即可:
node_memory_free_bytes_total / ( * )
node_memory_free_bytes_total表达式会查询出所有满足表达式条件的时间序列,在上一小节中我们称该表达式为瞬时向量表达式,而返回的结果成为瞬时向量。
当瞬时向量与标量之间进行数学运算时,数学运算符会依次作用域瞬时向量中的每一个样本值,从而得到一组新的时间序列。
而如果是瞬时向量与瞬时向量之间进行数学运算时,过程会相对复杂一点。 例如,如果我们想根据node_disk_bytes_written和node_disk_bytes_read获取主机磁盘IO的总量,可以使用如下表达式:
node_disk_bytes_written + node_disk_bytes_read
那这个表达式是如何工作的呢?依次找到与左边向量元素匹配(标签完全一致)的右边向量元素进行运算,如果没找到匹配元素,则直接丢弃。同时新的时间序列将不会包含指标名称。 该表达式返回结果的示例如下所示:
{device="sda",instance="localhost:9100",job="node_exporter"}=>@1518146427.807 + @1518146427.807
{device="sdb",instance="localhost:9100",job="node_exporter"}=>@1518146427.807 + @1518146427.807
PromQL支持的所有数学运算符如下所示:
+(加法)-(减法)*(乘法)/(除法)%(求余)^(幂运算)
使用布尔运算过滤时间序列
在PromQL通过标签匹配模式,用户可以根据时间序列的特征维度对其进行查询。而布尔运算则支持用户根据时间序列中样本的值,对时间序列进行过滤。
例如,通过数学运算符我们可以很方便的计算出,当前所有主机节点的内存使用率:
(node_memory_bytes_total - node_memory_free_bytes_total) / node_memory_bytes_total
而系统管理员在排查问题的时候可能只想知道当前内存使用率超过95%的主机呢?通过使用布尔运算符可以方便的获取到该结果:
(node_memory_bytes_total - node_memory_free_bytes_total) / node_memory_bytes_total > 0.95
瞬时向量与标量进行布尔运算时,PromQL依次比较向量中的所有时间序列样本的值,如果比较结果为true则保留,反之丢弃。
瞬时向量与瞬时向量直接进行布尔运算时,同样遵循默认的匹配模式:依次找到与左边向量元素匹配(标签完全一致)的右边向量元素进行相应的操作,如果没找到匹配元素,则直接丢弃。
目前,Prometheus支持以下布尔运算符如下:
==(相等)!=(不相等)>(大于)<(小于)>=(大于等于)<=(小于等于)
使用bool修饰符改变布尔运算符的行为
布尔运算符的默认行为是对时序数据进行过滤。而在其它的情况下我们可能需要的是真正的布尔结果。例如,只需要知道当前模块的HTTP请求量是否>=1000,如果大于等于1000则返回1(true)否则返回0(false)。这时可以使用bool修饰符改变布尔运算的默认行为。 例如:
http_requests_total > bool
使用bool修改符后,布尔运算不会对时间序列进行过滤,而是直接依次瞬时向量中的各个样本数据与标量的比较结果0或者1。从而形成一条新的时间序列。
http_requests_total{code="",handler="query",instance="localhost:9090",job="prometheus",method="get"}
http_requests_total{code="",handler="query_range",instance="localhost:9090",job="prometheus",method="get"}
同时需要注意的是,如果是在两个标量之间使用布尔运算,则必须使用bool修饰符
== bool # 结果为1
使用集合运算符
使用瞬时向量表达式能够获取到一个包含多个时间序列的集合,我们称为瞬时向量。 通过集合运算,可以在两个瞬时向量与瞬时向量之间进行相应的集合操作。目前,Prometheus支持以下集合运算符:
and(并且)or(或者)unless(排除)
vector1 and vector2 会产生一个由vector1的元素组成的新的向量。该向量包含vector1中完全匹配vector2中的元素组成。
vector1 or vector2 会产生一个新的向量,该向量包含vector1中所有的样本数据,以及vector2中没有与vector1匹配到的样本数据。
vector1 unless vector2 会产生一个新的向量,新向量中的元素由vector1中没有与vector2匹配的元素组成。
操作符优先级
对于复杂类型的表达式,需要了解运算操作的运行优先级
例如,查询主机的CPU使用率,可以使用表达式:
* ( - avg (irate(node_cpu{mode='idle'}[5m])) by(job) )
其中irate是PromQL中的内置函数,用于计算区间向量中时间序列每秒的即时增长率。关于内置函数的部分,会在下一节详细介绍。
在PromQL操作符中优先级由高到低依次为:
^*, /, %+, -==, !=, <=, <, >=, >and, unlessor
匹配模式详解
向量与向量之间进行运算操作时会基于默认的匹配规则:依次找到与左边向量元素匹配(标签完全一致)的右边向量元素进行运算,如果没找到匹配元素,则直接丢弃。
接下来将介绍在PromQL中有两种典型的匹配模式:一对一(one-to-one),多对一(many-to-one)或一对多(one-to-many)。
一对一匹配
一对一匹配模式会从操作符两边表达式获取的瞬时向量依次比较并找到唯一匹配(标签完全一致)的样本值。默认情况下,使用表达式:
vector1 <operator> vector2
在操作符两边表达式标签不一致的情况下,可以使用on(label list)或者ignoring(label list)来修改便签的匹配行为。使用ignoreing可以在匹配时忽略某些便签。而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=""}
method_code:http_errors:rate5m{method="get", code=""}
method_code:http_errors:rate5m{method="put", code=""}
method_code:http_errors:rate5m{method="post", code=""}
method_code:http_errors:rate5m{method="post", code=""}
method:http_requests:rate5m{method="get"}
method:http_requests:rate5m{method="del"}
method:http_requests:rate5m{method="post"}
使用PromQL表达式:
method_code:http_errors:rate5m{code=""} / ignoring(code) method:http_requests:rate5m
该表达式会返回在过去5分钟内,HTTP请求状态码为500的在所有请求中的比例。如果没有使用ignoring(code),操作符两边表达式返回的瞬时向量中将找不到任何一个标签完全相同的匹配项。
因此结果如下:
{method="get"} 0.04 // 24 / 600
{method="post"} 0.05 // 6 / 120
同时由于method为put和del的样本找不到匹配项,因此不会出现在结果当中。
多对一和一对多
多对一和一对多两种匹配模式指的是“一”侧的每一个向量元素可以与”多”侧的多个元素匹配的情况。在这种情况下,必须使用group修饰符: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>
多对一和一对多两种模式一定是出现在操作符两侧表达式返回的向量标签不一致的情况。因此需要使用ignoring和on修饰符来排除或者限定匹配的标签列表。
例如,使用表达式:
method_code:http_errors:rate5m / ignoring(code) group_left method:http_requests:rate5m
该表达式中,左向量method_code包含两个标签method和code。而右向量
rate5mmethod中只包含一个标签method,因此匹配时需要使用ignoring限定匹配的标签为code。 在限定匹配标签后,右向量中的元素可能匹配到多个左向量中的元素
rate5m
因此该表达式的匹配模式为多对一,需要使用group修饰符group_left指定左向量具有更好的基数。
最终的运算结果如下:
{method="get", code=""} 0.04 // 24 / 600
{method="get", code=""} 0.05 // 30 / 600
{method="post", code=""} 0.05 // 6 / 120
{method="post", code=""} 0.175 // 21 / 120
提醒:group修饰符只能在比较和数学运算符中使用。在逻辑运算and,unless和or才注意操作中默认与右向量中的所有元素进行匹配。
PromQL操作符的更多相关文章
- Prometheus监控学习笔记之PromQL操作符
0x00 二元运算符 Prometheus 的查询语言支持基本的逻辑运算和算术运算.对于两个瞬时向量, 匹配行为可以被改变. 算术二元运算符 在 Prometheus 系统中支持下面的二元算术运算符: ...
- Prometheus监控学习笔记之初识PromQL
0x00 概述 Prometheus 提供了一种功能表达式语言 PromQL,允许用户实时选择和汇聚时间序列数据.表达式的结果可以在浏览器中显示为图形,也可以显示为表格数据,或者由外部系统通过 HTT ...
- Prometheus学习系列(七)之Prometheus PromQL说明
前言 本文来自Prometheus官网手册1.2.3 和 Prometheus简介1.2.3 PromQL操作符 一.二元操作符 Prometheus的查询语言支持基本的逻辑运算和算术运算.对于两个瞬 ...
- 《为什么说 Prometheus 是足以取代 Zabbix 的监控神器?》
为什么说 Prometheus 是足以取代 Zabbix 的监控神器? Kuberneteschina 致力于提供最权威的 Kubernetes 技术.案例与Meetup! 关注他 12 人赞同 ...
- Prometheus 学习目录
Prometheus 介绍 Prometheus 安装 https://www.bookstack.cn/read/prometheus-book/quickstart-why-monitor.md ...
- docker+prom+grafana+altermanager
docker基础 docker run -it --name centos -v $HOME:/tmp -p 8080:8080 centos docker inspect container #查看 ...
- prometheus之查询语言
PromQL(Prometheus Query Language)是 Prometheus 自己开发的表达式语言,语言表现力很丰富,内置函数也很多.使用它可以对时序数据进行筛选和聚合. 一.PromQ ...
- Prometheus PromQL 基础
目录 时序 4 种类型 Counter Gauge Histogram Summary Histogram vs Summary 操作符 时序 4 种类型 Prometheus 时序数据分为 Coun ...
- 【PromQL】prometheus查询语言
常用查询: https://songjiayang.gitbooks.io/prometheus/content/exporter/nodeexporter_query.html group by 操 ...
随机推荐
- 《一篇文章读懂HTTPS及其背后的加密原理》阅读笔记
HTTPS(Hypertext Transfer Protocol Secure,超文本传输安全协议),是以安全为目标的HTTP通道,简单讲是HTTP的安全版.这篇文章深入介绍了它的原理. 当我们适用 ...
- JS-原生的ajax
记录一下: //post需要设置请求头 setRequestHeader(name, value)name //头部的名称:这个参数不应该包括空白.冒号或换行 //value 头部的值:这个参数不应该 ...
- JS-防抖与节流
问题的由来:一些事件频繁的被触发而导致频繁的调用事件处理程序,从而造成程序不必要的开销,影响程序性能:防抖和节流就是为了解决这种情况造成的性能消耗. 场景1:使用keyup事件监听输入框的值进行请求搜 ...
- 使用 swiper 制作 导航,点击项居中
目的:导航有多个,被点击的项居中显示. html: <div class="swiper-container"> <div class="swiper- ...
- IDEA中常用优化设置
1.设置鼠标悬浮提示 Editor->General 这里要勾选下,后面设置的是延迟时间 默认半秒:设置后,我们鼠标移动到类上看看: 2.显示方法分隔符 Editor->General - ...
- kafka 消息可靠性
1.消息发送机制 Kafka的ack机制. 当producer向leader发送数据时,可以通过request.required.acks参数来设置数据可靠性的级别: 1(默认):这意味着produc ...
- MySQL数据库备份还原
本文以CentOS 7 yum安装的MariaDB-server5.5为例,说明MySQL的几种 备份还原方式 将服务器A(192.168.1.100)上的数据库备份,还原到B(192.168.1.2 ...
- Android Studio 使用入门及问题汇总
声明:转载自http://blog.csdn.net/wei_chong_chong/article/details/56280383 之前一直用eclipse+adt做Android开发.曾经尝试使 ...
- 洛谷 P1241 括号序列(栈)
嗯... 题目链接:https://www.luogu.org/problem/P1241 首先这道题是栈的入门题的加强版, 不仅要你判断这个括号序列是否合法,还要你将这个序列补充完整... 一开始是 ...
- 监控Tomcat状态!(重点)
方法一:开发JAVA监控页面 [root@localhost ~]# mkdir /usr/local/tomcat8/webapps/memtest/[root@localhost ~]# cd / ...