就如同SQL中有一些内置函数,PromQL中也存在一些函数,我们可以在进行PromQL表达式进行使用,完成一些数据的处理。
学习函数前至少需要知道如下概念,因为函数的概念和传入的数据类型有关
http_requests_total
http_requests_total[5m]
count(http_requests_total)
1、常用聚合函数
sum (求和)、min (最小值)、max (最大值)、avg (平均值)
count (样本数量计数)、bottomk (样本值最小的 k 个元素)、topk (样本值最大的k个元素,和bottomk正好相反,用法一致)
案例:count,计算大于12189696的样本数量,如下,结果有4个
案例:bottomk(2,key),如下,查出最小的两个值
案例:topk(3,key)
2、其它
stddev (标准差)
stdvar (标准差异)
count_values (对 value 进行计数)
quantile (分布统计)
absent(v instant-vector) :传入一个瞬时非空向量则返回空向量,否则返回不带名称值为1的指标,用来监控空数据的情况,即nodata监控
ceil(v instant-vector) :四舍五入取整
floor(v instant-vector) :与 ceil() 函数相反,舍弃小数部分取整
ceil函数:
floor函数:
rate(v range-vector) :用于计算区间向量平均增长率,如计算QPS
参考:prometheus -- rate()与irate()分析与源码 - SegmentFault 思否
计算方法:
irate(v range-vector) :使用rate计算快速变化的样本平均增长率时,容易陷入长尾问题,因为它用平均值将峰值削平了,无法反映时间窗口内样本数据的快速变化。与rate类似,irate同样可以计算counter的平均增长率,但其反映出的是瞬时增长率。irate计算增长率时,使用指定时间范围内的最后两个样本数据
delta(v range-vector) :参数是一个区间向量,返回一个瞬时向量。它计算一个区间向量 v 的第一个元素和最后一个元素之间的差值
idelta(v range-vector) :参数是一个区间向量, 返回一个瞬时向量。它计算最新的 2 个样本值之间的差值。(当区间内仅有一个向量时无返回值)
increase(v range-vector) 函数获取区间向量中的第一个和最后一个样本并返回其增长量,它会在单调性发生变化时(如由于采样目标重启引起的计数器复位)自动中断。
abs(instant-vector) 求瞬时向量绝对值
changes(v range-vector) 计算区间向量中每个样本值变化次数,返回的是瞬时向量
clamp_max(v instant-vector, max scalar) 瞬时向量值如果大于max 则值修改为max,否则值不变(用于将向量规范到一个不大于max的区间内)
clamp_min(v instant-vector, min scalar) 同理,将向量规范到一个不小于min值的范围内
day_of_month(v=vector(time()) instant-vector) 返回 1~31 向量所在UTC时间中的所在月份的第几天
day_of_week(v=vector(time()) instant-vector) 函数,返回被给定 UTC 时间所在周的第几天。返回值范围:0~6,0 表示星期天。
days_in_month(v=vector(time()) instant-vector) 函数,返回当月一共有多少天。返回值范围:28~31。
deriv(v range-vector) 的参数是一个区间向量,返回一个瞬时向量。它使用简单的线性回归计算区间向量 v 中各个时间序列的导数。
exp(v instant-vector) 函数,输入一个瞬时向量,返回各个样本值的 e 的指数值,即 e 的 N 次方。当得到一个无穷大的值,显示 +Inf, 反之显示0, e的负数次方无限趋进0。e的空向量指数依然为空向量。
year(v=vector(time()) instant-vector) 函数返回被给定 UTC 时间的当前年份。
hour(v=vector(time()) instant-vector) 函数返回被给定 UTC 时间的当前第几个小时,时间范围:0~23。
minute(v=vector(time()) instant-vector) 函数返回给定 UTC 时间当前小时的第多少分钟。结果范围:0~59。
month(v=vector(time()) instant-vector) 函数返回给定 UTC 时间当前属于第几个月,结果范围:0~12。
label_join(v instant-vector, dst_label string, separator string, src_label_1 string, src_label_2 string, ...) 函数可以将时间序列 v 中多个标签 src_label 的值,通过 separator 作为连接符写入到一个新的标签 dst_label 中。可以有多个 src_label 标签。
1 2 |
|
label_replace(v instant-vector, dst_label string, replacement string, src_label string, regex string) 在原标签中匹配字符,放到目标标签中
ln(v instant-vector) 计算瞬时向量 v 中所有样本数据的自然对数。
1 2 3 4 |
|
log2(v instant-vector) 函数计算瞬时向量 v 中所有样本数据的二进制对数。特殊情况同ln。
log10(v instant-vector) 计算瞬时向量 v 中所有样本数据的十进制对数。特殊情况同ln。
predict_linear(v range-vector, t scalar) 函数可以预测时间序列 v 在 t 秒后的值。它基于简单线性回归的方式,对时间窗口内的样本数据进行统计,从而可以对时间序列的变化趋势做出预测。
resets(v range-vector) 的参数是一个区间向量。对于每个时间序列,它都返回一个计数器重置的次数。两个连续样本之间单调性发生变化被认为是一次计数器重置。
round(v instant-vector, to_nearest=1 scalar) 函数与 ceil 和 floor 函数类似,返回向量中所有样本值的最接近to_nearest值整数倍的值,当to_nearest=1时等价于ceil。
scalar(v instant-vector) 函数返回一个单元素瞬时向量的样本值,当多元素或者没有元素返回Nan。
vector(s scalar) 函数将标量 s 作为没有标签的向量返回(和scalar作用刚好相反)。
sort(v instant-vector) 函数对向量按元素的值进行升序排序。
sort_desc(v instant-vector) 函数对向量按元素的值进行降序排序。
sqrt(v instant-vector) 函数计算向量 v 中所有元素的平方根。
timestamp(v instant-vector) 函数返回向量 v 中的每个样本的时间戳(从 1970-01-01 到现在的秒数)。
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) : 区间向量内每个度量指标的样本数据个数。
到此所有常用函数都介绍完了,还有一些少见的如直方图等请查阅prometheus官网文档。
on, ignore, group_left, group_right
基础的模式是这样:
第一个vector的标签:{name, instance, service, method, host},第二个vector的标签{name, instance, service, method}
vector_1
这种就会去找两个vector标签和标签值都完全匹配的条目来做op这个操作。
on
vector_1
这个函数会只在前面和后面都出现的标签上面做完全匹配.
vector_1 + on(instance) vector_2:就只会找都有instance标签并且instance的值相同的条目进行计算
ignoring
这个函数跟on相反,忽略对一些标签的匹配
vector_1 + ignoring(instance) vector_2:忽略instance标签,其他的按照默认的情况匹配
group_left
针对第一个vector筛选出来的条目更多,但是两个vector的label可能不匹配,所以需要on或者ignore来限定标签。
左边和右边是1:N的关系
vector_1 + ignore(instance,host) group_left vector_2:这个就代表在忽略instance和host的情况下,左边的vector可能会多出一些条目跟右边的一条条目匹配并作运算。
和张羽确认了下,就是将右边的标签加到左边的,但是一般结合on使用,如下:
group_left作用即是将左右pod相同的情况,把右边的label_qke_cloud_qiyi_domain_app_id和label_qke_cloud_qiyi_domain_app_name两个标签加到左边,加过去之后就可以用sum by求和了
sum by (label_qke_cloud_qiyi_domain_app_id, label_qke_cloud_qiyi_domain_app_name) (rate(http_server_requests_seconds_count{}[5m]) * on (pod) group_left(label_qke_cloud_qiyi_domain_app_id, label_qke_cloud_qiyi_domain_app_name) kube_pod_labels{label_qke_cloud_qiyi_domain_app_name=\"hubble-biz-log\"})
比如:http_server_requests_seconds_count,搜索发现并不含label_qke_cloud_qiyi_domain_app_id
我们再搜索下kube_pod_labels:是包含label_qke_cloud_qiyi_domain_app_id 和 label_qke_cloud_qiyi_domain_app_name两个标签的,所以解释起来就合理了,就是将
还没完,还有多对一的关系:
我们看pod:我们发现,http_server_requests_seconds_count相同的pod是很多的,如下:
再看kube_pod_labels{pod="biz-alarm-query-pod-6888f58676-xqk4j"},如下图所示:pod是唯一的。
所以左边和右边是1:N的关系,所以是将右边的两个指标加到左边所有pod相同的指标中去
验证下:rate(http_server_requests_seconds_count{}[5m]) * on (pod) group_left(label_qke_cloud_qiyi_domain_app_id, label_qke_cloud_qiyi_domain_app_name) kube_pod_labels{label_qke_cloud_qiyi_domain_app_name="hubble-biz-log"}
如下图,标签确实被加进来了
顺便记录下:
kube_pod_labels是kube-state-metrics(kube-state-metrics - 滴滴滴 - 博客园)暴露出来的指标,K8S集群相关的指标是由kube-state-metrics暴露的;
另外,以container_开头的指标是由cAdvisor(集成在kubelet内,用作容器监控)暴露出来的指标
group_right:跟上面的group_left相反。
参考:
PromQL内置函数
Prometheus杂七杂八的东西_Greetlist的博客-CSDN博客_prometheus unless
如何处理PromeQL一对多的运算_运维打怪晋级之路的博客-CSDN博客_promeql