找回密码
 register

QQ登录

只需一步,快速开始

[*网络运维*] Proxmox VE 8.2.2(PVE) 纯手工在系统概要中显示CPU温度的思路方法

[复制链接]

[*网络运维*] Proxmox VE 8.2.2(PVE) 纯手工在系统概要中显示CPU温度的思路方法

[复制链接]
Waylee

主题

0

回帖

1万

积分

仙帝

积分
10124
Waylee 2024-9-1 21:21 | 显示全部楼层 |阅读模式

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

×
最近我的PVE上的虚拟机频繁重启,甚至PVE自身也会重启或者死机。经过一番排除法的验证,我发现是由于小主机的CPU温度过高,导致服务器触发自我保护,所以重启了系统。于是我决定让PVE显示CPU温度信息。
我的需求
首先需要说明的是,PVE系统自身是不会收集硬件温度信息的,所以也就不会显示这些信息,而我要做的就是让它收集并显示出来,配置之后的效果如下:
001.jpg
需要注意的是,由于每个人的硬件不同,所以收集到的信息也不同,那么显示的方式和效果也不同,我这里就是要说清楚这三个问题。
针对这个需求,首先我找了一篇参考文档:让PVE显示CPU温度,这个文档很有用,但是并不能照搬,因为这个文档没有讲清楚配置的原理,所以拿着文档硬抄的大概率就是不行的。
配置步骤
安装sensors
sensors是一个用来显示Linux硬件温度的软件,执行安装命令:
  1. apt install lm-sensors -y
复制代码
如果没有安装到,可能是要配置源,或者更新源,网上随便一搜就知道,也可以 参考我的教程:Proxmox VE 8.2.2 屏蔽订阅企业源 && 修改国内软件源
执行sensors
安装完成后,执行命令探测(所有的选择都输入y,最后一个enter):
  1. sensors-detect
复制代码
然后执行 sensors 命令就可以显示硬件温度信息:
  1. coretemp-isa-0000
  2. Adapter: ISA adapter
  3. Package id 0:  +40.0°C  (high = +80.0°C, crit = +100.0°C)
  4. Core 0:        +33.0°C  (high = +80.0°C, crit = +100.0°C)
  5. Core 4:        +40.0°C  (high = +80.0°C, crit = +100.0°C)
  6. Core 8:        +38.0°C  (high = +80.0°C, crit = +100.0°C)
  7. Core 12:       +36.0°C  (high = +80.0°C, crit = +100.0°C)
  8. Core 16:       +35.0°C  (high = +80.0°C, crit = +100.0°C)
  9. Core 20:       +36.0°C  (high = +80.0°C, crit = +100.0°C)
  10. Core 24:       +39.0°C  (high = +80.0°C, crit = +100.0°C)
  11. Core 25:       +39.0°C  (high = +80.0°C, crit = +100.0°C)
  12. Core 26:       +39.0°C  (high = +80.0°C, crit = +100.0°C)
  13. Core 27:       +39.0°C  (high = +80.0°C, crit = +100.0°C)
  14. Core 28:       +37.0°C  (high = +80.0°C, crit = +100.0°C)
  15. Core 29:       +37.0°C  (high = +80.0°C, crit = +100.0°C)
  16. Core 30:       +37.0°C  (high = +80.0°C, crit = +100.0°C)
  17. Core 31:       +37.0°C  (high = +80.0°C, crit = +100.0°C)
复制代码
但是重点来了,由于个人的硬件不同,这里显示的内容其实是不尽相同的,就比如我看到的文章都是有显示CPU的每个核心的温度,但是我这里并没有显示。
采集温度信息
能查询到温度信息后,现在需要修改文件 /usr/share/perl5/PVE/API2/Nodes.pm 来收集 sensors 命令的返回信息。直接打开文件,然后搜索 shared => $meminfo->{memshared} 找到如下位置,并在下面插入一行(注意里面不要有注释):
  1. $res->{ksm} = {
  2.     shared => $meminfo->{memshared},
  3. };
  4. $res->{cpu_temperatures} = `sensors`;
