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分が逆になっている様だな。