HDDの温度監視

HDDの温度をCentreonに監視させて、グラフを書く。前半はNagiosとやること一緒。

  • 対象OS : FreeBSD 8.1-R
  • コンポーネント : net-snmp-5.5_4 , smartmontools-5.40
  • 注記 : 各コンポーネントは単体では動作が確認できていることとする)

概要手順

  • SNMPのextend機能を使用して、HDDの温度がMIB値として取得できるようにする。
  • MIB値を調べる。
  • 対象のMIB値を取得してきて、Centreon用の出力をするようにプラグインを作成。
    • これはnagiosのパフォーマンス出力とほぼ同義だ。
  • CentreonのWebUIでcommandを登録。
  • 同様に監視対象となるホストを選択して、Servicesを登録。
  • Nagios再起動して終わり。

詳細

1.SNMPのextend機能を使用して、MIB値の登録

  • 以下のスクリプトを実行可能な形で作成
    • <code>#!/bin/sh

for dev in ls -t /dev/* | awk '/(ad|da)[0-9]+$/ {print $1}'; do

case $1 in
  name)       echo $dev;;
  temprature) /usr/local/sbin/smartctl -A $dev | awk '$1=="194" {print $10}';;
esac

done</code>

  • snmpd.confにextend行を記載(今回は最終行に2行追加)。
    • <code># cat snmpd.conf | tail -2 extend ataDevice /usr/local/share/snmp/atadevicetemprature.sh name extend ataDeviceTemperature /usr/local/share/snmp/atadevicetemprature.sh temprature</code>
  • snmpdの再起動
    • <code># /usr/local/etc/rc.d/snmpd restart</code>

2.MIB値の確認

  • nsExtensionsは1.3.6.1.4.1.8072.1.3なので、snmpwalkで一通り見てみる。
  • コマンド結果を一部抜粋
    • <code># snmpwalk -v 1 -c private 127.0.0.1 .1.3.6.1.4.1.8072.1.3 NET-SNMP-EXTEND-MIB::nsExtendOutNumLines.“ataDevice” = INTEGER: 4 NET-SNMP-EXTEND-MIB::nsExtendOutNumLines.“ataDeviceTemperature” = INTEGER: 4 NET-SNMP-EXTEND-MIB::nsExtendResult.“ataDevice” = INTEGER: 0 NET-SNMP-EXTEND-MIB::nsExtendResult.“ataDeviceTemperature” = INTEGER: 0 NET-SNMP-EXTEND-MIB::nsExtendOutLine.“ataDevice”.1 = STRING: /dev/ad8 NET-SNMP-EXTEND-MIB::nsExtendOutLine.“ataDevice”.2 = STRING: /dev/da0 NET-SNMP-EXTEND-MIB::nsExtendOutLine.“ataDevice”.3 = STRING: /dev/da1 NET-SNMP-EXTEND-MIB::nsExtendOutLine.“ataDevice”.4 = STRING: /dev/da2 NET-SNMP-EXTEND-MIB::nsExtendOutLine.“ataDeviceTemperature”.1 = STRING: 36 NET-SNMP-EXTEND-MIB::nsExtendOutLine.“ataDeviceTemperature”.2 = STRING: 36 NET-SNMP-EXTEND-MIB::nsExtendOutLine.“ataDeviceTemperature”.3 = STRING: 33 NET-SNMP-EXTEND-MIB::nsExtendOutLine.“ataDeviceTemperature”.4 = STRING: 34</code>
  • 値にシェルスクリプトのエラー値が入っている場合は、スクリプトを見直します。
  • その後、-Onオプションを付与してOIDを数値形式で出力し、Centreon用のスクリプトに記載します。
    • <code># snmpwalk -v 1 -On -c private 127.0.0.1 .1.3.6.1.4.1.8072.1.3</code>

3.Centreon用のシェルスクリプト作成

  • 参考文献
  • 端的に、以下の2点が守られていればとりあえず機能する。
    • スクリプトの戻り値が、下記のいずれかであること
      • <code>0(=OK), 1(=WARNING), 2(=CRITICAL), 3(=UNKNOWN), 4(=DEPENDENT)</code>
    • スクリプトのstdout(ようするにprintの出力)が、以下の形式であること
      • <code>ぶんしょー | こんぽーねんと=値</code>
      • 「ぶんしょー」部分は、画面出力に使用するだけ。自由に設定。
      • パイプの後ろ側はグラフを描画するときに使用。グラフの要素名=値となるように記述。複数ある場合は半角スペースで区切る。
  • 今回作成したスクリプト
    • <code># cat checksnmphddtemp.pl #!/usr/bin/perl -w ################################################################# # # Help : ./checksnmphddtemp_temp.pl -h # use strict; use Net::SNMP; use Getopt::Long;

Nagios specific

use lib “/usr/local/nagios/libexec”; use utils qw(%ERRORS $TIMEOUT);

Net-snmp hddtemp

ここは人によりけりだと思うので、自分で調べる。

今思ったけど、tempratureの略をtempにしたのはアレだなぁ。

my $hddtemplines = “.1.3.6.1.4.1.8072.1.3.2.3.1.3.9.97.116.97.68.101.118.105.99.101”; my $hddtempname = “.1.3.6.1.4.1.8072.1.3.2.4.1.2.9.97.116.97.68.101.118.105.99.101”; my $hddtemp_temp = “.1.3.6.1.4.1.8072.1.3.2.4.1.2.20.97.116.97.68.101.118.105.99.101.84.101.109.112.101.114.97.116.117.114.101”;

Globals

my $Version= '0.1'; # version my $ohost= undef; # hostname my $ocommunity= undef; # community my $oport= 161; # port my $ohelp= undef; # wan't some help ? my $oversion= undef; # print version my $onetsnmp= 1; # Check with netsnmp (default) my $owarn= undef; # warning level option my $ocrit= undef; # Critical level option my $operf= undef; # Performance data option my $otimeout= undef; # Timeout (Default 5) my $o_version2= undef; # use snmp v2c

sub printusage { print “Usage: $0 [-v] -H <host> -C <snmpcommunity> [-2] | (-l login -x passwd [-X pass -L <authp>,<privp>]) [-p <port>] -w <warn level> -c <crit level> [-f] [-t <timeout>] [-V]\n”; }

sub help {

 print "\nSNMP S.M.A.R.T. Temprature Monrotr for Nagios version ",$Version,"\n";
 print "(c)2011 ainoniwa.net\n\n";
 print_usage;
 print <<EOT;

-h, –help

 print this help message

-H, –hostname=HOST

 name or IP address of host to check

-C, –community=COMMUNITY NAME

 community name for the host's SNMP agent (implies SNMP v1 or v2c with option)

-2, –v2c

 Use snmp v2c

-P, –port=PORT

 SNMP port (Default 161)

-w, –warn=INTEGER

 warning level for temprature

-c, –crit=INTEGER

 critical level for temprature

-f, –perfdata

 Performance data output

-t, –timeout=INTEGER

 timeout for SNMP in seconds (Default: 5)

-V, –version

 prints version number

EOT }

sub isnnum {

my $num = shift;
if ( $num =~ /^(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;}
return 1;

}

sub checkoptions { Getopt::Long::Configure (“bundling”); GetOptions( 'h' ⇒ \$ohelp, 'help' ⇒ \$ohelp, 'H:s' ⇒ \$ohost, 'hostname:s' ⇒ \$ohost, 'p:i' ⇒ \$oport, 'port:i' ⇒ \$oport, 'C:s' ⇒ \$ocommunity, 'community:s' ⇒ \$ocommunity, 't:i' ⇒ \$otimeout, 'timeout:i' ⇒ \$otimeout, 'V' ⇒ \$oversion, 'version' ⇒ \$oversion, 'f' ⇒ \$operf, 'perfdata' ⇒ \$operf, '2' ⇒ \$oversion2, 'v2c' ⇒ \$oversion2, 'c:s' ⇒ \$ocrit, 'critical:s' ⇒ \$ocrit, 'w:s' ⇒ \$owarn, 'warn:s' ⇒ \$owarn, ); if ( defined($ohelp) )

  { help(); exit $ERRORS{"UNKNOWN"}};
if ( defined($o_version))
  { p_version(); exit $ERRORS{"UNKNOWN"}};
if (!defined($o_host) )
  { print "No host defined!\n";print_usage(); exit $ERRORS{"UNKNOWN"}}
if (!defined($o_community))
  { print "Put snmp login info!\n";print_usage(); exit $ERRORS{"UNKNOWN"}}
if ( ! defined($o_warn) || ! defined($o_crit))
  { print "Put warning and critical values!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}}
if ( isnnum($o_warn) || isnnum($o_crit))
  { print "Numeric value for warning or critical !\n"; print_usage(); exit $ERRORS{"UNKNOWN"}}
if ($o_warn > $o_crit)
  { print "warning <= critical ! \n"; print_usage(); exit $ERRORS{"UNKNOWN"}}
if (!defined($o_timeout)) {$o_timeout=5;}

}

check_options();

Connect to host

my ($session,$error); if (defined ($oversion2)) { # SNMPv2 Login ($session, $error) = Net::SNMP→session( -hostname ⇒ $ohost,

  1. version ⇒ 2,
  2. community ⇒ $ocommunity, -port ⇒ $oport,
  3. timeout ⇒ $otimeout ); } else { # SNMPV1 login ($session, $error) = Net::SNMP→session( -hostname ⇒ $ohost,
  4. community ⇒ $ocommunity, -port ⇒ $oport,
  5. timeout ⇒ $o_timeout

); } if (!defined($session)) {

 printf("ERROR opening session: %s.\n", $error);
 exit $ERRORS{"UNKNOWN"};

}

Global variable

my $resultat=undef; my $result=undef; my @data=undef; my $lines=undef; my $name=undef; my $output=“Temprature :”; my $n_status = “OK”; my $NAME=0; my $DATA=1;

Net snmp memory check

Get NetSNMP hddtemp lines

$resultat = $session→getrequest($hddtemplines); if (!defined($resultat)) {

printf("ERROR: get_request hddtemp_lines : %s.\n", $session->error);
$session->close;
exit $ERRORS{"UNKNOWN"};

}

Get NetSNMP hddtemp data and ouput text create.

$lines = $$resultat{$hddtemplines}; while ( $lines > 0) { $name = $session→getrequest($hddtempname.“.”.$lines); $result = $session→getrequest($hddtemptemp.“.”.$lines); if ( !defined($name) && !defined($result) ) { printf(“ERROR: getrequest hddtemp_name : %s.\n”, $session→error);

  $session->close;
  exit $ERRORS{"UNKNOWN"};
}
# '5' is length of '/dev/'.
$data[$lines][$NAME] = substr($$name{$hddtemp_name.".".$lines},5);
$data[$lines][$DATA] = $$result{$hddtemp_temp.".".$lines};
$output             .= " ".$data[$lines][$NAME].":".$data[$lines][$DATA];
if ($data[$lines][$DATA] > $o_crit) {
  $output .= ">$o_crit!CRITICAL";
  $n_status = "CRITICAL";
} else {
if ($data[$lines][$DATA] > $o_warn) {
  $output .= ">$o_warn!WARNING";
  $n_status = "WARNING";
  }
}
$lines--;

}

### Perfdata Create

if (defined ($operf)) { $output .= “ | ”; $lines = $$resultat{$hddtemplines};

while ( $lines > 0) {
  $output .= $data[$lines][$NAME] ."=".$data[$lines][$DATA]." ";
  $lines--;
}

}

Last Output.

$session→close; print “$output \n”; exit $ERRORS{$n_status};</code>

  • CentreonにCommand登録する前に、手元で動作確認しておいたほうがいいよ。
    • <code>./checksnmphddtemp.pl -H 127.0.0.1 -C private -w 46 -c 50 -f</code>

4.CentreonにCommandの登録

  • 言葉だけ。
  • Configuration → Commands → Add
    • Command Name(自由に)
      • <code>hddtemp</code>
    • Command Line(動作確認用のコマンドと同じになるように)
      • <code>$USER1$/checksnmphddtemp.pl -H $HOSTADDRESS$ -C $USER2$ -w $ARG1$ -c $ARG2$ -f</code>
      • $USER1$,$USER2$は、Configure → Nagios → resourcesに設定されてる。
      • $HOSTADDRESS$は、Centreonの設定項目から自動的に引っ張ってくる。
        • 異なるホストを監視するのに、Command2つ作るのは面倒でゲソ。
      • $ARG1$,$ARG2$は、下記のArgument Exampleに示す値を、Services設定時に入れる。
        • 監視ホストによって値を変えたくなるでゲソ?
    • Argument Example
      • 空でもいいけど、$ARGn$に入る値の書き方を示すので書いていたほうがいい。
      • “!”で区切って、順次$ARGn$($ARG1$,$ARG2$…)に代入されるよ。
      • <code>!46!50</code>
    • $HOSTADDRESS$
      • 空でいい
    • Command Type
      • とりあえず“Check”
    • Graph template
      • 空でいい

5.Centreonに監視Servicesの登録

  • Configuration → Services → Add
    • Description : 適当な名前
    • Service Template : generic-service
      • 別にこれでなくてもいいけど。
    • Check Command : hddtemp
      • さっき作った名前
    • Args : 青い矢印クリック
      • さっき作った“!46!50”が入力されるよ。
    • Relations(上のタブにあるでゲソ)
      • Linked with Hosts : 対象ホストを選択してAdd
  • Saveして終わり。

6.Nagiosの再起動

  • Configuration → Nagios
  • 下記2つにチェックを追加して、“Export”
    • Move Export Files
    • Restart Nagios

7.動いてる図

management/centreon/hddtemp/start.txt · 最終更新: 2011/08/24 10:07 (外部編集)
CC Attribution-Noncommercial-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0