最近在利用grafana+prometheus监控linux文件系统是否挂载时,碰到了一个比较刺手的问题,就是利用PromQL查询时遇到了返回结果为空的情况,导致panel无法展示信息的情况。
我的需求:
例如lustre文件系统成功挂载时,显示绿色,lustre文件系统没有挂载时,显示红色,表明当前的挂载出现了问题,并且当前的图形的图例要显示该台服务器的主机名。如下所示:
在实现这个功能时,使用了几种方法:
1、通过node_filesystem_size_bytes查询文件系统的可用容量
例如:
node_filesystem_size_bytes{nodename="node0142",fstype="lustre"}
使用该语句查询的结果存在两种情况,一是文件系统存在的话返回正常的结果,二是文件系统不存在的话会返回empty query result;
正常的返回结果:
文件系统不存在的返回结果:
返回结果为Empty query result的时候,上述的显示图就不会在panel中,因为没有数据,整个panel面板就是空的,而我想要的结果是即使是空的,也可以显示主机名,并且状态置为红色,以便一眼就能看出哪些服务器的文件系统掉了。
2、使用vector(0)处理空的返回结果
第一种方法无法处理返回结果为空的情况,因此便想到能否利用某种方法代替默认的行为,例如没有数据的情况就返回0。幸运的是vector(0)语法可以处理这种情况,如下所示:
node_filesystem_size_bytes{nodename="node0142",fstype="lustre"} or vector(0)
利用该方法,当文件系统不存在时,默认的查询结果就是0,而不是empty query result,如图所示:
但不幸的是,该方法返回的结果key-value中,只有value,没有key,这也导致了另外一个问题,我无法获取key中的nodename label去作为显示图标的legend。
呈现的结果是虽然有图展示,但是图例只有value,无法获取服务器的主机名。
3、获取多个文件系统的容量
基于第二种方法出现的问题,此时想可以通过查询多个文件系统的容量,例如挂载文件系统和根文件系统,因为正常的服务器肯定有根文件系统,使得查询的结果中包含nodename的label,如图所示:
这种方式解决的非正常计算节点的问题,此时只需要设置返回结果的阈值,例如挂载文件系统容量为10T,根文件系统为500G,若查询结果为500G,则设置查询结果小于等于500G时,显示红色,也可以达到目的。
但是对于正常挂载文件系统的节点,这样查询的结果则会返回两组键值对向量:
因此这样的结果会导致在panel面板中,会有两个图呈现:
这样的结果也不是想要的,最终结果是想要呈现lustre文件系统的挂载状态。
4、使用max等函数处理多个文件系统查询的结果
既然多个文件系统查询有多个结果,可以用prometheus函数处理查询结果,对结果进行过滤,例如使用max函数获取最大容量的文件系统:
但是这样的结果最终也是查询的key-value向量中缺少key额值,无法对获取key中的label 作为图标的legend。
5、终极解决方法:使用max by方法
max by (nodename)(node_filesystem_size_bytes{nodename="node0001",fstype=~"lustre|rootfs"})
最终返回的查询结果中,既有key,也有value,完美解决了之前的方法中所带来的问题。
最终的文件系统监控状态如图所示:
红色代表相应的文件系统没有挂载的,绿色代表挂载正常。
PS:图中的显示插件是traffic light