【监控】PromQL必知必会
PromQL(prometheus Query Language)是prometheus自己开发的数据查询DSL语言,语言表现非常丰富,内置函数,在日常数据可视化(grafana)及rule告警中使用
1.PromQL数据类型
在Prometheus的表达式语言中,PromQL数据类型归类为以下四种:
- 瞬时向量(instant vector):是指同一时刻的一组时间序列,每个时间序列包含一个样本,所有样本共享相同的时间戳,即每个时序只有一个点
- 区间向量(range vector):是指在任何一个时间范围内的一组时间序列,包含每个时间序列随时间变化的一系列数据点,这时每个时序有多个点
- 标量(scalar),即纯量数据,一个简单的数字浮点值,只有一个数字,没有时许
- 字符串(string):简单字符串值
2.时间序列过滤器
瞬时向量过滤器
允许在指定的时间戳内选择一组时间序列和每个序列的单个样本值。
例如:选择指标名称为node_cpu_seconds_total的所有时间序列
node_cpu_seconds_total
可以加标签过滤,标签匹配模式支持完全匹配和正则匹配:
- =:选择与提供的字符串完全相同的标签
- !=: 选择与提供的字符串不相同的标签
- =~选择正则表达式与提供的字符串(或子字符串)相匹配的标签
- !~ 选择正则表达式与提供的字符串(或子字符串)不匹配的标签
node_cpu_seconds_total{mode=~"idle|user|system",cpu!="0"}
区间向量过滤器
时间范围通过时间选择器[]进行定义。以指定应为每个返回的区间向量样本值中提取多长的时间范围,秒-s、分钟-m、小时-h、天-d、周-w、年-y
例如选择过去5分钟内
node_cpu_seconds_total{instance=“prometheus“,mode=“idle”}[5m]
时间位移操作
在瞬时向量表达式或者区间向量表达式中,都是以当前时间为基准
node_cpu_seconds_total{} #瞬时向量表达式,选择当前最新数据
node_cpu_seconds_total{}[5m] #区间向量表达式,选择以当前时间为基准,5分钟内的数据
那如何查询5分钟以前的数据或昨天一天的区间样本数据?这时使用位移操作,关键字为offset
sum(node_cpu_seconds_total{ instance="prometheus服务器“,mode="idle"} offset 5m)
rate(node_cpu_seconds_total{ instance="prometheus服务器“,mode="idle"}[5m] offset 1w) #一周前的5分钟之内的cpu空闲率
注意:offset关键字要紧跟随在选择器{}后面。以下表示式不合法:
sum(node_cpu_seconds_total{ instance="prometheus服务器“,mode="idle"})offset 5m
3.操作符
二元运算符
- 算数二元操作符:+、-、*、/、%、^等
- 关系运算符:相等(==)等
- 集合运算符:and(并且)、or(或者)、unless(排除)
聚合操作
- sum
- min
- max
- avg(平均值)
- stddev(标准差)
- stdvar(标准差异)
- count(计数)
- count_values(对value进行计数)
- bottomk(样本值最小的k个元素)
- topk(样本值最大的k个元素)
- quantile(分布统计)
这些操作被用于聚合所有标签维度,或者通过without或者by子语句来保留不同的维度
语法:
<aggr-op>([parameter,]<vector expression>)[without|by (<label list>)]
其中只有count_value、quantile、topk、bottomk支持参数parameter
without(排除标签名称)
by(保留标签名称):类似sql的 group by
例如:图中排出cpu、job、mode标签后只剩下instance标签,再对instance标签做sum聚合操作
等价于by(instance)
基于时间的聚合
前面讲的sum()、avg和相关的聚合运算符是从标签维度进行聚合,这些运算符在一个时间内对多个序列进行聚合,但有时候我们可能想在每个序列中按时间间进行聚合,如使尖锐的曲线更平滑,或深入了解一个序列在一段时间内的最大值。
PromQL支持多种基于时间的聚合函数,以下是一些示例:
rate()
: 计算时间序列在每秒内增长的速率。例如,以下查询将计算过去5分钟内名为http_requests_total
的所有时间序列的每秒请求数:
rate(http_requests_total[5m])
irate()
: 类似于rate()
函数,但是在查询开始时间处,计算时间序列的瞬时增长率。例如,以下查询将计算过去5分钟内名为http_requests_total
的所有时间序列的瞬时每秒请求数:
irate(http_requests_total[5m])
irate函数是通过区间向量中最后两个样本数据来计算区间向量的增长速率,相比rate函数提供更高的灵敏度,可以避免在时间窗口范围内的“长尾问题”,更好反映瞬时状态变化。在长期趋势分析或告警中推荐rate函数
delta()
: 计算时间序列最新值与一段时间前的值之间的差异。例如,以下查询将计算过去5分钟内名为node_memory_MemFree_bytes
的所有时间序列的值减去5分钟前的值:
delta(node_memory_MemFree_bytes[5m])
increase()
: 计算时间序列在一段时间内的增长量。例如,以下查询将计算过去1小时内名为http_requests_total
的所有时间序列的总增长量:
increase(http_requests_total[1h])
sum_over_time()
: 计算一段时间内时间序列的值的总和。例如,以下查询将计算过去5分钟内名为node_cpu_seconds_total
的所有时间序列的总和:
sum_over_time(node_cpu_seconds_total[5m])
avg_over_time()
: 计算一段时间内时间序列的值的平均值。例如,以下查询将计算过去1小时内名为http_request_duration_seconds
的所有时间序列的平均响应时间:
avg_over_time(http_request_duration_seconds[1h])
min_over_time()
: 计算一段时间内时间序列的最小值。例如,以下查询将计算过去5分钟内名为node_memory_MemFree_bytes
的所有时间序列的最小值:
min_over_time(node_memory_MemFree_bytes[5m])
max_over_time()
: 计算一段时间内时间序列的最大值。例如,以下查询将计算过去5分钟内名为node_memory_MemFree_bytes
的所有时间序列的最大值:
max_over_time(node_memory_MemFree_bytes[5m])
count_over_time()
: 计算一段时间内时间序列的数据点数量。例如,以下查询将计算过去1小时内名为http_requests_total
的所有时间序列的数据点数量:
count_over_time(http_requests_total[1h])
quantile_over_time()
: 计算一段时间内时间序列的分位数。例如,以下查询将计算过去5分钟内名为http_request_duration_seconds
的所有时间序列的99th分位数:
quantile_over_time(0.99, http_request_duration_seconds[5m])
stddev_over_time()
: 计算一段时间内时间序列的标准差。例如,以下查询将计算过去1小时内名为http_request_duration_seconds
的所有时间序列的标准差:
stddev_over_time(http_request_duration_seconds[1h])
irate() + rate()
:irate()
函数计算瞬时增长率,rate()
函数计算平均增长率。这两个函数可以结合使用,以平滑瞬时增长率并计算更准确的平均增长率。例如,以下查询将计算过去5分钟内名为http_requests_total
的所有时间序列的平均每秒请求数:
rate(irate(http_requests_total[5m])[1m])
4.内置函数
官网介绍
数学函数
- abs
- sqrt:求平方根
时间函数
- timestamp(): 返回当前时间的时间戳。
- time(): 返回当前时间的时间戳,并将其转换为ISO 8601格式的字符串。
- floor(): 将时间戳向下舍入到最近的整数秒。
- ceil(): 将时间戳向上舍入到最近的整数
- offset(): 计算时间序列的偏移量。
预测gauge指标变化趋势函数
- predict_linear(v range-vector,t scalar)预测时间序列v在t秒后的值,它是基于线性回归方式对时间窗口内的样本数据进行统计,从而对时间序列的变化趋势作出预测