|
本帖最后由 lk_yeah 于 2024-7-26 10:28 编辑
这一贴的内容是在PVE的监控页面上添加CPU温度、芯片组温度、CPU频率、硬盘温度。做这项工作其实跟运行的虚拟机无关,不喜欢可以不做。
先放效果
这是PVE节点概要的页面,其中“PVE管理版本”和“存储库状态”之间的内容是我添加的,显示的数字是可以动态更新的。
下面就给出实现方法。
安装温度显示软件lm-sensors
命令行运行
根据提示,按下Y键,等一下就可以了。
然后运行
这条命令的作用是检测该主机上的硬件探测器,并将检测结果添加到/etc/modules中。执行过程会不断询问是否检测某种硬件,基本上一路Y键就可以了。
注意,这条命令中,-之前没有空格,sensors-detect是一个可执行文件,不是某条命令加选项。
检测完成后运行lm-sensors的基本命令就可以输出它监控到的各种硬件数值了。
以上就是我执行sensors命令后显示出的信息,最上面就是CPU温度,然后是主板芯片组的温度,再往下还有各种温度、电压、风扇转速等等,信息相当多。
配置页面
配置页面一共需要修改两个文件:
/usr/share/perl5/PVE/API2/Nodes.pm——这个文件定义变量名
/usr/share/pve-manager/js/pvemanagerlib.js——这个文件是页面代码
温馨提示,修改前备份一下原文件,预防改出问题。
命令行运行
- cp /usr/share/perl5/PVE/API2/Nodes.pm /usr/share/perl5/PVE/API2/Nodes.pm.bak
- cp /usr/share/pve-manager/js/pvemanagerlib.js /usr/share/pve-manager/js/pvemanagerlib.js.bak
复制代码
首先以显示CPU温度为例,讲解下实现原理。
Nodes.pm中搜索shared => $meminfo->{memshared}
添加:
- $res->{cpu_temperatures} = `sensors`;
复制代码 pvemanagerlib.js中搜索textField: 'pveversion'
添加:
- {
- itemId: 'cpu-temperatures',
- colspan: 2,
- printBar: false,
- title: gettext('CPU温度'),
- textField: 'cpu_temperatures',
- renderer:function(value){
- const c0 = value.match(/Core 0.*?\+([\d\.]+)?/)[1];
- const c1 = value.match(/Core 1.*?\+([\d\.]+)?/)[1];
- const c2 = value.match(/Core 2.*?\+([\d\.]+)?/)[1];
- const c3 = value.match(/Core 3.*?\+([\d\.]+)?/)[1];
- const c4 = value.match(/Core 4.*?\+([\d\.]+)?/)[1];
- const c5 = value.match(/Core 5.*?\+([\d\.]+)?/)[1];
- const p0 = value.match(/Package id 0.*?\+([\d\.]+)?/)[1];
- return `Package: ${p0}℃; Core 0: ${c0}℃; Core 1: ${c1}℃; Core 2: ${c2}℃; Core 3: ${c3}℃; Core 4: ${c4}℃; Core 5: ${c5}℃`
- }
- },
复制代码
解释一下:
第一段中
cpu_temperatures为变量名;sensors为可执行命令,就是可以运行于Linux命令行的命令。
第二段中
itemId随便定义,只要在这个文件中不重复就行;title中的汉字就是页面左侧显示的文字;textField要跟第一段中变量名一致;后面的函数中,Core 0、Core 1之类的,是sensors命令执行后获取到的内容中,CPU核心温度的键名,具体请参看我上面的贴图,return句是显示输出的结果。
总结一下,两段代码就是从第一段的可执行命令中获取到的内容中,取相应的值按第二段返回语句显示出来。
温馨提示,每段代码最后的逗号分号一定不要忘记,缺了就报错了。
显示CPU温度的代码用到了lm-sensors。大家不要原样抄我的,我的CPU是8700,6核的,请根据自己的实际情况修改。
同理,大家可以根据自己的需要,把lm-sensors显示出的其他信息,比如电压、风扇转速等添加进来。
明白了原理后,我下面再给出显示CPU频率、固态盘温度、机械盘温度的代码。当然了,这些代码都是我从网上白嫖来的。
Nodes.pm添加:
- $res->{cpu_frequency} = `lscpu|grep MHz`;
- $res->{nvme_ssd_temperatures} = `smartctl -a /dev/nvme?|grep -E "Model Number|Total NVM Capacity|Temperature:|Percentage|Data Unit|Power On Hours"`;
- $res->{hdd_temperatures} = `smartctl -a /dev/sd?|grep -E "Model|Capacity|Power_On_Hours|Temperature"`;
复制代码 pvemanagerlib.js添加:
- {
- itemId: 'cpu-frequency',
- colspan: 2,
- printBar: false,
- title: gettext('CPU频率'),
- textField: 'cpu_frequency',
- renderer:function(value){
- const f0 = value.match(/CPU MHz.*?([\d]+)/)[1];
- const f1 = value.match(/CPU min MHz.*?([\d]+)/)[1];
- const f2 = value.match(/CPU max MHz.*?([\d]+)/)[1];
- return `实时: ${f0} MHz; 最小: ${f1} MHz; 最大: ${f2} MHz`
- }
- },
- {
- itemId: 'nvme_ssd-temperatures',
- colspan: 2,
- printBar: false,
- title: gettext('NVME硬盘'),
- textField: 'nvme_ssd_temperatures',
- renderer:function(value){
- if (value.length > 0) {
- let nvmedevices = value.matchAll(/^Model.*:\s*([\s\S]*?)(\n^Total.*\[[\s\S]*?\]$|\s{0}$)\n^Temperature:\s*([\d]+)\s*Celsius\n^Percentage.*([\d]+\%)\n^Data Units.*\[([\s\S]*?)\]\n^Data Units.*\[([\s\S]*?)\]\n^Power.*:\s*([\s\S]*?)\n/gm);
- for (const nvmedevice of nvmedevices) {
- for (var i=5; i<8; i++) {
- nvmedevice = nvmedevice.replace(/ |,/gm, '');
- }
- if (nvmedevice[2].length > 0) {
- let nvmecapacity = nvmedevice[2].match(/.*\[([\s\S]*?)\]/);
- nvmecapacity = nvmecapacity[1].replace(/ /, '');
- value = `${nvmedevice[1]} | 已使用寿命: ${nvmedevice[4]} (累计读取: ${nvmedevice[5]}, 累计写入: ${nvmedevice[6]}) | 容量: ${nvmecapacity} | 已通电: ${nvmedevice[7]}小时 | 温度: ${nvmedevice[3]}°C\n`;
- }
- else {
- value = `${nvmedevice[1]} | 已使用寿命: ${nvmedevice[4]} (累计读取: ${nvmedevice[5]}, 累计写入: ${nvmedevice[6]}) | 已通电: ${nvmedevice[7]}小时 | 温度: ${nvmedevice[3]}°C\n`;
- }
- }
- return value.replace(/\n/g, '<br>');
- }
- {
- return `提示: 未安装硬盘或已直通硬盘控制器`;
- }
- }
- },
-
- {
- itemId: 'hdd-temperatures',
- colspan: 2,
- printBar: false,
- title: gettext('SATA硬盘'),
- textField: 'hdd_temperatures',
- renderer:function(value){
- if (value.length > 0) {
- let devices = value.matchAll(/(\s*Model.*:\s*[\s\S]*?\n){1,2}^User.*\[([\s\S]*?)\]\n^\s*9[\s\S]*?\-\s*([\d]+)[\s\S]*?(\n(^19[0,4][\s\S]*?$){1,2}|\s{0}$)/gm);
- for (const device of devices) {
- if(device[1].indexOf("Family") !== -1){
- devicemodel = device[1].replace(/.*Model Family:\s*([\s\S]*?)\n^Device Model:\s*([\s\S]*?)\n/m, '$1 - $2');
- }
- else {
- devicemodel = device[1].replace(/.*Model:\s*([\s\S]*?)\n/m, '$1');
- }
- device[2] = device[2].replace(/ |,/gm, '');
- if(value.indexOf("Min/Max") !== -1){
- let devicetemps = device[5].matchAll(/19[0,4][\s\S]*?\-\s*(\d+)(\s\(Min\/Max\s(\d+)\/(\d+)\)$|\s{0}$)/gm);
- for (const devicetemp of devicetemps) {
- value = `${devicemodel} | 容量: ${device[2]} | 已通电: ${device[3]}小时 | 温度: ${devicetemp[1]}°C\n`;
- }
- }
- else if (value.indexOf("Temperature") !== -1){
- let devicetemps = device[5].matchAll(/19[0,4][\s\S]*?\-\s*(\d+)/gm);
- for (const devicetemp of devicetemps) {
- value = `${devicemodel} | 容量: ${device[2]} | 已通电: ${device[3]}小时 | 温度: ${devicetemp[1]}°C\n`;
- }
- }
- else {
- value = `${devicemodel} | 容量: ${device[2]} | 已通电: ${device[3]}小时 | 提示: 未检测到温度传感器\n`;
- }
- }
- return value.replace(/\n/g, '<br>');
- }
- else {
- return `提示: 未安装硬盘或已直通硬盘控制器`;
- }
- }
- },
复制代码 经过测试,主机中安装的每个硬盘,都需要一段单独的代码,注意修改响应的设备名称,就是类似“/dev/sda”、“/dev/nvme0n1”这样的名称,可以通过lsblk命令查看。
差点忘了,还要在命令行执行一下提权命令,不然也会出问题。
- chmod +s /usr/sbin/smartctl
复制代码
还需要调整下页面高度,不然会显示不完全。
pvemanagerlib.js中搜索widget.pveNodeStatus
这个高度值请大家自己根据自己的情况进行调整。
搜索gettext('Status') + ': ' + zpool
这个高度值网上很多教程都提到了需要改,但我测试的结果改了没用,所以我没改。大家可以自己尝试。
修改了Nodes.pm文件,需要使用命令行运行下面命令重启API代理守护进程使修改生效,仅修改js文件,无需运行。
- systemctl restart pveproxy
复制代码 温馨提示,浏览器测试修改效果别忘了Ctrl+F5。
|
评分
-
查看全部评分
|