Prometheus监控教程:使用PromQL查询监控数据(上篇)

PromQL是Prometheus提供的一个函数式的表达式语言,可以使用户实时地查找和聚合时间序列数据。表达式计算结果可以在图表中展示,也可以在 Prometheus表达式浏览器中以表格形式展示,或者作为数据源以HTTP API的方式提供给外部系统使用。PromQL虽然以QL结尾,但是它不是类似SQL的语言,因为在时间序列上执行计算类型时,SQL语言相对缺乏表达能力。而PromQL语言表达能力非常丰富,可以使用标签进行任意聚合,还可以使用标签将不同的标签连接到一起进行算术运算操作。内置了时间和数学等很多函数可以使用。

一、PromQL表达式

1.1、语言数据类型

PromQL表达式语言中,一个表达式或者子表达式可以表示以下4种类型之一:

  • Instant vector:瞬时向量,一组time series(时间序列),每个time series包括了一个时间戳的数据点,所有time series数据点拥有相同的时间戳。

  • Range vector:范围向量,一组time series包含一个时间范围内的一组数据点。

  • Scalar:标量,为一个浮点数值。

  • String:字符串,为一个字符串数值。当前未使用。

1.2、Literals数据格式

1.2.1 String literals

 字符串可以用单引号(‘’)、双引号(“”)或反引号(``)指定为文字。

1.2.2 Float literals

 浮点类型数值的格式为:-[.(digits)]
 如:-2.43

1.3、Time series(时间序列)选择器

1.3.1 Instant vector selectors(即时矢量选择器)

 瞬时向量选择器用于选择一组time series和每个time series对应的某一个时间戳数据点,唯一的要求是必须指定metric指标名。

例:查询指标名http_requests_total对应的所有time series表达式:

http_requests_total

可以通过在花括号 ( {}) 中附加一个逗号分隔的标签匹配器列表来进一步过滤这些时间序列。

例:仅选择具有http_requests_total 度量名称且job标签设置为prometheus且其 group标签设置为的时间序列canary:

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

通过负匹配或正则表达式匹配tag选择时间序列,支持如下匹配运算符:

  • = 等于

  • != 不等于

  • =~ 选择与提供的字符串进行正则表达式匹配的标签

  • !~ 选择与提供的字符串不匹配的标签

1.3.2 Range vector selectors(范围矢量选择器)

范围向量字面量的工作方式类似于即时向量字面量,唯一区别是选择的时间序列是一个时间范围内的时序数据。从语法上讲,持续时间附加在[]向量选择器末尾的方括号 ( ) 中,以指定应该为每个结果范围向量元素获取多远的时间值

例:为所有时间序列选择了过去 5 分钟内记录的所有值,这些时间序列的指标名称http_requests_total和job标签设置为prometheus:

http_requests_total{job="prometheus"}[5m]

1.3.3 Offset modifier(偏移修改器)

 Offset修改器允许修改查询中瞬时向量和范围向量的时间偏移。

 例:返回 http_requests_total 相对于当前查询评估时间过去 5 分钟的值

http_requests_total offset 5m

注:offset修饰符总是需要立即跟随选择器

1.4、Subquery(子查询)

 子查询允许针对给定的范围和分辨率运行即时查询。子查询的结果是一个范围向量。

<instant_query> [ <range> : [<resolution>]] [offset <duration>]
注:<resolution>是可选的,默认为全局评估间隔

例:回过去30分钟CpuPercent 5m统计的rate(平均增长速率)值,精度是1分钟。

rate(CpuPercent{}[5m])[30m:1m]

二、PromQL运算符

 PromQL支持基本的逻辑和算术运算。对于两个瞬时向量的运算,其结果可能影响匹配行为。

2.1、算数运算符

  • +(加法)

  • - (减法)

  • * (乘法)

  • / (除法)

  • %(模数)

  • ^(幂)

 2.2、比较运算符

  • == (等于)

  • !=  (不等于)

  • >   (大于)

  • <   (小于)

  • >=(大于或等于)

  • <=(小于或等于)

2.3、逻辑/集合运算符

 逻辑/集合二元运算符仅在即时向量之间定义:

  • and  过滤出两个向量里都有的时间序列

  • or     过滤出两个向量里所有的时间序列

  • unless   过滤出左边向量里,右边没有的时间序列

