PromQL语句
PromQL语句:
promql是内置的数据查询语言,使用表达式来查询
根据指标和标签,以及时间范围,表达式的查询可覆盖在一个时间序列,或只包含单个时间序列的单个样本
采集的数据是float64格式,毫秒精度的时间戳
采集cadvisor指标的语句: https://www.iteye.com/blog/yjph83-2394091
语法格式:
函数(
{
指标名称:
通常用于描述系统上要测定的某个特征,支持使用字母、数字、下划线和冒号,且必须能匹配RE2规范的正则表达式
http_requests_total #表示接收到的HTTP请求总数
标签:
键值型数据,附加在指标名称之上,从而让指标能够支持多纬度特征,可选项
标签名称可使用字母、数字和下划线,且必须能匹配RE2规范的正则表达式
以“_ _”为前缀的名称为Pro系统预留使用
http_requests_total{method=GET} #所有get请求
http_requests_total{method=POST} #所有post请求
注意:
指标名称和标签的特定组合代表一个时间序列
- 指标名称相同,但标签不同的的组合分别代表不同的时间序列
- 不同的指标名称代表不同的时间序列
promql支持基于定义的指标标签进行过滤和聚合
- 更改任何标签值,包括添加或删除标签,都会创建一个新的时间序列
- 尽可能保持标签的稳定性,否则很可能创建新的时间序列,更甚者会生成一个动态的数据环境,并使得监控的数据源难以跟踪,从而导致建立在该指标之上的图形、告警及记录规则变得无效
函数:
普通函数:
abs()
abs(即时向量) #返回样本的绝对值
absent()
absent(即时向量) #非空指标返回0,空返回1。可用来做报警判断
ceil()
ceil(即时向量) #对样本数据四舍五入,向上取整
node_load1{instance=`2.2.2.20`} #结果为:0.04
ceil(node_load1{instance=`2.2.2.20`}) #结果为:1
changes()
changes(区间向量) #对区间向量的指标数据,进行变化统计
changes(node_load1{instance=`2.2.2.20`}[1m]) #1分钟负载变化次数,如0.1变0.5,算1次
clamp_max()
clamp_max(即时向量,最大值) #返回数据<最大值,就是原始数据;返回数据>最大值,就是最大值
clamp_max(node_load1{instance=`2.2.2.20`},2) #1分钟负载小于2就是原始值,大于2就是给定的2
day_of_month()
day_of_month(即时向量)
#返回被给定 UTC 时间所在月的第几天。返回值范围:1~31
day_of_month(container_start_time_seconds{container=`prometheus`,pod=`prometheus-k8s-0`})
day_of_week()
day_of_week(即时向量) #返回被给定 UTC 时间所在周的第几天。返回值范围:0~6,0为星期天
days_in_month()
days_in_month(即时向量) #返回当月一共有多少天。返回值范围:28~31
hour()
hour(即时向量) #返回被给定 UTC 时间的当前第几个小时,时间范围:0~23
minute()
minute(即时向量) #回给定 UTC 时间当前小时的第多少分钟。结果范围:0~59
month()
month(即时向量) #返回给定 UTC 时间当前属于第几个月,结果范围:0~12
yeat()
year(即时向量) #返回被给定 UTC 时间的当前年份
delta()
delta(区间向量) #返回一个即时向量,计算区间向量最后一个样本和第一个样本值的差
delta(instance:node_cpu:rate:sum{instance=`2.2.2.10`}[1d])
delta(cpu_temp_celsius{host="zeus"}[2h]) #cpu过去2小时的温度差
floor()
floor(即时向量) #与ceil函数相反,向下四舍五入取整
deriv()
deriv(区间向量) #返回即时向量,使用简单的线性回归计算区间向量中各个时间序列的导数
exp()
exp(即时向量) #返回各个样本值的e的指数值,即 e 的 N 次方。当 N 的值足够大时会返回
+Inf
特殊情况:
Exp(+Inf) = +Inf
Exp(NaN) = NaN
histogram_quantile()
官方文档: https://prometheus.io/docs/practices/histograms/
histogram_quantile(中位数,即时向量) #求中位数在即时向量中的最大占比
histogram_quantile(0.5, http_request_duration_seconds_bucket) #http请求中,50%的请求是多少秒
holt_winter()
holt_winter(区间向量,平滑因子,趋势因子) #生成时间序列数据平滑值。平滑因子越低, 对旧数据的重视程度越高。趋势因子越高,对数据的趋势的考虑就越多
idelta()
idelta(区间向量) #返回即时向量,计算最新的 2 个样本值之间的差值。一般用在Gauge类型的时间序列上
increase()
increase(区间向量) #获取区间向量中的第一个和最后一个样本并返回其增长量
increase(prometheus_http_requests_total{job=`prometheus-k8s`}[5m])
rate()
rate(区间向量) #计算平均增长速率
rate(http_requests_total[5m]) #过去5分钟内HTTP请求数的每秒增长率
itate()
irate(区间向量) #计算区间向量的增长率,返回结果是即时向量,计算最后两个数据
irate(prometheus_http_requests_total{job=`prometheus-k8s`,code='200'}[5m]) #5分钟内200状态码增长速率
注意:
- irate只能用于绘制快速变化的计数器,在长期趋势分析或者告警中更推荐使用 rate 函数。因为使用 irate 函数时,速率的简短变化会重置 FOR 语句,形成的图形有很多波峰,难以阅读
- 当将 irate() 函数与聚合函数或随时间聚合的函数(任何以 _over_time 结尾的函数)一起使用时,必须先执行 irate 函数,然后再进行聚合操作,否则当采样目标重新启动时 irate() 无法检测到计数器是否被重置
label_join()
label_join(即时向量,新标签,连接符,源标签) #新建标签
label_join(up{instance=`10.20.104.1:9153`},"xxx",",","job","namespace") #新建xxx标签,值为:job和namespace的值,两者的值用","号分割
label_replace()
label_replace(即时向量, 新标签, 替换内容, 源标签, 正则匹配) #对源标签进行正则匹配,替换到新标签
label_replace(up,"host","$1","instance","(.*):.*") #正则匹配instance标签,将匹配的样本值赋值给新表情host
ln()
ln(即时向量) #计算所有样本数据的自然对数
特殊情况:
ln(+Inf) = +Inf
ln(0) = -Inf
ln(x < 0) = NaN
ln(NaN) = NaN
log2()
log2(即时向量) #所有样本数据的二进制对数。特殊情况同上
log10()
log10(即时向量) #所有样本数据的十进制对数。特殊情况同上
predict_linear()
predict_linear(区间向量, 秒) #预测区间向量在n秒后的趋势走向
predict_linear(node_filesystem_free_bytes{job=`node-exporter`}[2h], 4 * 3600) < 0 #基于2小时的样本数据,来预测主机可用磁盘空间的是否在4个小时候被占满
predict_linear(http_requests_total{code="200",instance="120.77.65.193:9090",job="prometheus",method="get"}[5m], 5) #基于5m的数据,预测5秒promtheus的200状态码访问量
resets()
resets(区间向量) #对于每个时间序列,都返回一个计数器重置的次数。两个连续样本之间的值的减少被认为是一次计数器重置。只用在计数器类型的时间序列上
scalar()
scalar(即时向量) #返回唯一的时间序列的值作为一个标量。如果度量指标的样本数量大于 1 或者等于 0, 则返回
NaN
sort()
sort(即时向量) #按元素的值进行升序排序,返回结果:key: value = 度量指标:样本值[升序排列]
sort_desc()
sort_desc(即时向量) #按元素的值进行降序排序,返回结果:key: value = 度量指标:样本值[降序排列]
sqrt()
sqrt(即时向量) #计算向量中所有元素的平方根
time()
time() #返回从 1970-01-01 到现在的秒数
timestamp()
timestamp(即时向量) #返回向量中的每个样本的时间戳(从 1970-01-01 到现在的秒数)
vector()
vector(标量) #将标量作为没有标签的向量返回,即返回结果为:key: value= {}, s
聚合函数:
有11个,仅支持单个即时向量
sum() #求和
avg() #平均值,常用
count() #分组数量统计
stddev() #标准差,了解数据波动大小
stdvar() #求方差,求取标准差过程中的中间状态
min() #最小值
max() #最大值
topk() #逆序返回分组的最大的前n个时间序列和值
bottomk() #分位数,用于评估数据的分布状态,返回分组内指定的分位数的值,即数值落在小于指定的区间的比例
count_values() #分组时间序列的样本值进行统计
quantile() #分位数
分组聚合(关联词):
聚合函数(指标{}) [without|by] (标签)
without:
从结果中删除由without子句指定的标签,未指定的标签就是分组的标准
by:
使用by子句中指定的标签进行聚合,结果中的内容没有匹配指定标签就被忽略
为保留上下文信息,用by时,要指定结果中原本出现的job、instance等
数据类型:
即时向量:
特定时间序列集合上具有相同时间戳的一组样本值称为即时向量
即时向量选择器:
- 指标名称: 用于限定特定指标下的时间序列,即负责过滤指标;可选;
- 匹配器(Matcher): 或称为标签选择器,用于过滤时间序列上的标签;定义在{}之中;可选
3种组合使用方法:
只给指标名称或匹配择器为空:
- 返回指标名称下的所有标签的即时样本数据
- 返回所有指标数据
http_requests_total = http_requests_total{}
只给匹配器:
- 返回所有匹配器的所有即时样本数据
{job='.*',method='get'} #返回所有标签名是job,且标签metheod=get的指标数据
指标名加匹配器:
http_requests_total{method='get'}
范围(区间)向量:
特定或全部的时间序列集合上,在指定的同一时间范围内的所有样本值
需要在表达式后面跟一个时间范围,用: [时间]
[5m] #当前时间 ~ 前5分钟的区间
时间单位:
必须用整数时间,但可以组合使用
ms、s、m、h、d、w、y
例:
[1d6h]
[1h50m]
偏移量修改器:
默认情况,以当前时间为准。用偏移量后,可指定历史某个时间点为准
在表达式后使用: offset
http_requests_total offset 5m #过去5分钟时间点的数据,如当前为11:05,则采集11:00的数据
http_requests_total[5m]offset 1d #获取当前时间点,1天前的5分钟内的数据
标量(Scalar):
- 一个浮点型的数据值
- 字符串(String):支持使用单引号、双引号或反引号进行引用,但反引号中不会对转义字符进行转义
向量表达式要点:
- 需要将返回值绘制成图形时,仅支持即时向量类型的数据(可直接绘图)
- 对于诸如rate一类的速率函数来说,其要求使用的却又必须是范围向量型的数据(用函数后间接绘图)
匹配器:
操作符:
=
!= 不等于
=~ 正则匹配
!~ 取反
注:
匹配到空标签值时,所有时间序列都匹配,包含没有这个标签的也会匹配
正则匹配需要指定整个值
至少有一个指标名称或非空的标签
使用"name"作为标签时,可对指标名称进行过滤
{__name__=~"http_requests_.*"} = http_requests_所有
运算符:
支持的运算:
- 两个标量的运行
- 即时向量和标量的运行:运算符匹配到每个样本
- 两个即时向量运行: 遵循向量匹配机制。可基于向量匹配模式,定义运算机制
运算符:
+、-、*、/、%、^(幂、乘积)
==、!=、>、<、>=、<=
逻辑:
and、or、unless
向量匹配机制:
比较时,左侧为参照物
1对1
rate(http_requests_total{status_code=~'5.*'}[5m]) > 0.1* rate(http_requests_total[5m]) #各类50X响应码的速率 在 5m内所有各类且请求中的比例
1对多或多对1
做个体在整体中的占比计算
如,全部圆形积木为100个,蓝色10个,红色15个...,求所有颜色积木在圆形积木中的占比
常用指标:
node_memory_MemTotal_bytes #node节点总内存大小
node_memory_MemFree_bytes #节点剩余内存,除缓冲缓存部分
node_memory_Active_bytes #节点可用内存,加缓冲缓存部分
node_disk_io_time_seconds_total #查看m磁盘io
node_filesystem_free_bytes #文件系统剩余空间
node_load1
node_load5
node_load15
案例:
https://www.iteye.com/blog/yjph83-2394091
sum(rate(demo_api_request_duration_seconds_count{job="demo"}[5m])) #demo 服务每秒处理的请求数
max_over_time(
histogram_quantile(0.95, sum by(le, path) (
rate(demo_api_request_duration_seconds_bucket[1m])
)
)[1h:]
) #过去一小时内 demo服务的最大 95 分位数延迟值(1 分钟内平均),按 path 划分
(1-avg(irate(node_cpu_seconds_total{mode='idle'})[5m]) by (instance))*100 #cpu在5m的使用率
node_load1 > on(instance)2*count(node_cpu_seconds_total{mode='idle'}) by(instance) #cpu在1m的饱和度