夫です。
このWebサーバーはAtomマシーンで動作しており、日中は無人の部屋で動作している。
となると、なんとかして、外部から温度などの情報を監視しておきたいものである。いや、監視しなければならない。
先日の
ブログにて温度監視のやり方について述べた。
今回はその温度監視を、あらかじめ定期的にログに出力していることを前提に、そのログを定期的に解析し、
Google Chart APIに与え、現在の温度等を表示できるようにする。
まず、あらかじめlm_sensorsによる情報は以下のようなシェルスクリプトを延々回し、で定期的にログ出力をしておく。
#!/bin/bash
while [ true ];
do
date >> /var/log/sensor.log
/usr/local/bin/sensors >> /var/log/sensor.log
/usr/sbin/hddtemp /dev/sda >> /var/log/sensor.log
sleep 60
done
もちろんローテーションも忘れずに。
# less /etc/logrotate.d/sensorlog
/var/log/sensor.log {
nocompress
missingok
daily
rotate 7
}
続いて、以下のPerlスクリプトを、これまた定期的に実施する。なお、以下のスクリプトでは最新のログのみを参照しているので、ローテーションされた直後(朝4時)は、たいしたデータが表示されないはず。最低2世代のログファイルを参照すれば解決できるが、特に朝4時に状態を見たい要望はないので捨て置く。
#!/usr/bin/perl
#Target list
$target_sensor[0]{sensor}="CPU_TEMP(C)";
$target_sensor[0]{min}=0;
$target_sensor[0]{max}=100;
$target_sensor[1]{sensor}="CHIP_TEMP(C)";
$target_sensor[1]{min}=0;
$target_sensor[1]{max}=100;
$target_sensor[2]{sensor}="SYSTEM_BOARD_TEMP(C)";
$target_sensor[2]{min}=0;
$target_sensor[2]{max}=100;
$target_sensor[3]{sensor}="HDD_TEMP(C)";
$target_sensor[3]{min}=0;
$target_sensor[3]{max}=100;
$target_sensor[4]{sensor}="CASE_FAN(RPM)";
$target_sensor[4]{min}=0;
$target_sensor[4]{max}=2000;
$target_sensor[5]{sensor}="CHIP_FAN(RPM)";
$target_sensor[5]{min}=0;
$target_sensor[5]{max}=8000;
my $data_num=301;
open(IN,"$ARGV[0] ")||die("cannot open logs");
$i=0;
while($line=){
if( $line =~ /JST$/ ){
$i++;
chomp($line);
$date[$i]=$line;
$date[$i]=~s/\s//g;
$date[$i]=~s/年/\//g;
$date[$i]=~s/月/\//o;
$date[$i]=~s/日//o;
$date[$i]=~s/日曜日|月曜日|火曜日|水曜日|木曜日|金曜日|土曜日/ /o;
$date[$i]=~s/JST//g;
($day[$i],$time[$i])=split(/ /,$date[$i]);
}else{
@a=split(/\s+/, $line);
if($a[0] eq "CPU") {
$target_sensor[0]{$i}=$a[2];
$target_sensor[0]{$i}=~s/\+//g;
$target_sensor[0]{$i}=~s/°C//g;
}
if($a[0] eq "Chip") {
$target_sensor[1]{$i}=$a[2];
$target_sensor[1]{$i}=~s/\+//g;
$target_sensor[1]{$i}=~s/°C//g;
}
if($a[0] eq "Sys") {
$target_sensor[2]{$i}=$a[2];
$target_sensor[2]{$i}=~s/\+//g;
$target_sensor[2]{$i}=~s/°C//g;
}
if($a[0] =~ /^\/dev/){
$target_sensor[3]{$i}=$a[2];
$target_sensor[3]{$i}=~s/\+//g;
$target_sensor[3]{$i}=~s/°C//g;
}
if($a[0] eq "fan1:") {
$target_sensor[4]{$i}=$a[1];
}
if($a[0] eq "fan2:") {
$target_sensor[5]{$i}=$a[1];
}
}
}
close(IN);
if($i<$data_num){
$data_num=$i-1;
}
$time_tag .="< img src=\"http://chart.apis.google.com/chart?&chxt=x,y&chxl=0:|";
$j=$i-$data_num;
while($j < $i){
if($j==$i-$data_num || $j==$i-int(($data_num-1)/2) || $j==$i-1){
$time_tag .="$time[$j]";
$time_tag .="|";
}
$j++;
}
$time_tag =~s/\|$//o;
$time_tag .= "&cht=lc&chd=t:";
for($h=0; $h < 6; $h++){
$j=$i-$data_num;
while($j<$i){
$target_sensor[$h]{out} .= $target_sensor[$h]{$j};
$target_sensor[$h]{out} .= ",";
$j++;
}
}
for($h=0; $h < 6; $h++){
$target_sensor[$h]{out}=~s/,$//o;
$tmp ="$time_tag";
$tmp .="$target_sensor[$h]{out}";
$tmp .="&chds=$target_sensor[$h]{min},$target_sensor[$h]{max}&chxr=1,$target_sensor[$h]{min},$target_sensor[$h]{max}&chco=76A4FB&chls=1.0&chs=200x150&chtt=$target_sensor[$h]{sensor}\">\n";
print "$tmp";
}
exit();
もう少し、コードを短縮化できる余地はありそうだけど、そこそこ可読性がよいので、とりあえずこの版でページ上部のグラフは作成している。
このスクリプトを以下のような周期でcronにて実行し、出力された、部分的なHTMLをWebサイトに取り込むようにすると、最新の情報を表示させることができる。
*/5 * * * * /usr/local/bin/sensorslog2csv_r3.pl /var/log/sensor.log > /path/to/出力ファイル
ちなみにPHPで外部ファイルを取り込むには以下のようなコードをページ内の表示したい箇所に記載すればよい。
<?php
$fname = "/path/to/出力ファイル";
$fp = fopen($fname, 'rb');
while (!feof($fp)) {
$line = fgets($fp, 1024);
print "$line\n";
}
fclose ($fp);
?>
Google Chart APIは大変ありがたい機能だと思う。グラフを作るライブラリをいくつか試したけれども、結構CPUパワーをつかい、個人的にはできれば自前ではやりたくない領域だった。いまやURIを生成するだけで画像を表示してくれるなんて、なんてすばらしい機能だろう。
クリック。