2.4、聚合运算符

 Prometheus 支持以下内置聚合运算符,可用于聚合单个即时向量的元素,从而生成具有聚合值的元素更少的新向量

  • sum          (总和)

  • min           (最小值)

  • max               (最大值)

  • avg                (平均值)

  • group             (结果向量中的所有值都是1)

  • stddev           (计算维度上的总体标准偏差)

  • stdvar            (计算维度上的总体标准方差)

  • count             (计算向量中的元素个数)

  • count_values(计算具有相同值的元素个数)

  • bottomk        (样本值的最小k个元素)

  • topk              (按样本值计算的最大k个元素)

  • quantile        (在维度上计算 φ-quantile (0 ≤ φ ≤ 1))

 注:这些运算符既可以用于聚合所有标签维度,也可以通过包含withoutorby子句来保留不同的维度;这些子句可以在表达式之前或之后使用。

2.5、运算符优先级

  1. ^

  2. *,/,%

  3. +,-

  4. ==,!=,>,<,>=,<=

  5. and,unless

  6. or

三、PromQL内置函数

 一些函数有默认参数,例如year(v=vector(time()) instant-vector). 这意味着有一个参数v是一个即时向量,如果没有提供,它将默认为表达式的值 vector(time())。

  • abs()

  abs(v instant-vector)  返回输入向量,其中所有样本值都转换为其绝对值。

  • absent()

  absent(v instant-vector)  如果传递给它的瞬时向量有任何元素,则返回一个空向量;如果传递给它的向量没有元素,则返回一个值为 1 的 1 元素向量

 通常用于设置告警,判断给定的指标和标签没有数据时产生告警。

  • absent_over_time()

  absent_over_time(v range-vector)  如果传递给它的范围向量有任何元素,则返回一个空向量;如果传递给它的范围向量没有元素,则返回一个值为 1 的 1 元素向量。

 同absent(),常用于判断指标与标签组合,不存在于时间序列时报警。

  • ceil()

  ceil(v instant-vector)  将所有元素的样本值四舍五入到最接近的整数。

  • changes()

  changes(v range-vector)  计算给出的时间范围内,value是否发生变化,将发生变化时的条目作为即时向量返回

  • clamp()

  clamp(v instant-vector, min scalar, max scalar)  设定所有元素的样本值的上限与下限

 注:当min>max时,返回一个空向量:NaN if min or max is NaN

  • day_of_month()

 day_of_month(v=vector(time()) instant-vector)  以 UTC 格式返回每个给定时间的月份日期,返回值从 1 到 31。

  • day_of_week()

       day_of_week(v=vector(time()) instant-vector)  以 UTC 格式返回每个给定时间的星期几,返回值从 0 到 6,其中 0 表示星期日。

  • days_in_month()

  days_in_month(v=vector(time()) instant-vector)  以 UTC 格式返回每个给定时间该月的天数,返回值从 28 到 31。

  • delta()

  delta(v range-vector)  计算范围向量中每个时间序列元素的第一个值和最后一个值之间的差,返回具有给定增量和等效标签的即时向量。增量被外推以覆盖范围向量选择器中指定的整个时间范围,因此即使样本值都是整数,也可以获得非整数结果。

 例:返回现在和 2 小时前 CPU 温度的差异:

delta(cpu_temp_celsius{host="zeus"}[2h])
  • deriv()

  deriv(v range-vector)  使用简单线性回归的方法计算时间序列在范围向量 中的每秒导数

 注:deriv()函数在可视化页面上只能用于仪表盘

  • exp()

  exp(v instant-vector)  计算v中所有元素的指数函数

  • histogram_quantile() 分位直方图

  histogram_quantile(φ scalar, b instant-vector)  从instant vector中获取数据计算q分位(0<= q <=1)。b里的样本是每个桶的计数。每个样本必须具有标签le,表示桶的上限。直方图指标类型会自动提供了_bucket后缀和相应tags的time series。

 使用rate()函数指定分位计算的时间窗口。

 例1:一个直方图指标名:http_request_duration_seconds。计算其对应所有time series过去10分钟90分位数,使用如下表达式:

