ホーム » 技術 » lm_sensorsでサーバの温度を監視する

lm_sensorsでサーバの温度を監視する

そういやオヒスのルータマシンの温度監視をやってなかったなと気づき、自宅のルータマシンの温度監視を流用すればいいやと思って調べてみたら、この前Zabbixのバージョンアップをやったときに動かなくなっていたことを発見してしまい、やり直すことにした。

概要

例によって本稿で示す監視の概略を示す。

  • lm_sensorsでサーバの温度センサから情報を取得する
  • zabbix-agentでデータを取る。ついでにdiscoveryルールも作る
  • zabbix-serverで受信する。グラフ化などは適当に

ターゲットは、最近お騒がせのCentOS8だ。

lm_sensorsのインストール

自分の環境ではあんまり何も考えないで、

dnf -y install lm_sensors
sensors-detect --auto

とした。確認できたセンサからデータを読み取るにはsensorsコマンドを使う。-jオプションを付けるとJSON形式でデータが取れる。

[north@xorn ~]$ sensors -j
{
   "iwlwifi_1-virtual-0":{
      "Adapter": "Virtual device",
      "temp1":{
ERROR: Can't get value of subfeature temp1_input: Can't read

      }
   },
   "acpitz-virtual-0":{
      "Adapter": "Virtual device",
      "temp1":{
         "temp1_input": 41.000,
         "temp1_crit": 100.000
      }
   },
   "coretemp-isa-0000":{
      "Adapter": "ISA adapter",
      "Package id 0":{
         "temp1_input": 41.000,
         "temp1_max": 110.000,
         "temp1_crit": 110.000,
         "temp1_crit_alarm": 0.000
      },
      "Core 0":{
         "temp2_input": 40.000,
         "temp2_max": 110.000,
         "temp2_crit": 110.000,
         "temp2_crit_alarm": 0.000
      },
      "Core 1":{
         "temp3_input": 40.000,
         "temp3_max": 110.000,
         "temp3_crit": 110.000,
         "temp3_crit_alarm": 0.000
      },
      "Core 2":{
         "temp4_input": 40.000,
         "temp4_max": 110.000,
         "temp4_crit": 110.000,
         "temp4_crit_alarm": 0.000
      },
      "Core 3":{
         "temp5_input": 40.000,
         "temp5_max": 110.000,
         "temp5_crit": 110.000,
         "temp5_crit_alarm": 0.000
      }
   }
}

これで一通りセンサの一覧と、各センサのデータが読める。

Zabbixのdiscoveryルール

discoveryルールは所定のJSONデータにして返せばよいので、sensorsコマンドの出力を整形して返せばよさそうだ。

/etc/zabbix/bin/zabbix-sensors-discovery

#!/usr/bin/perl

use strict;
use warnings;
use JSON;

system 'sensors-detect --auto >/dev/null 2>&1';
my $s = `sensors -j 2>/dev/null`;
$s =~ s/\n//g;
my $j = decode_json($s);

my $f = 0;
print "[\n";
foreach my $chip (keys %$j) {
        foreach my $unit (sort keys %{$j->{$chip}}) {
                if (ref($j->{$chip}->{$unit}) eq "HASH") {
                        foreach my $val (sort keys %{$j->{$chip}->{$unit}}) {
                                if ($val =~ m/_input$/) {
                                        print ",\n" if ($f);
                                        $f = 1;
                                        printf("{\"{#CHIPNAME}\":\"%s\",\"{#UNITNAME}\":\"%s\",\"{#VALNAME}\":\"%s\"}", $chip, $unit, $val);
                                }
                        }
                }
        }
}
print "]\n";

exit 0;

これでこんなJSONが返る。

[
{"{#CHIPNAME}":"acpitz-virtual-0","{#UNITNAME}":"temp1","{#VALNAME}":"temp1_input"},
{"{#CHIPNAME}":"coretemp-isa-0000","{#UNITNAME}":"Core 0","{#VALNAME}":"temp2_input"},
{"{#CHIPNAME}":"coretemp-isa-0000","{#UNITNAME}":"Core 1","{#VALNAME}":"temp3_input"},
{"{#CHIPNAME}":"coretemp-isa-0000","{#UNITNAME}":"Core 2","{#VALNAME}":"temp4_input"},
{"{#CHIPNAME}":"coretemp-isa-0000","{#UNITNAME}":"Core 3","{#VALNAME}":"temp5_input"},
{"{#CHIPNAME}":"coretemp-isa-0000","{#UNITNAME}":"Package id 0","{#VALNAME}":"temp1_input"}]

discoveryには十分だ。

センサからのデータ読み出し

ついでにsensorsコマンドでデータを読むスクリプトも作っておく。

/etc/zabbix/bin/zabbix-sensors

#!/usr/bin/perl

use strict;
use warnings;
use JSON;

if ($#ARGV != 2) {
        print "usage: zabbix-sensors chip unit val\n";
        exit 1;
}

my $chip = shift;
my $unit = shift;
my $val = shift;

my $s = `sensors -j $chip`;
$s =~ s/\n//g;
my $j = decode_json($s);
print $j->{$chip}->{$unit}->{$val}, "\n";

exit 0;

UserParameterの設定

次にdiscoveryルールとキーを定義するためにconfファイルを書く。

/etc/zabbix/zabbix_agentd.d/lm_sensors.conf

# lm_sensors
UserParameter=lm_sensors.discovery, /etc/zabbix/bin/zabbix-sensors-discovery
UserParameter=lm_sensors[*], /etc/zabbix/bin/zabbix-sensors "$1" "$2" "$3"

lm_sensors.confと2つのスクリプトを所定のディレクトリに配置したらzabbix-agentをリスタートする。

systemctl restart zabbix-agent

Zabbix ServerのTemplate

次にZabbix ServerでTemplateを用意する。適当に作っていただいてもよいし、自分が作ったものをimportしていただいてもよい。参考リンクにGithubのリンクを置いておくのでそちらをご覧いただきたい。

簡単に説明すると、discoveryルールでlm_sensors.discoveryをコールし、Item prototypesでlm_sensors[*]にパラメータを渡せばよい。あとは見つかったセンサを自動的に追加してくれるはずだ。

センサごとのグラフのプロトタイプも作っておくとよい。またサーバごとにお好みのセンサを集めたグラフを個別に作ると便利だと思う。

参考リンク