zaki work log

作業ログやら生活ログやらなんやら

Proxmox VEのweb管理画面にCPUの温度を表示する

去年の春に構築して灼熱の夏は無事に乗り越えたMINISFORUM NAB6だけど、以前使ってたIntel NUC(現在win11が入ってる)はちょいちょい熱暴走起こしてたので、念のために簡単にモニタリングできるようにしてみた。

2024.04.01 パッケージバージョンアップで変更が復元される件を追記

lm-sensorsのインストール

lm-sensorsはハードでモニタリングしている情報をLinuxで取得する古来からあるプログラム。Debianパッケージでも提供されているのでそれを使用する。

atmarkit.itmedia.co.jp

apt-get install lm-sensors

aptでシュッと入る。

root@pve:~# apt-get install lm-sensors
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following package was automatically installed and is no longer required:
  proxmox-kernel-6.2.16-15-pve
Use 'apt autoremove' to remove it.
The following additional packages will be installed:
  libsensors-config libsensors5
Suggested packages:
  fancontrol read-edid i2c-tools
The following NEW packages will be installed:
  libsensors-config libsensors5 lm-sensors
0 upgraded, 3 newly installed, 0 to remove and 1 not upgraded.
Need to get 146 kB of archives.
After this operation, 518 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://ftp.jp.debian.org/debian bookworm/main amd64 libsensors-config all 1:3.6.0-7.1 [14.3 kB]
Get:2 http://ftp.jp.debian.org/debian bookworm/main amd64 libsensors5 amd64 1:3.6.0-7.1 [34.2 kB]
Get:3 http://ftp.jp.debian.org/debian bookworm/main amd64 lm-sensors amd64 1:3.6.0-7.1 [97.2 kB]
Fetched 146 kB in 1s (177 kB/s)      
Selecting previously unselected package libsensors-config.
(Reading database ... 77682 files and directories currently installed.)
Preparing to unpack .../libsensors-config_1%3a3.6.0-7.1_all.deb ...
Unpacking libsensors-config (1:3.6.0-7.1) ...
Selecting previously unselected package libsensors5:amd64.
Preparing to unpack .../libsensors5_1%3a3.6.0-7.1_amd64.deb ...
Unpacking libsensors5:amd64 (1:3.6.0-7.1) ...
Selecting previously unselected package lm-sensors.
Preparing to unpack .../lm-sensors_1%3a3.6.0-7.1_amd64.deb ...
Unpacking lm-sensors (1:3.6.0-7.1) ...
Setting up libsensors-config (1:3.6.0-7.1) ...
Setting up libsensors5:amd64 (1:3.6.0-7.1) ...
Setting up lm-sensors (1:3.6.0-7.1) ...
Created symlink /etc/systemd/system/multi-user.target.wants/lm-sensors.service → /lib/systemd/system/lm-sensors.service.
Processing triggers for man-db (2.11.2-2) ...
Processing triggers for libc-bin (2.36-9+deb12u4) ...
root@pve:~# 

動作の確認

手元の環境では設定なしでsensorsコマンド実行で温度が取れる。

root@pve:~# sensors
coretemp-isa-0000
Adapter: ISA adapter
Package id 0:  +46.0°C  (high = +100.0°C, crit = +100.0°C)
Core 0:        +36.0°C  (high = +100.0°C, crit = +100.0°C)
Core 4:        +46.0°C  (high = +100.0°C, crit = +100.0°C)
Core 8:        +38.0°C  (high = +100.0°C, crit = +100.0°C)
Core 12:       +37.0°C  (high = +100.0°C, crit = +100.0°C)
Core 16:       +38.0°C  (high = +100.0°C, crit = +100.0°C)
Core 20:       +38.0°C  (high = +100.0°C, crit = +100.0°C)
Core 28:       +38.0°C  (high = +100.0°C, crit = +100.0°C)
Core 29:       +38.0°C  (high = +100.0°C, crit = +100.0°C)
Core 30:       +38.0°C  (high = +100.0°C, crit = +100.0°C)
Core 31:       +38.0°C  (high = +100.0°C, crit = +100.0°C)

acpitz-acpi-0
Adapter: ACPI interface
temp1:        +27.8°C  (crit = +105.0°C)

