基础语法
Prometheus提供了一种功能性查询语言,称为PromQL(Prometheus Query Language),允许用户实时地选择和聚合时间序列数据。PromQL计算结果可以在图表中展示,也可以在Prometheus表达式浏览器中以表格形式展示;或者作为数据源, 以HTTP API的方式提供给外部系统使用。
PromQL数据类型
在Prometheus的表达式语言中,表达式或子表达式可以归为以下四种类型:
Instant vector(瞬时向量):它是指在同一时刻,抓取的所有metric数据。这些metric数据的key都是相同的,也包括相同的时间戳。
Range vector(范围向量):它是指在任何一个时间范围内,抓取的所有metric数据。
Scalar(标量):一个简单的浮点值。
String(字符串):一个当前没有使用过的字符串。
依赖于使用场景(例如画图展示或者输出表达式结果),根据用户所写的表达式,只有部分类型是合法的返回结果。例如:瞬时向量类型是唯一可以直接在图表中使用的。
常量
字符串
字符串可以用单引号、双引号或者反引号表示。PromQL遵循与Go相同的转义规则 。 在单引号,双引号中,反斜杠成为了转义字符,后面可以跟着a, b, f, n, r, t, v或者\。 可以使用八进制(\nnn)或者十六进制(\xnn, \unnnn和\Unnnnnnnn)提供特定字符。
在反引号内不处理转义字符。与Go不同,Prom不会丢弃反引号中的换行符。例如:
"this is a string"
'these are unescaped: \n \\ \t'
`these are not unescaped: \n ' " \t`
浮点数
标量浮点值可以写为形如 [-] (digits)[.(digits)]
的数字,例如:
-2.43
时间序列选择器
瞬时向量选择器
瞬时向量选择器可以对一组时间序列数据进行筛选,并返回每个符合条件的样本数据键值对(时间戳-样本值):最简单的形式是:只有一个metric被指定,这种情况下,返回结果包含这个metric的所有样本数据键值对。下面这个例子选择所有时间序列metric为http_requests_total
的样本数据:
http_requests_total
可以通过附加以花括号( {}
)标注的一组标签,来进一步过滤这些时间序列。此示例选择metric为http_requests_total
的时间系列,同时满足 job
标签等于 prometheus
, group
标签等于 canary
。
http_requests_total{job="prometheus",group="canary"}
还可以对标签值进行负匹配,或者将标签值与正则表达式进行匹配。 存在以下标签匹配运算符:
=
:选择与提供的字符串完全相同的标签。!=
:选择不等于提供的字符串的标签。=~
:选择正则表达式匹配提供的字符串(或子字符串)的标签。!~
:选择不与提供的字符串(或子字符串)匹配的标签。
例如,返回metric为 http_requests_total
,标签 environment
匹配 staging
, testing
, development
,并且标签 method
不等于 GET
的所有时间序列数据。
http_requests_total{environment=~"staging|testing|development",method!="GET"}
匹配空标签值的标签匹配器也可以选择没有设置任何标签的所有时间序列数据。正则表达式完全匹配。向量选择器必须指定一个metric或者至少不能为空字符串的标签值。以下表达式是非法的:
{job=~".*"} # Bad!
相反,这些表达式是有效的,因为它们都有一个与空标签值不匹配的选择器:
{job=~".+"} # Good!
{job=~".*",method="get"} # Good!
标签匹配器能够被应用到metric,使用__name__
标签筛选metric。例如:表达式http_requests_total
等价于{__name__="http_requests_total"}
。 其他的匹配器,如:= ( !=, =~, !~)
都可以使用。下面的表达式选择了metric以job
开头的时间序列数据:
{__name__=~"job.*"}
Prometheus正则表达式详情参考 RE2 syntax.
范围向量选择器
范围向量选择器像瞬时向量选择器一样工作,不同的是它们从时间序列中选择一定时间范围内的数据。 在语法上,范围持续时间附加在向量选择器末尾的方括号( []
)中。时间持续的值以数字表示,其后跟以下时间单位:
s - 秒
m - 分钟
h - 小时
d - 天
w - 周
y - 年
在此示例中,我们选择在过去5分钟内为metric为 http_requests_total
且 job
标签设置为 prometheus
的所有时间序列记录的元素值:
http_requests_total{job="prometheus"}[5m]
偏移修改器
偏移修改器允许更改查询中各个瞬时和范围向量的时间偏移。例如,以下表达式返回相对于当前查询时间5分钟前metric为 http_requests_total
的元素值:
http_requests_total offset 5m
请注意,偏移修改器始终需要跟随在选择器之后,即以下内容是正确的:
sum(http_requests_total{method="GET"} offset 5m) // GOOD.
以下为错误示例:
sum(http_requests_total{method="GET"}) offset 5m // INVALID.
同样适用于范围向量。 这将返回 http_requests_total
一周前的5分钟数据的 rate
:
rate(http_requests_total[5m] offset 1w)
子查询
子查询允许您在给定范围和分辨率内运行瞬时查询。 子查询的结果是范围向量。
语法: <instant_query> '[' <range> ':' [<resolution>] ']' [ offset <duration> ]
<resolution>
可缺省。
陷阱
陈旧性
运行查询时,选择采样数据(独立于实际当前时间序列)的时间戳。这主要是为了支持聚合(总和,平均等)这样的情况,其中多个聚合时间序列在时间上不完全对齐。由于它们的独立性,Prometheus需要在每个相关时间序列的时间戳上分配值。它只需在此时间戳之前采用最新的样本即可。如果目标抓取或规则评估不再返回先前存在的时间序列的样本,则该时间序列将被标记为陈旧。如果目标被移除,之前很快就会将其先前返回的时间序列标记为陈旧。如果在时间序列标记为过时后在采样时间戳处计算查询,则不会为该时间系列返回任何值。如果随后在该时间序列中摄取新样本,它们将照常返回。如果在采样时间戳前5分钟未找到任何样本(默认情况下),则此时间点不返回该时间序列的值。这实际上意味着时间序列在其最新收集的样本超过5分钟或者标记为陈旧之后从图表“消失”。对于在其刮擦中包含时间戳的时间序列,不会标记陈旧性。在这种情况下,仅应用5分钟的阈值。
避免慢查询和重载
如果查询需要对大量数据进行操作,则绘制图表可能会超时或使服务器或浏览器过载。因此,在构建对未知数据的查询时,始终在Prometheus表达式浏览器的表格视图中开始构建查询,直到结果集看起来合理(最多数百个,而不是数千个时间序列)。只有在您充分过滤或汇总数据后,才能切换到图表模式。如果表达式仍然需要很长时间来绘制图形,请通过记录规则 预先记录它。这与Prometheus的查询语言尤其相关,其中像api_http_requests_total这样的简单metric选择器可以扩展到具有不同标签的数千个时间序列。还要注意,即使输出只是少量的时间序列,聚合在许多时间序列上的表达式也会在服务器上产生负载。这类似于在关系数据库中对列的所有值求和的速度很慢,即使输出值只是一个数字。