用示例学习!利用PromQL灵活绘制图表(Prometheus + Grafana)
背景 –
背景说明
尽管使用Prometheus和Grafana开始进行资源监控是个好主意,但Grafana Labs上的仪表板总感觉不太合适。而且,每个仪表板的查询语句都略有不同,不知道哪个是正确的!
只有一个选项:
使用Prometheus和Grafana开始资源监控后,发现Grafana Labs提供的仪表板不太符合我的需求。而且,每个仪表板的查询语句都不太相同,让我不知道哪个才是正确的!
只要自己好好写查询语句尝试一下!鉴于这一点,我将写一下。如果掌握了这里介绍的三种查询语句,基本上可以应用到各种场景中。
请阅读以上内容。
虽然是基本的事情,但在Grafana绘制图表时所输入的查询语句是Prometheus的PromQL。(起初以为是Grafana的查询语法…)
- Querying basics | Prometheus
node-exporter的指标,如果使用curl打开,会附带帮助信息。还有一个演示网站,你也可以在那里尝试。
- demo.robustperception.io:9100/metrics
Grafana模板化
使用Grafana的模板功能,将变量嵌入到查询中。在定义以下变量的前提下进行描述。
node
クエリの対象とするノード。Prometheusが自動的に付けるinstance
ラベルに対して使用することを想定localhost:8080
interval
クエリで表示する値の単位時間5m
CPU利用率

查询
avg(irate(node_cpu{instance="$node",mode!="idle"}[$interval])) without(cpu)
摘要
显示指定实例($node)在单位时间($interval)内每秒的CPU使用率平均值。另外,对于空闲状态,不显示因为它表示空闲。
普罗米修斯的原始数据片段
# HELP node_cpu Seconds the cpus spent in each mode.
# TYPE node_cpu counter
node_cpu{cpu="cpu0",instance="docker104:9100",job="node",mode="iowait"} 1.57
node_cpu{cpu="cpu0",instance="docker104:9100",job="node",mode="system"} 42.51
node_cpu{cpu="cpu0",instance="docker104:9100",job="node",mode="user"} 74.37
node_cpu{cpu="cpu1",instance="docker104:9100",job="node",mode="iowait"} 5.13
node_cpu{cpu="cpu1",instance="docker104:9100",job="node",mode="system"} 34.1
node_cpu{cpu="cpu1",instance="docker104:9100",job="node",mode="user"} 72.7
每个实例的每个CPU上的CPU使用时间(以秒为单位)以mode为单位存储在node_cpu度量中。
查询解释
-
- 需要的数据是指定实例的mode不为idle的CPU使用时间的最近$interval分钟的数据。
node_cpu{instance=”$node”, mode!=”idle”}[$interval]
此时,将返回mode数量乘以CPU核心数的记录,并将数据作为数组存储为$interval分钟的数据。
将返回的数据转换为每秒的平均增长值。
irate()
此时,将返回mode数量乘以CPU核心数的记录,并将value转换为每秒的平均增长值。
计算所有CPU的平均值。
avg() without(cpu)
无需计算的标签在without子句中指定。这次的标签是cpu、instance、job和mode,我们将忽略cpu,并计算每个模式的平均值。最终将得到所有cpu的平均值。
平均值
avg算子返回每个记录存储的标量值的平均值。如果记录的value是一个数组(范围向量),则不能应用该算子。
rate()和irate()
rate()和irate()函数都用于计算在一定时间范围内获取的数据每秒平均增加了多少。
只需一种选项,以下是中文本地化的释义:
鉴于增量,只有保留某种合计值的指标,诸如node_cpu或http_requests_total等,适用于此函数。
rate(v range-vector)计算范围向量中时间序列的每秒平均增长率。
irate(v range-vector)计算范围向量中时间序列的每秒瞬时增长率。
查询功能 | Prometheus
没有和通过
如上所述,without子句会忽略指定的标签并应用聚合函数。实际执行without(cpu)的情况下,原始数据将变为以下状态,即缺少cpu标签。
{instance="docker104:9100",job="node",mode="user"} 0.0005000000000002558
反过来,通过“by”语句,即忽略其他标签,仅针对指定的标签应用聚合函数。执行“by(mode)”会使除mode之外的所有标签都消失。
{mode="user"} 0.0005000000000002558
这次有4个标签,实例和作业标签是固定的。换句话说,只通过查看返回的记录中的值,无CPU和按模式分类的结果将是相同的。
CPU核心数量

以下的查询都会返回相同的值。
count(count (node_cpu{instance="$node"}) by(cpu))
count(node_cpu{instance="$node", mode="system"})
简要梗概
没有直接返回CPU核心数的指标。node_cpu指标按照每个CPU的使用率返回,可以利用它来计算。
查询解释
count(count (node_cpu{instance="$node"}) by(cpu))
-
- 获取指定实例的最近的node_cpu指标。
-
- node_cpu{instance=”$node”}。
-
- 在这个时间点上,将返回模式数 x CPU核心数的记录,并将最近的数据存储为标量值。
-
- 按CPU计算指标的数量。
-
- count() by(cpu)。
-
- 在这一点上,将按每个CPU返回system,user等CPU使用率数据的数量。由于这个数量不是目标值,所以将其忽略。
-
- 计算CPU的数量。
- count()。
count(node_cpu{instance="$node", mode="system"})
-
- 获取指定实例的mode=”system”的指标
-
- node_cpu{instance=”$node”, mode=”system”}
-
- 此时,会返回每个CPU核心的system使用率
-
- 数CPU的数量
- count()
可用内存

( avg_over_time(node_memory_MemFree{instance=~"$node"}[$interval])
+ avg_over_time(node_memory_Buffers{instance=~"$node"}[$interval])
+ avg_over_time(node_memory_Cached{instance=~"$node"}[$interval])
) / node_memory_MemTotal{instance=~"$node"} * 100
概述
如果您所使用的Linux内核版本在3.14及以上,您可以使用node_memory_MemAvailable指标来检查可用内存量。但需要考虑到可能存在一些不符合该条件的主机。
解释查询
由于重复的原因,只解释以下部分。
avg_over_time(node_memory_MemFree{instance=~"$node"}[$interval])
-
- 获取指定实例在最近的$interval分钟内的node_memory_MemFree指标
node_memory_MemFree{instance=~”$node”}[$interval]
在此时刻,将返回一个记录,其中value数组中包含了$interval分钟的所有数据
获取获取到的value的平均值
avg_over_time()
平均值的时间内 ()
如果您想要获取在某个时间范围内获取的数据中,每个数据的平均值,可以使用avg_over_time()函数。上述的rate()函数系列可能会出现很多示例,可能会让人难以理解,但这个函数可以简单地计算出时间范围的平均值。
概括起来
在Prometheus的指标中,存在不同的数据类型,即使我们说“平均”,计算的方法也有很多种。另外,指标既可以表示当前值,也可以表示总计值,因此只要理解这些方面,就可以轻松地编写代码了。