关于prometheus:PromQL全解析

70次阅读

共计 9334 个字符,预计需要花费 24 分钟才能阅读完成。

PromQL(Prometheus Query Language)为 Prometheus tsdb 的查询语言。是联合 grafana 进行数据展现和告警规定的配置的要害局部。

本文默认您已理解 Prometheus 的四种指标类型:

  • counter(计数器)
  • gauge(仪表类型)
  • histogram(直方图类型)
  • summary(摘要类型)

便于读者实际,本文大部分样本数据 target:

  • Prometheus
  • node_exporter

表达式数据类型


PromQL 查问语句即表达式,实现的四种数据类型:

Instant vector

Instance vector(刹时向量)示意一个工夫序列的汇合,然而每个时序只有最近的一个点,而不是线。

Range vector

Range vector(范畴向量)示意一段时间范畴里的时序,每个时序可蕴含多个点

sources:Understanding Prometheus Range Vectors

Scalar

Scalar(标量)通常为数值,能够将只有一个时序的 Instance vector 转换成 Scalar。

String

简略字符串值,目前未被应用。

选择器


标签选择器

查问 Prometheus http 状态码为 400 的申请数量。

prometheus_http_requests_total{code="400"}

标签匹配运算符:

  • =:与字符串匹配
  • !=:与字符串不匹配
  • =~:与正则匹配
  • !~:与正则不匹配

查问 Prometheus http 状态码为 4xx 或 5xx 并且 handler 为 /api/v1/query 的申请数量

prometheus_http_requests_total{code=~"4.*|5.*",handler="/api/v1/query"}

外部标签 __name__ 用来匹配指标名称,上面的表达式与上一条等价

{code=~"4.*|5.*",handler="/api/v1/query",__name__="prometheus_http_requests_total"}
范畴选择器

查问过来 5 分钟 Prometheus 健康检查的采样记录。

prometheus_http_requests_total{code="200",handler="/-/healthy"}[5m]

单位:mssmhdwy

工夫串联:[1h5m]一小时 5 分钟

工夫偏移


通过 offset

通过 offset 将工夫倒退 5 分钟,即查问 5 分钟之前的数据。

prometheus_http_requests_total{code="200"} offset 5m

同样反对查问range vector

prometheus_http_requests_total{code="200"}[3m] offset 5m
@修饰符

还能够通过@ 间接跳转到某个 uinx 工夫戳,需开启启动参数--enable-feature=promql-at-modifier

prometheus_http_requests_total{code="200"} @ 1646089826

运算符


Prometheus 中的运算符与各类编程语言中的基本一致。

数学运算符

Prometheus 中存在以下数学运算符:

  • +(加法)
  • -(减法)
  • *(乘法)
  • /(除法)
  • %(取模)
  • ^(幂)

两个标量之间的计算

10/3

刹时向量与标量计算,因为计算后值意义与原指标名有差别,Prometheus 很贴心的帮咱们移除了指标名称。

prometheus_http_response_size_bytes_sum / 1024

两个刹时向量间的计算,如下计算 node 的内存使用率

(
1 -
node_memory_MemAvailable_bytes{job="node",instance="localhost:9100"} 
/ node_memory_MemTotal_bytes{job="node",instance="localhost:9100"}
)
* 100

如果两个刹时向量标签不统一可通过 ignoring 疏忽多余标签

输出示例:

method_code:http_errors:rate5m{method="get", code="500"}  24
method_code:http_errors:rate5m{method="post", code="500"} 6

method:http_requests:rate5m{method="get"}  600
method:http_requests:rate5m{method="post"} 120

查问示例:

method_code:http_errors:rate5m{code="500"} / ignoring(code) method:http_requests:rate5m

后果示例:

{method="get"}  0.04            //  24 / 600
{method="post"} 0.05            //   6 / 120

如果两个刹时向量数量不统一时可通过 group_leftgroup_right 指定以那一侧为准

输出示例:

method_code:http_errors:rate5m{method="get", code="500"}  24
method_code:http_errors:rate5m{method="get", code="404"}  30
method_code:http_errors:rate5m{method="put", code="501"}  3
method_code:http_errors:rate5m{method="post", code="500"} 6
method_code:http_errors:rate5m{method="post", code="404"} 21