复制代码
这个文件的作用就是使用命令 sensors 去采集硬件信息,然后传递给变量 cpu_temperatures,也就是说现在 cpu_temperatures 的内容其实就是我们查询到的信息,这个变量后续会用到。
提取温度信息
由于我们执行 sensors 命令显示的信息很多,而且每个人的电脑上面看到的结果也大概率不同,但是我们大概能判断哪些是温度信息,并且可以自己查一下分别是什么硬件的温度。
此时我们就需要把温度信息提取出来了。这里可以分享一下我自己的方法(独家方法,完全是自己临时想的,而且很有效):因为后续我们要展示信息的时候是使用的js文件,也就是js语法,所以可以直接在浏览器的控制台去调试,提取自己想要的温度信息。
首先,打开任意页面的控制台,然后把使用命令 sensors 查询的所有信息复制出来,放到控制台(浏览器按F12可以调出控制台)并赋值给变量 value,就像这样(注意使用代码符号括起来):
  1. var value = `coretemp-isa-0000
  2. Adapter: ISA adapter
  3. Package id 0:  +40.0°C  (high = +80.0°C, crit = +100.0°C)
  4. Core 0:        +33.0°C  (high = +80.0°C, crit = +100.0°C)
  5. Core 4:        +40.0°C  (high = +80.0°C, crit = +100.0°C)
  6. Core 8:        +38.0°C  (high = +80.0°C, crit = +100.0°C)
  7. Core 12:       +36.0°C  (high = +80.0°C, crit = +100.0°C)
  8. Core 16:       +35.0°C  (high = +80.0°C, crit = +100.0°C)
  9. Core 20:       +36.0°C  (high = +80.0°C, crit = +100.0°C)
  10. Core 24:       +39.0°C  (high = +80.0°C, crit = +100.0°C)
  11. Core 25:       +39.0°C  (high = +80.0°C, crit = +100.0°C)
  12. Core 26:       +39.0°C  (high = +80.0°C, crit = +100.0°C)
  13. Core 27:       +39.0°C  (high = +80.0°C, crit = +100.0°C)
  14. Core 28:       +37.0°C  (high = +80.0°C, crit = +100.0°C)
  15. Core 29:       +37.0°C  (high = +80.0°C, crit = +100.0°C)
  16. Core 30:       +37.0°C  (high = +80.0°C, crit = +100.0°C)
  17. Core 31:       +37.0°C  (high = +80.0°C, crit = +100.0°C)

  18. acpitz-acpi-0
  19. Adapter: ACPI interface
  20. temp1:        +27.8°C  

  21. nct6798-isa-0290
  22. Adapter: ISA adapter
  23. in0:                      752.00 mV (min =  +0.00 V, max =  +1.74 V)
  24. in1:                        1.02 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
  25. in2:                        3.41 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
  26. in3:                        3.33 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
  27. in4:                        1.01 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
  28. in5:                      152.00 mV (min =  +0.00 V, max =  +0.00 V)
  29. in6:                      744.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
  30. in7:                        3.41 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
  31. in8:                        3.23 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
  32. in9:                        1.07 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
  33. in10:                       1.12 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
  34. in11:                      16.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
  35. in12:                       1.04 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
  36. in13:                     424.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
  37. in14:                     904.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
  38. fan1:                        0 RPM  (min =    0 RPM)
  39. fan2:                      798 RPM  (min =    0 RPM)
  40. fan3:                        0 RPM  (min =    0 RPM)
  41. fan4:                        0 RPM  (min =    0 RPM)
  42. fan5:                        0 RPM  (min =    0 RPM)
  43. fan6:                        0 RPM  (min =    0 RPM)
  44. SYSTIN:                    +39.0°C  (high = +80.0°C, hyst = +75.0°C)
  45.                                     (crit = +125.0°C)  sensor = thermistor
  46. CPUTIN:                    +39.0°C  (high = +80.0°C, hyst = +75.0°C)
  47.                                     (crit = +125.0°C)  sensor = thermistor
  48. AUXTIN0:                   +40.0°C  (high = +80.0°C, hyst = +75.0°C)
  49.                                     (crit = +100.0°C)  sensor = thermistor
  50. AUXTIN1:                   +19.0°C  (high = +80.0°C, hyst = +75.0°C)
  51.                                     (crit = +125.0°C)  sensor = thermistor
  52. AUXTIN2:                  +127.0°C  (high = +80.0°C, hyst = +75.0°C)  ALARM
  53.                                     (crit = +125.0°C)  sensor = thermistor
  54. AUXTIN3:                   +31.0°C  (high = +80.0°C, hyst = +75.0°C)
  55.                                     (crit = +100.0°C)  sensor = thermistor
  56. AUXTIN4:                  +127.0°C  (high = +80.0°C, hyst = +75.0°C)  ALARM
  57.                                     (crit = +100.0°C)
  58. PECI Agent 0 Calibration:  +39.0°C  (high = +80.0°C, hyst = +75.0°C)
  59. PCH_CHIP_CPU_MAX_TEMP:      +0.0°C  
  60. PCH_CHIP_TEMP:              +0.0°C  
  61. PCH_CPU_TEMP:               +0.0°C  
  62. PCH_MCH_TEMP:               +0.0°C  
  63. intrusion0:               ALARM
  64. intrusion1:               ALARM
  65. beep_enable:              disabled

  66. nvme-pci-e100
  67. Adapter: PCI adapter
  68. Composite:    +41.9°C  (low  = -273.1°C, high = +81.8°C)
  69.                        (crit = +84.8°C)
  70. Sensor 1:     +41.9°C  (low  = -273.1°C, high = +65261.8°C)
  71. Sensor 2:     +45.9°C  (low  = -273.1°C, high = +65261.8°C)`;