nvme-pci-0100
Adapter: PCI adapter
Composite:    +46.9°C  (low  =  -0.1°C, high = +82.8°C)
                       (crit = +89.8°C)

root@pve:~# 

-jオプションを付与するとJSON形式で出力できる。

root@pve:~# sensors -j 
{
   "coretemp-isa-0000":{
      "Adapter": "ISA adapter",
      "Package id 0":{
         "temp1_input": 41.000,
         "temp1_max": 100.000,
         "temp1_crit": 100.000,
         "temp1_crit_alarm": 0.000
      },
      "Core 0":{

    ...

動作しているマシンのCPUはCore i7-12650Hで、物理CPUは1、CPUごとのコアは10。「Core N」のNの値が飛び飛びなのが気になるけど、10コアそれぞれの温度と、「Package id 0」は全体の加重平均らしいので、この値を表示させてみる。

askubuntu.com

www.intel.com

UIの改造

温度を取れるようになったので、PVEのweb画面に表示してみる。
参考情報はこちらというか、基本この通りやれば良い。

www.forum-nas.fr

値の取得部分

Perlモジュールを修正。

--- /usr/share/perl5/PVE/API2/Nodes.pm.org      2023-12-14 23:20:06.000000000 +0900
+++ /usr/share/perl5/PVE/API2/Nodes.pm  2024-02-04 11:25:27.877690336 +0900
@@ -446,6 +446,10 @@
        $res->{pveversion} = PVE::pvecfg::package() . "/" .
            PVE::pvecfg::version_text();
 
+        # for lm-sensors
+        # https://www.forum-nas.fr/threads/tuto-afficher-la-temp%C3%A9rature-cpu-dans-proxmox-ve-8.21096/
+        $res->{thermalstate} = `sensors -j`;
+
        my $dinfo = df('/', 1);     # output is bytes
 
        $res->{rootfs} = {

UI部分

参考リンクはPVE Manager Versionとあるが、現バージョンだとManager Versionになってるのでそれを探す。

    items: [

        //...

        {
            itemId: 'version',
            colspan: 2,
            printBar: false,
            title: gettext('Manager Version'),
            textField: 'pveversion',
            value: '',
        },
    ],

    updateTitle: function() {

このitemsリストに以下のPerlモジュールで収集したデータを取得して返すコードを追加。
このとき辞書のキーはsensors -jで確認できるJSONのキーを使用する。

--- /usr/share/pve-manager/js/pvemanagerlib.js.org      2023-12-14 23:20:06.000000000 +0900
+++ /usr/share/pve-manager/js/pvemanagerlib.js  2024-02-04 11:59:06.069857992 +0900
@@ -43294,6 +43294,16 @@
            textField: 'pveversion',
            value: '',
        },
+        {
+            itemId: 'thermal',
+            colspan: 2,
+            printBar: false,
+            title: gettext('CPU Thermal State'),
+            textField: 'thermalstate',
+            renderer: function(value) {
+                return `${JSON.parse(value)["coretemp-isa-0000"]["Package id 0"]["temp1_input"]}°C`;
+            }
+        }
     ],
 
     updateTitle: function() {

手元のマシンはコアが10個あってそれぞれの値を並べるのは表示領域的に厳しいので「Package id 0」を1個だけ使用。

表示を確認

変更が済んだらWeb UIサービスを再起動する。

systemctl restart pveproxy

これで、webの画面で該当のpveノードのサマリーで温度を確認できる。

応用すれば何でも表示できると思う。
見た感じ1秒に1回のペースで値が更新されるので、そのたびに内部の取得コマンドが実行されてるのだと思われ。

/usr/share以下のファイルって勝手に書き換えていいの?

どちらのファイルもpve-managerパッケージによってインストールされているので、バージョンアップによって変更(復元)される可能性はあるのでその点は注意。(バージョンアップで復元されました)

root@pve:~# dpkg -S /usr/share/perl5/PVE/API2/Nodes.pm /usr/share/pve-manager/js/pvemanagerlib.js
pve-manager: /usr/share/perl5/PVE/API2/Nodes.pm
pve-manager: /usr/share/pve-manager/js/pvemanagerlib.js