変奏現実

パソコンやMMORPGのことなどを思いつくまま・・・記載されている会社名・製品名・システム名などは、各社の商標、または登録商標です。

この画面は、簡易表示です

CentOS6.2

PHPでSNMP監視

phpでsnmp監視できるらしい。
元ネタはSNMPの活用(4) – ホスト情報をMySQLに自動蓄積~グラフの生成
CentOS6.2ではどうなるのかな。
まずphp-pearとphp-snmpを入れた方がいいらしい。

# pear -V

でコマンドがありませんと出たら、

# yum list php-*

で見るとphp用のモジュールはいっぱいあるのが判る。@が無いのはインストールしていないモジュールだ。

# yum list php-pear php-snmp

Available Packages
php-pear.noarch                        1:1.9.4-4.el6                        base
php-snmp.i686                       5.3.3-3.el6_2.5                      updates

と出たら、

# yum -y install php-pear

で、pearをインストする必要がある。
# pear -V
再度確認すると

Installed Packages
php-pear.noarch                       1:1.9.4-4.el6                        @base
php-snmp.i686                       5.3.3-3.el6_2.5                     @updates

と出るはずだ。
次にDB.phpもインストしないと使えないので

# pear install DB

WARNING: “pear/DB” is deprecated in favor of “pear/MDB2”
downloading DB-1.7.14.tgz …
Starting to download DB-1.7.14.tgz (133,103 bytes)
………………………..done: 133,103 bytes
install ok: channel://pear.php.net/DB-1.7.14

# find / -name DB.php -print

/usr/share/pear/DB.php

でやっと入ったようだ。
1.phpmyadminでSNMP専用のデータベースを作る。
2.phpmyadminでそのデータベースにテーブルを作る。

snmpで調べる対象を登録するテーブルを作る。

create table snmp_object (
code int PRIMARY KEY,
object_id_1m   varchar(255),
object_id_5m   varchar(255),
title   varchar(255),
sub_title_1m   varchar(255),
sub_title_5m   varchar(255)
);

snmpで調べる対象をテーブルに登録する。

insert into snmp_object(code,object_id_1m,object_id_5m,title,sub_title_1m,sub_title_5m)
values(0,’.1.3.6.1.2.1.2.2.1.10.2′,’.1.3.6.1.4.1.2021.9.1.9.1′,’.1.3.6.1.2.1.2.2.1.16.2′,’In’,’Out’);

insert into snmp_object(code,object_id_1m,object_id_5m,title,sub_title_1m,sub_title_5m)
values(1,’.1.3.6.1.4.1.2021.10.1.5.1′,’.1.3.6.1.4.1.2021.10.1.5.2′,’CPU使用率’,’1分間平均’,’5分間平均’);

insert into snmp_object(code,object_id_1m,object_id_5m,title,sub_title_1m,sub_title_5m)
values(2,’.1.3.6.1.4.1.2021.4.6.0′,’.1.3.6.1.4.1.2021.4.4.0′,’空きメモリ量’,’空き物理メモリ’,’空きスワップメモリ’);

insert into snmp_object(code,object_id_1m,object_id_5m,title,sub_title_1m,sub_title_5m)
values(3,’.1.3.6.1.4.1.2021.9.1.9.1′,’.1.3.6.1.4.1.2021.9.1.9.1′,’ディスク使用率’,’/ Disk used’,’/ Disk used’);

データを格納するテーブルを作る。

create table log (
snmp_time   timestamp    PRIMARY KEY,
code int,
snmp_val_1m    varchar(255),
snmp_val_5m    varchar(255)
);

ALTER TABLE `log`
DROP PRIMARY KEY,
ADD PRIMARY KEY(
`code`,
`snmp_time`);

phpはコマンドラインからも使えるようになっているので、
3.こんなスクリプトを作る。

#!/usr/bin/php
<?php
/**************
**snmpget.php**
**************/
require_once(“DB.php”);
snmp_set_quick_print(1);
$dsn = “mysql://<database-username>:<database-passward>@<host-name>/<database-name>;
$ipaddr =<ip-address>;
$community = “public”;
// MySQLに接続
$db = DB::connect($dsn);
// 文字セットを指定
$db->query(” SET NAMES ‘utf8’ “);
// 設定を読み出す
$sql = “SELECT code, object_id_1m, object_id_5m, title from snmp_object”;
$code_res = $db->query($sql);
if ($code_res !== false){
while ($row =& $code_res->fetchRow()) {
$code =         $row[0];
$object_id_1m = $row[1];
$object_id_5m = $row[2];
$title =        $row[3];
// snmpからデータ収集
$snmp_val_1m = (float)snmpget($ipaddr, $community, $object_id_1m);
$snmp_val_5m = (float)snmpget($ipaddr, $community, $object_id_5m);
if ($snmp_val_1m !== false && $snmp_val_5m !== false) {
// データベースへ書き込み
$sql = sprintf(“insert into log(snmp_time,code,snmp_val_1m,snmp_val_5m) values(CURRENT_TIMESTAMP,%s,’%s’,’%s’);”,
$code,$snmp_val_1m,$snmp_val_5m);
$res = $db->query($sql);
if (PEAR::isError($res)) {
// print $sql . ” fail.\n”;
} else {
// print “success.\n”;
}
}
}
} else {
// print “fail. no object.^n”;
}