method:http_requests:rate5m{method="get"}  600
method:http_requests:rate5m{method="del"}  34
method:http_requests:rate5m{method="post"} 120

查问示例:

group_left以左侧为准

method_code:http_errors:rate5m / ignoring(code) group_left method:http_requests:rate5m

后果示例:

{method="get", code="500"}  0.04            //  24 / 600
{method="get", code="404"}  0.05            //  30 / 600
{method="post", code="500"} 0.05            //   6 / 120
{method="post", code="404"} 0.175           //  21 / 120
比拟运算符

Prometheus 中存在以下比拟运算符:

  • ==(相等)
  • !=(不相等)
  • >(大于)
  • <(小于)
  • >=(大于或等于)
  • <=(小于或等于)

两个标量之间比拟,在运算符后跟 bool 润饰,后果0(false) 或1 (true)

10 < bool 5

刹时向量与标量比拟,查问 node 状态

up{job="node"} ==  bool 1

两个刹时向量比拟,查看音讯队列容量状态

prometheus_notifications_queue_length < bool prometheus_notifications_queue_capacity

逻辑运算符

Prometheus 中存在以下逻辑运算符:

  • and(与)
  • or(或)
  • unless(非)

逻辑运算仅实用于向量

如下咱们有 4 个 target,进行相应的逻辑运算,实现和标签抉择类似成果。

up{instance!="192.168.1.123:9091"} and up{job!="alertmanager"}  

up{instance="192.168.1.123:9091"} or up{job="alertmanager"}  

up unless up{job="alertmanager"}  

Prometheus 中二元运算符的优先级,从高到低。

  1. ^
  2. *, /, %,atan2
  3. +,-
  4. ==, !=, <=, <, >=,>
  5. and,unless
  6. or

雷同优先级的运算符是左联合的

聚合运算符