histogram_quantile(0.9, rate(http_request_duration_seconds_bucket[10m]))

 例2:为指标名http_request_duration_seconds对应的每个tags组合(每个time series)计算90分位数。为了聚合数据,比如使用sum()进行聚合,需要通过by子句包含le标签

histogram_quantile(0.9, sum(rate(http_request_duration_seconds_bucket[10m])) by (job, le))
  • hour()

  hour(v=vector(time()) instant-vector)  以 UTC 格式返回每个给定时间的一天中的小时,返回值从 0 到 23。

  • increase()

  increase(v range-vector)  计算范围向量中时间序列的增量。单调性的中断(例如由于目标重新启动而导致的计数器重置)会自动调整。该增加被外推以覆盖范围向量选择器中指定的整个时间范围,因此即使计数器仅增加整数增量,也可以获得非整数结果。

 例:返回范围向量中每个时间序列在过去 5 分钟内测量的 HTTP 请求数:

increase(http_requests_total{job="api-server"}[5m])
注:increase只能与counter类型指标(按增长率展示,即相邻两个时间点的差值除以时间差)一起使用。它是rate(v)乘以指定时间范围窗口下的秒数(相当于rate()乘以秒数),更易于人类理解。在记录规则中使用rate,以便每秒一致地跟踪增长。
  • irate()

  irate(v range-vector)  计算范围向量中时间序列的每秒瞬时增长率。这是基于最后两个数据点。单调性的中断(例如由于目标重新启动而导致的计数器重置)会自动调整。

 例:返回针对范围向量中每个时间序列的两个最近数据点的 HTTP 请求的每秒速率,最多可追溯 5 分钟:

irate(http_requests_total{job="api-server"}[5m])

 注:irate仅应在绘制易失性、快速移动的计数器时使用。用于rate警报和缓慢移动的计数器,因为速率的短暂变化可以重置FOR子句,并且完全由罕见峰值组成的图形难以阅读。

  • ln()

  ln(v instant-vector)  计算v中所有元素的自然对数

  • log2()

  log2(v instant-vector)  计算v中所有元素的二进制对数

  • rate()

  rate(v range-vector)  计算范围向量中时间序列的每秒平均增长率。单调性的中断(例如由于目标重新启动而导致的计数器重置)会自动调整。此外,计算推断到时间范围的末端,允许错过刮擦或刮擦周期与该范围的时间段的不完美对齐。

 例:返回在过去 5 分钟内测量的每秒 HTTP 请求速率,范围向量中的每个时间序列:

rate(http_requests_total{job="api-server"}[5m])

 注:rate()只能与counter类型指标一起使用。它最适合警报和缓慢移动计数器的图形。

  • resets()

  resets(v range-vector)  对于每个输入时间序列,resets(v range-vector)将提供的时间范围内的计数器重置次数作为即时向量返回。两个连续样本之间值的任何减少都被解释为计数器复位。

 注:resets()只能作用于counter类型指标

  • round()

  round(v instant-vector, to_nearest=1 scalar)  将所有元素的样本值四舍五入为v最接近的整数。平局通过四舍五入解决。可选to_nearest参数允许指定样本值应该四舍五入的最接近的倍数。这个倍数也可以是分数。默认为1。

  • scalar()

  scalar(v instant-vector)  给定一个单元素输入向量,scalar(v instant-vector)以标量形式返回该单元素的样本值。如果输入向量没有恰好一个元素,scalar将返回NaN

  • sort()

  sort(v instant-vector)  返回按样本值升序排序的向量元素。

  •  time()  

  time()  返回自 1970 年 1 月 1 日 UTC 以来的秒数。请注意,这实际上并不返回当前时间,而是要计算表达式的时间。

  • timestamp()

 timestamp(v instant-vector)  返回给定向量的每个样本的时间戳,作为自 1970 年 1 月 1 日 UTC 以来的秒数(Prometheus 2.0+)

  • year()

  year(v=vector(time()) instant-vector)  以 UTC 格式返回每个给定时间的年份。

学习更多内容,请关注IT运维先森微信公众号,将为你分享更多技术内容。 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT运维先森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值