$db->disconnect();
?>

これを実行するとデータが格納される。

select * from log;

とりあえず、MRTGのクローン設定に

*/5 * * * * root /root/snmpget.php

を居候させて様子を見てみよう。
あとはグラフ化すれば良いのだけれど、
データが充分溜まったらやろうかな。
出来上がったCPU負荷率グラフはコレ。
※Highcharts-2.1.9のサンプルのseries: 部分に、PHPコードを組み込んだだけもの。

series: [
<?php
require_once(“DB.php”);
snmp_set_quick_print(1);

$dsn = “mysql://<database-username>:<database-passward>@<host-name>/<database-name>;

// MySQLに接続
$db = DB::connect($dsn);
// 文字セットを指定
$db->query(” SET NAMES ‘utf8’);

$sql = “SELECT code, title, sub_title_1m, sub_title_5m from snmp_object where code=1;”;
$code_res = $db->query($sql);
if ($code_res !== false){
  while ($row =& $code_res->fetchRow()) {
  $code =         $row[0];
  $title =        $row[1];
  $sub_title_1m = $row[2];
  $sub_title_5m = $row[3];
  }

  $sql = “SELECT snmp_time, code, snmp_val_1m, snmp_val_5m from log where code=1 order by snmp_time;”;
  $res = $db->query($sql);
  $d1 = array();
  $d5 = array();
  $cnt=0;
  $start_time = new DateTime();
  while ($row =& $res->fetchRow()) {
    // PHPでmysqlでtimestamp型をうまく扱えない様なので
    $snmp_time =   . $row[0];       // 一旦文字列に変換して
    $start_time0 = new DateTime($snmp_time, new DateTimeZone(JST));  // DateTime型に取り込んでみた。
    if( $start_time > $start_time0 ) {
      $start_time = $start_time0;
    }
    $code =        $row[1];
    $snmp_val_1m = $row[2];
    $snmp_val_5m = $row[3];
    $d1[$cnt] = $snmp_val_1m;
    $d5[$cnt] = $snmp_val_5m;
    $cnt = $cnt +1;
  }
  $d1_text = join(“,”,$d1);
  $d5_text = join(“,”,$d5);
  echo “{\n”;
  echo “type: ‘area’,\n”;
  echo “name: ‘” . $sub_title_1m . “‘,\n”;
  echo “pointInterval: 5 * 60 * 1000,\n”;
  echo “pointStart: Date.UTC(“ . date_format($start_time,‘Y’) . “,” . (0+date_format($start_time,‘m’)-1) . “,” . date_format($start_time,‘d’) . “,” . date_format($start_time,‘H’) . “,” . date_format($start_time,‘i’) . “,” . date_format($start_time,‘s’) . “,0),\n”;
  echo “data: [” . $d1_text . ” ]\n”;
  echo “},{\n”;
  echo “name: ‘” . $sub_title_5m . “‘,\n”;
  echo “pointInterval: 5 * 60 * 1000,\n”;
  echo “pointStart: Date.UTC(“ . date_format($start_time,‘Y’) . “,” . (0+date_format($start_time,‘m’)-1) . “,” . date_format($start_time,‘d’) . “,” . date_format($start_time,‘H’) . “,” . date_format($start_time,‘i’) . “,” . date_format($start_time,‘s’) . “,0),\n”;
  echo “data: [” . $d5_text . ” ]\n”;
  echo “}\n”;
}
$db->disconnect();
?>
]

実行結果はこんな感じ

series: [
{
type: ‘area’,
name: ‘1分間平均’,
pointInterval: 5 * 60 * 1000,
pointStart: Date.UTC(2012,1,02,04,20,02,0),
data: [169,154,138,125,104,40,1,0,0,0,0,1,0,2,0,0,0,0,5,0,0,0,1,0,1,5,1,0,0,0,4,0,5,0,0,0,0,0,1,0,1,1,0,19,0,0,1,2,0,0,0,7,0,2,0,0,0,0,2,0,1,0,0,0,0,0,0,0,11,4 ]
},{
name: ‘5分間平均’,
pointInterval: 5 * 60 * 1000,
pointStart: Date.UTC(2012,1,02,04,20,02,0),
data: [132,129,135,130,116,93,34,11,2,1,1,2,2,2,1,1,0,0,1,0,0,0,1,0,1,1,0,0,0,0,2,0,2,0,0,0,0,0,1,0,1,0,0,4,1,0,1,2,0,0,0,2,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1,0,8,8 ]
}
]

グラグの見た目はこんな感じに。

100%制限を無くすと、

MRTGと比べるとどうだろう。

1分と5分が逆になっている様だな。




top