Prometheus 反对以下内置聚合运算符,可用于聚合单个刹时向量,生成新的向量:

  • sum(总和)
  • min(最小)
  • max(最大)
  • avg(平均值)
  • group(分组)
  • stddev(标准偏差)
  • stdvar(规范方差)
  • count(计算向量中的元素个数)
  • count_values(计算具备雷同值的元素个数)
  • bottomk(样本值的最小 k 个元素)
  • topk(按样本值计算的最大 k 个元素)
  • quantile(分位数计算 φ-quantile (0 ≤ φ ≤ 1)

聚合运算符可通过 without、by 依据标签扩大

summinmaxavg

计算 http 申请的总和,最大、最小申请的 url 的数量,均匀数量

sum(prometheus_http_requests_total)

通过状态码别离统计

group:

类 uniq 的用法

stddevstdvar

反映一组数据离散水平,用以掂量数据值偏离算术平均值的水平。标准偏差为方差的开平方,标准偏差越小,这些值偏离平均值就越少,反之亦然。

通过标准差来反映网络稳定

stddev(rate(node_network_transmit_bytes_total[5m]))

rate 计算某段时间的速率

countcount_values:

统计总共有几个时序

count(prometheus_http_requests_total)

计算每个 value 的数量

count_values("value",prometheus_http_requests_total)

bottomktopk

计算 value 中最小的 5 个时序

bottomk(5,prometheus_http_requests_total)

quantile: 求数据的分位数

咱们当初要找出 K8s 集群中所有 node 节点的内存使用率的散布状况

quantile
(0.8,
(
1 -
node_memory_MemAvailable_bytes{job="kubernetes-service-endpoints"} 
/ node_memory_MemTotal_bytes{job="kubernetes-service-endpoints"}
)
* 100
)

间接能够看出 80% 的节点内存使用率在 68% 以下

函数


值取整

ceil()

ceil(v instant-vector)样本数据向上取整。

ceil(node_load1)  #1.2-->2

floor()

floor(v instant-vector)与 ceil()相同,floor()样本值向下取整。

round()

round(v instant-vector, to_nearest=1 scalar) 对样本值四舍五入取整。to_nearest 参数是可选的, 默认为 1, 示意样本返回的是最靠近 1 的整数倍的值,参数能够为分数。

取整

round(prometheus_engine_query_duration_seconds_sum)

取整到最近的 5 的倍数

round(prometheus_engine_query_duration_seconds_sum,5)
值截取

clamp()

clamp(v instant-vector, min scalar, max scalar) 截取所有元素的样本值在 [min,max]汇合内的样本, 如果 min>max 返回 NaN

放回样本值在 10 到 20 的样本

clamp(prometheus_http_requests_total,10,20)

clamp_max()

clamp_max(v instant-vector, max scalar) 同 clamp(),不过只限定样本最大值

clamp_min()

clamp_min(v instant-vector, min scalar) 同 clamp(),不过只限定样本最小值

值变动统计

changes()

changes(v range-vector)返回某段时间内样本值扭转的次数

changes(node_load1[1m])  
复位统计

resets()

resets(v range-vector) 返回样本范畴工夫内的复位次数。与 counter 应用,两个间断样本之间值如有缩小则被视为计数器复位。

查看上下文替换次数计数器在 5 分钟内复位次数

resets(node_context_switches_total[5m])
日期与工夫治理

day_of_month()

day_of_month(v=vector(time()) instant-vector)如果样本值是 utc 工夫,则返回这个工夫所属月份中的日期(1-31)

v=vector(time()) 为默认参数

day_of_month(node_boot_time_seconds)

day_of_week()

day_of_week(v=vector(time()) instant-vector) 同上,如果样本值是 utc 工夫,则返回这个工夫所属星期几(0-6)

days_in_month()

days_in_month(v=vector(time()) instant-vector) 如果样本值是 utc 工夫,则返回这个工夫所属月份的天数(28-31)

hour()

hour(v=vector(time()) instant-vector)如果样本值是 utc 工夫,则返回这个工夫所属一天中的第几个小时(1-13)

minute()

minute(v=vector(time()) instant-vector) 如果样本值是 utc 工夫,则返回这个工夫所属小时中的第几分钟(1-59)

month()

month(v=vector(time()) instant-vector)如果样本值是 utc 工夫,则返回这个工夫所属的月份(1-12)

year()

year(v=vector(time()) instant-vector)如果样本值是 utc 工夫,则返回这个工夫所属的年份

time()

返回自 1970 年 1 月 1 日 UTC 以来的秒数,不是零碎工夫,而是表达式计算时那一刻的工夫。

timestamp()

timestamp(v instant-vector)返回每个样本值的工夫戳,自 1970 年 1 月 1 日 UTC 以来的秒数。

直方图分位数

histogram_quantile()

histogram_quantile(φ float, b instant-vector) 从 bucket 类型的向量 b 中计算 φ (0 ≤ φ ≤ 1) 分位数的样本的最大值,与聚合运算符 quantile 类似。

计算 80% 申请的持续时间最大值。

histogram_quantile(0.8,rate(prometheus_http_request_duration_seconds_bucket[1d]))
差别与增长率

delta()

delta(v range-vector)计算范畴向量中每个工夫序列元素的第一个值和最初一个值之间的差。与指标类型 gauge 一起应用

计算一天内内存可用量的变动

delta(node_memory_MemAvailable_bytes[1d])

idelta()

idelta(v range-vector)计算范畴向量中最初两个样本之间的差别。与指标类型 gauge 一起应用

idelta(node_memory_MemAvailable_bytes[1m])

increase()

increase(v range-vector) 计算工夫范畴内的增量,与 counter 一起应用。它是速率 rate(v) 乘以工夫范畴内秒数的语法糖,次要用于人类可读性。

计算 10 分钟内申请增长量

increase(prometheus_http_requests_total[10m])

rate()

rate(v range-vector)计算范畴向量中工夫序列的均匀每秒增长率。

过来 10 分钟申请均匀每秒增长率,与 counter 一起应用。

rate(prometheus_http_requests_total[10m])

irate()

irate(v range-vector) 通过工夫范畴的最初两个点来计算每秒刹时增长率。

irate(prometheus_http_requests_total[10m])
label 治理

label_join()

label_join(v instant-vector, dst_label string, separator string, src_label_1 string, src_label_2 string, ...)为每个工夫序列增加一个 label,值为指定旧 label 的 value 连贯

label_join(up{instance="localhost:9100", job="node"},"new_label","-","instance","job")

后果:

up{instance="localhost:9100", job="node", new_label="localhost:9100-node"}   1

label_replace()

label_replace(v instant-vector, dst_label string, replacement string, src_label string, regex string)从源 label 中获取 value 元素用于增加新的 label

$1 获取正则匹配,匹配值增加到 hello 标签中

label_replace(up{instance="localhost:9100", job="node"},"hello","$1","job","(.*)")

后果:

up{hello="node", instance="localhost:9100", job="node"}       1
预测

predict_linear()

predict_linear(v range-vector, t scalar) 通过简略线性回归预测 t 秒后的样本值,与 gauge 一起应用。

依据过来 1 小时的文件系统残余空间量,预测 1 小时之后的残余空间

predict_linear(node_filesystem_free_bytes[1h],3600)
转换

absent()

absent(v instant-vector)如果向量有元素,则返回一个空向量;如果向量没有元素,则返回值为 1。

设置如下告警表达式:

absent(up{job="node"} == 1)

因为 up{job="node"} 不存在或值不为 1 则告警表达式的值为 1 产生告警

absent_over_time()

absent_over_time(v range-vector)如果范畴向量有元素,则返回一个空向量;如果范畴向量没有元素,则返回值为 1。

如果 up{job=”node1″}在某段时间不存在则返回 1

absent_over_time(up{job="node1"}[1h])

scalar()

scalar(v instant-vector)以标量模式返回该单元素的样本值, 如果输出向量不是正好一个元素,scalar将返回NaN.

vector()

vector(s scalar)将标量作为没有标签的向量返回。

sgn()

sgn(v instant-vector)返回一个向量,其中所有样本值都转换为 1 或 - 1 或 0

定义如下:

如果 v 为正,则为 1

如果 v 为负,则为 -1

如果 v 等于 0,则为 0。

排序

sort()

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

sort_desc()

与 sort()相同,按降序排序。

_over_time()

上面的函数列表容许传入一个范畴向量,返回一个带有聚合的刹时向量:

  • avg_over_time(range-vector): 区间向量内每个度量指标的平均值。
  • min_over_time(range-vector): 区间向量内每个度量指标的最小值。
  • max_over_time(range-vector): 区间向量内每个度量指标的最大值。
  • sum_over_time(range-vector): 区间向量内每个度量指标的求和值。
  • count_over_time(range-vector): 区间向量内每个度量指标的样本数据个数。
  • quantile_over_time(scalar, range-vector): 区间向量内每个度量指标的样本数据值分位数,φ-quantile (0 ≤ φ ≤ 1)
  • stddev_over_time(range-vector): 区间向量内每个度量指标的总体标准偏差。
  • stdvar_over_time(range-vector): 区间向量内每个度量指标的总体规范方差
数学函数

abs()

abs(v instant-vector) 返回样本的绝对值。

sqrt()

sqrt(v instant-vector)计算样本值的平方根。

deriv()

deriv(v range-vector) 应用简略线性回归计算工夫序列在范畴向量中的每秒导数。与指标类型 gauge 一起应用

exp()

exp(v instant-vector)计算样本值的指数函数。

非凡状况:

  • Exp(+Inf) = +Inf
  • Exp(NaN) = NaN

ln()、log2()、log10()

ln/log2/log10(v instant-vector) 计算样本值对数

非凡状况(同实用于 log2/log10):

  • ln(+Inf) = +Inf
  • ln(0) = -Inf
  • ln(x < 0) = NaN
  • ln(NaN) = NaN

holt_winters()

holt_winters(v range-vector, sf scalar, tf scalar)基于拜访向量 v,生成工夫序列数据平滑数据值。平滑因子 sf 越低, 对旧数据越重要。趋势因子 tf 越高,更关怀趋势数据。0<sf,tf<=1。与 gauge 一起应用

三角函数、弧度

  • acos(v instant-vector)
  • acosh(v instant-vector)
  • asin(v instant-vector)
  • asinh(v instant-vector)
  • atan(v instant-vector)
  • atanh(v instant-vector)
  • cos(v instant-vector)
  • cosh(v instant-vector)
  • sin(v instant-vector)
  • sinh(v instant-vector)
  • tan(v instant-vector)
  • tanh(v instant-vector)

角度、弧度转化

  • deg(v instant-vector)
  • pi()
  • rad(v instant-vector)

如果内容有误请斧正。通过博客浏览:iqsing.github.io

参考

[1] Understanding Prometheus Range Vectors: https://satyanash.net/softwar…

[2] promethues: https://prometheus.io/docs/pr…

正文完
 0