トップへ(mam-mam.net/)

PHPとシェルスクリプトコマンドとCRONでサーバー監視

PHPとシェルスクリプトコマンドとCRONでサーバー監視

PHPの「shell_exec」関数を使うとシェルスクリプトのコマンドを実行することが出来ます。
シェルスクリプトの「top」コマンドや、「vmstat」+「awk」コマンドを使うとリソース情報を取得することが出来ます。
これらを使ったphpファイルを作り、
クーロンに5分毎に起動するように登録すると、サーバーを監視することが出来ます。
(例)
crontab -e
#以下の行を追加
*/5 * * * * /usr/bin/php /path/monitor.php > /dev/null 2>&1

「monitor.php」ファイル

<?php
//メールFrom
$from="webmaster@hoge.jp";
//メールTo
$to="webmaster@hoge.jp";
//件名
$subject="サーバー警告";

//閾値の設定(例)
$thresh=[
  "process"=>[
    "zombie"=>10 //ゾンビプロセス数が10個以上
  ],
  "cpu"=>[
    "ussy"=>95,  //5秒平均のCPU使用率が95%以上
    "wa"=>80     //IO待機時間の割合が80%以上
  ],
];
//警告メッセージ
$warning=[
  "process"=>[
    "zombie"=>"ゾンビプロセス数が %d で閾値(".$thresh["process"]["zombie"].")以上です。\r\n"
  ],
  "cpu"=>[
    "ussy"  =>"5秒平均のCPU使用率が %f で閾値(".$thresh["cpu"]["ussy"].")以上です。\r\n",
    "wa"    =>"IO待機時間の割合が %f で閾値(".$thresh["cpu"]["wa"].")以上です。\r\n".
              "ディスクIO又は通信IOが増加しています。\r\n"
  ],
];

$command='top -b -n 1|head -n 4';
$ret_top=shell_exec($command);
$ret_top=explode(",", preg_replace('/\r\n|\n/', ',', $ret_top));

$command='vmstat 1 5 | awk \'NR>2 {us+=$13; sy+=$14; id+=$15; wa+=$16} END {print us/5, ",", sy/5, ",", id/5, ",", wa/5}\'';
$ret_vmstat=shell_exec($command);
$ret_vmstat=explode(",", $ret_vmstat);

$val=[
  "process"=>[
    "running"   => intval(preg_replace('/[^\d]/','',$ret_top[7])),
    "sleeping"  => intval(preg_replace('/[^\d]/','',$ret_top[8])),
    "stopped"   => intval(preg_replace('/[^\d]/','',$ret_top[9])),
    "zombie"    => intval(preg_replace('/[^\d]/','',$ret_top[10])),
  ],
  "memory"=>[
    "free"      => intval(preg_replace('/[^\d]/','',$ret_top[20])),
    "used"      => intval(preg_replace('/[^\d]/','',$ret_top[21])),
    "buf_cache" => intval(preg_replace('/[^\d]/','',$ret_top[22])),
  ],
  "cpu"=>[
    //ユーザーモードCPU使用率+システムモードCPU使用率
    "ussy" => floatval($ret_vmstat[0])+floatval($ret_vmstat[1]),
    "id" => floatval($ret_vmstat[2]), //アイドル時間の割合
    "wa" => floatval($ret_vmstat[3]), //IO待機時間の割合
  ]
];

$message=[];
if($val["process"]["zombie"]>=$thresh["process"]["zombie"]){
  $message[]=sprintf($warning["process"]["zombie"], $val["process"]["zombie"]);
}
if($val["cpu"]["ussy"]>=$thresh["cpu"]["ussy"]){
  $message[]=sprintf($warning["cpu"]["ussy"], $val["cpu"]["ussy"]);
}
if($val["cpu"]["wa"]>=$thresh["cpu"]["wa"]){
  $message[]=sprintf($warning["cpu"]["wa"], $val["cpu"]["wa"]);
}

if(count($message)>0){
  $head = "From: ".$from."\r\n".
          "Reply-To: ".$from;
  $body = implode("\r\n", $message);
  $body.= "\r\n".
          "プロセス数(動作中)"  .$val["process"]["running"]."\r\n".
          "プロセス数(一時停止)".$val["process"]["sleeping"]."\r\n".
          "プロセス数(停止中)"  .$val["process"]["stopped"]."\r\n".
          "プロセス数(ゾンビ)"  .$val["process"]["zombie"]."\r\n".
          "\r\n".
          "メモリ(未使用)"      . $val["memory"]["free"] ."KB\r\n".
          "メモリ(使用)"        . $val["memory"]["used"] ."KB\r\n".
          "メモリ(バッファ/キャッシュ)" . $val["memory"]["buf_cache"] ."KB\r\n".
          "\r\n".
          "CPU(使用率)"         . $val["cpu"]["ussy"] ."KB\r\n".
          "CPU(アイドル率)"     . $val["cpu"]["id"] ."KB\r\n".
          "CPU(IO待ち)"         . $val["cpu"]["wa"] ."KB\r\n";
  mb_language('uni');
  mb_send_mail($to, $subject, $body, $head);
}