复制代码
002.jpg
然后我们使用js语法来分别把不同的温度赋值给一个变量,就比如cpu的温度赋值代码(核心越多,写的越多,因为每个核心都有可能会有传感器):
  1. const c0 = value.match(/Core 0.*?\+([\d\.]+)?/)[1];
  2. const c1 = value.match(/Core 4.*?\+([\d\.]+)?/)[1];
  3. const c2 = value.match(/Core 8.*?\+([\d\.]+)?/)[1];
  4. const c3 = value.match(/Core 12.*?\+([\d\.]+)?/)[1];
  5. const c4 = value.match(/Core 16.*?\+([\d\.]+)?/)[1];
  6. const c5 = value.match(/Core 20.*?\+([\d\.]+)?/)[1];
  7. const c6 = value.match(/Core 24.*?\+([\d\.]+)?/)[1];
  8. const c7 = value.match(/Core 25.*?\+([\d\.]+)?/)[1];
  9. const c8 = value.match(/Core 26.*?\+([\d\.]+)?/)[1];
  10. const c9 = value.match(/Core 27.*?\+([\d\.]+)?/)[1];
  11. const c10 = value.match(/Core 28.*?\+([\d\.]+)?/)[1];
  12. const c11 = value.match(/Core 29.*?\+([\d\.]+)?/)[1];
  13. const c12 = value.match(/Core 30.*?\+([\d\.]+)?/)[1];
  14. const c13 = value.match(/Core 31.*?\+([\d\.]+)?/)[1];
  15. const p0 = value.match(/Package id 0.*?\+([\d\.]+)?/)[1];
复制代码
单行测试代码:
003.jpg

一起测试代码,输出总的结果:
004.png
当你调试OK,拿到你想要的所有信息之后,再继续下一步。
显示温度信息
上面提取温度信息完成后,开始编辑文件 /usr/share/pve-manager/js/pvemanagerlib.js 来将提取的方式和要显示的格式配置到这个js文件中。
首先找到添加的位置,使用搜索关键词 textField: 'pveversion' 定位到如下位置,然后添加如下代码:
  1. {
  2.             itemId: 'version',
  3.             colspan: 2,
  4.             printBar: false,
  5.             title: gettext('Manager Version'),
  6.             textField: 'pveversion',
  7.             value: '',
  8.         },// 下面一块是新增的,这里的逗号不要漏掉
  9.      
  10.     {                  
  11.         itemId: 'cpu-temperatures',
  12.         colspan: 2,
  13.         printBar: false,
  14.         title: gettext('CPU温度'),
  15.         textField: 'cpu_temperatures',
  16.         renderer:function(value){
  17.             const c0 = value.match(/Core 0.*?\+([\d\.]+)?/)[1];45145            
  18.             const c1 = value.match(/Core 4.*?\+([\d\.]+)?/)[1];
  19.             const c2 = value.match(/Core 8.*?\+([\d\.]+)?/)[1];
  20.             const c3 = value.match(/Core 12.*?\+([\d\.]+)?/)[1];
  21.             const c4 = value.match(/Core 16.*?\+([\d\.]+)?/)[1];
  22.             const c5 = value.match(/Core 20.*?\+([\d\.]+)?/)[1];
  23.             const c6 = value.match(/Core 24.*?\+([\d\.]+)?/)[1];
  24.             const c7 = value.match(/Core 25.*?\+([\d\.]+)?/)[1];
  25.             const c8 = value.match(/Core 26.*?\+([\d\.]+)?/)[1];
  26.             const c9 = value.match(/Core 27.*?\+([\d\.]+)?/)[1];
  27.             const c10 = value.match(/Core 28.*?\+([\d\.]+)?/)[1];
  28.             const c11 = value.match(/Core 29.*?\+([\d\.]+)?/)[1];
  29.             const c12 = value.match(/Core 30.*?\+([\d\.]+)?/)[1];
  30.             const c13 = value.match(/Core 31.*?\+([\d\.]+)?/)[1];
  31.             const p0 = value.match(/Package id 0.*?\+([\d\.]+)?/)[1];
  32.             return `Package: ${p0}℃; Core 0: ${c0}℃; Core 4: ${c1}℃; Core 8: ${c2}℃; Core 12: ${c3}℃; Core 16: ${c4}℃; Core 20: ${c5}℃; Core 24: ${c6}℃; Core 25: ${c7}℃; Core 26: ${c8}℃; Cor      e 27: ${c9}℃; Core 28: ${c10}℃; Core 29: ${c11}℃; Core 30: ${c12}℃; Core 31: ${c13}℃`
  33.         }
  34.     },//注意这里的逗号
