写在前面

指标名称(metrics name) 和 一组标签(labelset) 唯一的标识一条时间序列。 metrics name 反映了样本的基本信息,而 label 则提供了多种特征维度。

PromQL 是Prometheus 内置的查询语言,提供 查询,聚合,逻辑运算 的支持。可以用在 数据查询,可视化,报警当中。

所有的PromQL表达式都必须至少包含一个指标名称(例如http_request_total),或者一个不会匹配到空字符串的标签过滤器(例如{code=”200”}), 除了使用<metric name>{label=value}的形式以外,我们还可以使用内置的__name__标签来指定监控指标名称:

查询

直接按 metrics name 查询

http_requests_total (作用等于 http_requests_total{})

完全匹配标签 =

http_requests_total {app=”demo-app”}

反向匹配标签 !=

http_requests_total {app!=”demo-app”}

正则匹配 label=~regx

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

正则排除 label!~regx

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

范围查询

直接通过类似于PromQL表达式http_requests_total查询时间序列时,返回值中只会包含该时间序列中的最新的一个样本值,这样的返回结果我们称之为瞬时向量。而相应的这样的表达式称之为瞬时向量表达式 而如果我们想过去一段时间范围内的样本数据时,我们则需要使用区间向量表达式。区间向量表达式和瞬时向量表达式之间的差异在于在区间向量表达式中我们需要定义时间选择的范围,时间范围通过时间范围选择器[]进行定义

查询 24 小时

http_requests_total{}[24h]

  • s - 秒
  • m - 分钟
  • h - 小时
  • d - 天
  • w - 周
  • y - 年
时间位移操作

查询5分钟前的瞬时样本数据

http_request_total{} offset 5m

聚合操作
查询系统所有http请求的总量

sum(http_request_total)

按照mode计算主机CPU的平均使用时间

avg(node_cpu) by (mode)

按照主机查询各个主机的CPU使用率

sum(sum(irate(node_cpu{mode!=’idle’}[5m])) / sum(irate(node_cpu[5m]))) by (instance)

标量

当使用表达式count(http_requests_total),返回的数据类型,依然是瞬时向量。用户可以通过内置函数scalar()将单个瞬时向量转换为标量。 标量只有一个数字,没有时序: 10

字符串

直接使用字符串,作为PromQL表达式,则会直接返回字符串

操作符

在PromQL操作符中优先级由高到低依次为:

  1. ^
  2. *, /, %
  3. +, -
  4. ==, !=, <=, <, >=, >
  5. and, unless
  6. or
数学运算
  • + (加法)

  • - (减法)

  • * (乘法)

  • / (除法)

  • % (求余)

  • ^ (幂运算)

布尔运算
  • == (相等)

  • != (不相等)

  • > (大于)

  • < (小于)

  • >= (大于等于)

  • <= (小于等于)

bool修饰符改变布尔运算符的行为

布尔运算符的默认行为是对时序数据进行过滤。而在其它的情况下我们可能需要的是真正的布尔结果。例如,只需要知道当前模块的HTTP请求量是否>=1000,如果大于等于1000则返回1(true)否则返回0(false)。这时可以使用bool修饰符改变布尔运算的默认行为 。

使用bool修改符后,布尔运算不会对时间序列进行过滤,而是直接依次瞬时向量中的各个样本数据与标量的比较结果0或者1。从而形成一条新的时间序列

ttp_requests_total > bool 1000

同时需要注意的是,如果是在两个标量之间使用布尔运算,则必须使用bool修饰符

2 == bool 2 # 结果为1

集合运算符
  • and (并且)

  • or (或者)

  • unless (排除)

聚合操作

  • sum (求和)

  • min (最小值)

  • max (最大值)

  • avg (平均值)

  • stddev (标准差)

  • stdvar (标准方差)

  • count (计数)

  • count_values (对value进行计数)

  • bottomk (后n条时序)

  • topk (前n条时序)

  • quantile (分位数)

([parameter,]) [without|by (

without用于从计算结果中移除列举的标签,而保留其它标签。by则正好相反,结果向量中只保留列出的标签,其余标签则移除。通过without和by可以按照样本的问题对数据进行聚合

常用内置函数

increase(v range-vector)

参数v是一个区间向量,increase函数获取区间向量中的第一个后最后一个样本并返回其增长量。因此,可以通过以下表达式Counter类型指标的增长率:

increase(node_cpu[2m]) / 120

rate(v range-vector)

rate函数可以直接计算区间向量v在时间窗口内平均增长速率

rate(node_cpu[2m])

irate(v range-vector)

使用rate或者increase函数去计算样本的平均增长速率,容易陷入“长尾问题”当中,其无法反应在时间窗口内样本数据的突发变化

irate函数是通过区间向量中最后两个样本数据来计算区间向量的增长速率。这种方式可以避免在时间窗口范围内的“长尾问题”,并且体现出更好的灵敏度,通过irate函数绘制的图标能够更好的反应样本数据的瞬时变化状态

irate(node_cpu[2m])

不过当需要分析长期趋势或者在告警规则中,irate的这种灵敏度反而容易造成干扰。因此在长期趋势分析或者告警中更推荐使用rate函数

predict_linear(v range-vector, t scalar)

predict_linear函数可以预测时间序列v在t秒后的值。它基于简单线性回归的方式,对时间窗口内的样本数据进行统计,从而可以对时间序列的变化趋势做出预测

predict_linear(node_filesystem_free{job=”node”}[2h], 4 * 3600) < 0 (基于2小时的样本数据,来预测主机可用磁盘空间的是否在4个小时候被占满)

label_replace

label_replace标签为时间序列添加额外的标签

label_replace(v instant-vector, dst_label string, replacement string, src_label string, regex string)

例如:

label_replace(up, “host”, “$1”, “instance”, “(.):.“)

label_join

将时间序列中v多个标签src_label的值,通过separator作为连接符写入到一个新的标签dst_label中

label_join(v instant-vector, dst_label string, separator string, src_label_1 string, src_label_2 string, …)

HTTP API

Prometheus 提供了稳定的HTTP 的查询方式。

响应体
1
2
3
4
5
6
7
{
"status": "success" | "error",
"data": {}
// if error:
"errorType": "",
"error": ""
}
1. 查询瞬时数据
  • url: /api/v1/query GET

  • 参数

    参数说明
    queryPromQL
    time用于指定用于计算PromQL的时间戳。可选参数,默认情况下使用当前系统时间
    timeout超时设置。可选参数,默认情况下使用-query,timeout的全局设置
2. 查询区间数据
  • url: /api/v1/query_range GET

  • 参数

    参数说明
    queryPromQL表达式
    start起始时间
    end结束时间
    step查询步长
    timeout超时