0%

Prometheus查询语言:PromQL

PromQL简介

Prometheus提供了一种称为PromQL(Prometheus查询语言)的功能查询语言,使用户可以实时选择和汇总时间序列数据。表达式的结果既可以显示为图形,也可以在Prometheus的表达式浏览器中显示为表格数据,也可以由外部系统通过HTTP API使用。

更多内容参考QUERYING PROMETHEUS探索PromQL

时间序列

1
2
3
4
5
6
# HELP node_cpu Seconds the cpus spent in each mode.
# TYPE node_cpu counter
node_cpu{cpu="cpu0",mode="idle"} 362812.7890625
# HELP node_load1 1m load average.
# TYPE node_load1 gauge
node_load1 3.0703125

其中非#开头的每一行表示当前Node Exporter采集到的一个监控指标(监控样本):node_cpu和node_load1表明了当前指标的名称(大括号中的标签则反映了该指标的一些特征和维度),浮点数是该指标的具体值。指标格式为:

1
metric_name [ {label_name="label_value"} ] value [ timestamp ]

其中metric_name和label_name必须遵循PromQL的格式规范要求。value是一个float格式的数据,timestamp的类型为int64(从1970-01-01 00:00:00以来的毫秒数),timestamp为可选默认为当前时间。具有相同metric_name的样本必须按照一个组的形式排列,并且每一行必须是唯一的指标名称和标签键值对组合。

Prometheus会将所有采集到的指标数据以时间序列(time-series)的方式保存在内存数据库中,并且定时保存到硬盘上。时间序列是按照时间戳和指标的序列顺序存放的,我们称之为向量(vector)。

可以将time-series理解为一个数字矩阵,X轴是时间戳,Y轴是指标。

数据类型

在Prometheus的表达语言中,一个表达式或子表达式可以分以下四种类型之一:

  • 瞬时向量:一组时间序列,这组时间序列具有相同的时间戳
  • 范围向量:一段时间范围的时间序列
  • 标量:一个简单的数字浮点值
  • String:一个简单的字符串值;目前未使用

根据用例(例如在绘制图形或显示表达式的输出时),由于用户指定的表达式的结果,其中只有某些类型是合法的。例如,返回瞬时向量的表达式是唯一可以直接绘制图形的类型。

常量

字符串常量

字符串可以用单引号,双引号或反引号指定为常量。
PromQL遵循与Go相同的转义规则。在单引号或双引号中,反斜杠开始一个转义序列。可以使用八进制或十六进制提供特定字符。
反引号内不会处理任何转义。与Go不同,Prometheus不会在反引号内丢弃换行符。

1
2
3
"this is a string"
'these are unescaped: \n \\ \t'
`these are not unescaped: \n ' " \t`

浮点常量

浮点常量可以写做数字形式:[-](digits)[.(digits)] ,例如 -2.43

时间序列选择器

瞬时向量选择器

瞬时向量选择器允许在给定的时间戳(瞬时)下选择一组时间序列和每个样本的单个样本值:以最简单的形式,仅指定度量名称。这将导致一个瞬时向量,其中包含具有该度量名称的所有时间序列的元素。
通过在花括号 {} 中附加逗号分隔的标签匹配器列表,可以进一步过滤这些时间序列。
也可以否定标签值,或将标签值与正则表达式匹配。存在以下标签匹配运算符:

  • =:选择与字符串完全相等的标签。
  • !=:选择不等于字符串的标签。
  • =〜:选择与字符串进行正则表达式匹配的标签。
  • !〜:选择与字符串正则表达式不匹配的标签。

匹配空标签值的标签匹配器还会选择所有根本没有设置特定标签的时间序列。正则表达式匹配完全锚定。同一标签名称可能有多个匹配器。
向量选择器必须指定一个名称或至少一个与空字符串不匹配的标签匹配器。
通过与内部 __name__ 标签进行匹配,标签匹配器也可以应用于度量标准名称。Prometheus中的所有正则表达式都使用RE2语法

1
2
3
4
5
6
{job=~".*"} # Bad!
{job=~".+"} # Good!
{job=~".*",method="get"} # Good!
{__name__=~"job:.*"} # selects all metrics that have a name starting with job:
on{} # Bad!
{__name__="on"} # Good!

范围向量选择器

范围向量的工作方式与瞬时向量相同,不同的是范围向量从瞬时向量中选择了一定范围的样本。语法上,将范围持续时间附加在向量选择器末尾的方括号 [] 中,以指定提取时间值的范围。
持续时间以数字指定,后面紧跟以下单位之一:s - seconds,m - minutes,h - hours,d - days,w - weeks,y - years

偏移量

偏移量允许更改查询中各个瞬时向量和范围向量的时间偏移。

1
2
3
4
http_requests_total offset 5m
sum(http_requests_total{method="GET"} offset 5m) // GOOD.
sum(http_requests_total{method="GET"}) offset 5m // INVALID.
rate(http_requests_total[5m] offset 1w)

子查询

子查询对给定的范围进行即时查询。子查询的结果是范围向量。
语法:

1
<instant_query> '[' <range> ':' [<resolution>] ']' [ offset <duration> ]

resolution是可选的。默认值为全局评估间隔。

运算符

Prometheus支持许多二进制和聚合运算符,更多内容参考表达式语言运算符

函数

Prometheus支持多种对数据进行操作的函数,更多内容参考表达式语言函数

注释

PromQL支持以#开头的行注释。

例子

详细内容参见QUERY EXAMPLE

简单时间序列查询

1
2
3
4
5
6
http_requests_total
{__name__="http_requests_total"}
http_requests_total{job="apiserver", handler="/api/comments"}
http_requests_total{job="apiserver", handler="/api/comments"}[5m]
http_requests_total{job=~".*server"}
http_requests_total{status!~"4.."}

子查询

1
2
rate(http_requests_total[5m])[30m:1m]
max_over_time(deriv(rate(distance_covered_total[5s])[30s:5s])[10m:])

函数运算等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
rate(http_requests_total[5m])

sum by (job) (
rate(http_requests_total[5m])
)

(instance_memory_limit_bytes - instance_memory_usage_bytes) / 1024 / 1024

sum by (app, proc) (
instance_memory_limit_bytes - instance_memory_usage_bytes
) / 1024 / 1024

topk(3, sum by (app, proc) (rate(instance_cpu_time_ns[5m])))

count by (app) (instance_cpu_time_ns)