复制代码
我们来注释并分析一下这个新增的代码是在干嘛:
     {                   
        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 4.*?\+([\d\.]+)?/)[1];
            const c2 = value.match(/Core 8.*?\+([\d\.]+)?/)[1];
            const c3 = value.match(/Core 12.*?\+([\d\.]+)?/)[1];
            const c4 = value.match(/Core 16.*?\+([\d\.]+)?/)[1];
            const c5 = value.match(/Core 20.*?\+([\d\.]+)?/)[1];
            const c6 = value.match(/Core 24.*?\+([\d\.]+)?/)[1];
            const c7 = value.match(/Core 25.*?\+([\d\.]+)?/)[1];
            const c8 = value.match(/Core 26.*?\+([\d\.]+)?/)[1];
            const c9 = value.match(/Core 27.*?\+([\d\.]+)?/)[1];
            const c10 = value.match(/Core 28.*?\+([\d\.]+)?/)[1];
            const c11 = value.match(/Core 29.*?\+([\d\.]+)?/)[1];
            const c12 = value.match(/Core 30.*?\+([\d\.]+)?/)[1];
            const c13 = value.match(/Core 31.*?\+([\d\.]+)?/)[1];
            const p0 = value.match(/Package id 0.*?\+([\d\.]+)?/)[1];
            return `Package: ${p0}℃; Core 0: ${c0}℃; Core 4: ${c1}℃; Core 8: ${c2}℃; Core 12: ${c3}℃; Core 16: ${c4}℃; Core 20: ${c5}℃; Core 24: ${c6}℃; Core 25: ${c7}℃; Core 26: ${c8}℃; Cor      e 27: ${c9}℃; Core 28: ${c10}℃; Core 29: ${c11}℃; Core 30: ${c12}℃; Core 31: ${c13}℃`
        }
    },

这里的关键就是这个 renderer 函数返回的内容,也就是最后显示的内容,看这个js的内容,value 这个参数就是我们使用 sensors 命令获取到的所有信息,而下面各种 match 就是去提取信息,所以为什么前面我让在浏览器中调试这些信息的提前,就是为了调试好每个输出的信息。
最后返回了一个字符串,这个里面类似 ${cpu} 就是js语法,使用前面定义的变量去替换里面的内容。
面板高度修改
还需要调整下页面高度,不然会显示不完全。
pvemanagerlib.js中搜索widget.pveNodeStatus就可以看到height: 350,的字眼,对这个350进行修改即可
提示:所以,编写这个文件的内容的时候千万不要无脑复制粘贴,要结合自己查询的信息去调试提取(无非就是改一下正则而已),然后把自己想要显示的内容显示出来。

重启面板查看效果
修改了Nodes.pm文件,需要使用命令行运行下面命令重启API代理守护进程使修改生效,仅修改js文件,无需运行。
  1. systemctl restart pveproxy
复制代码
刷新pve的概要页面,如果正常就能显示出温度信息,如果没有显示,一直在加载,那说明你的语法有错误,可以检查一下前后逗号是否漏了,其他语法可以在控制台或者你自己的node环境调试。
总结
通过这个让 PVE 显示温度的过程,可以非常清晰的了解 PVE 显示额外信息的原理,主要就是两个地方的操作:
  • 修改 /usr/share/perl5/PVE/API2/Nodes.pm 文件,添加要执行的采集命令(我甚至觉得这里可以执行脚本来进行更复杂的采集操作,待求证)
  • 修改 /usr/share/pve-manager/js/pvemanagerlib.js 文件来从采集命令的输出中提取要显示的信息,然后显示出来,这里是完全的 js 语法,所以可以在本地进行调试。
  • 修改完上述两个文件后,重启服务即可 systemctl restart pveproxy

参考的原作者链接,大部分转自此文:参考文章



您需要登录后才可以回帖 登录 | register

本版积分规则

雪舞知识库 | 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 |网站地图|天天打卡

GMT+8, 2024-12-5 03:02 , Processed in 0.078606 second(s), 7 queries , Redis On.

Powered by XueWu Licensed

Copyright © Tencent Cloud.

快速回复 返回顶部 返回列表