お盆休みに向けてphpでサーバーの死活監視

お盆休み、PCの環境から離れてしまうので、死活監視をいれてみよう!と考える。
いろいろと機能豊富なツールもあるようだが、
インストールや設定がちょっと面倒。
そもそもhttpdやmysqldの生存確認だけ最低限できればいいや、、
ということで、phpで組むことに。

設定ファイルはyamlphpから読むためにspycをrequireする。
設置は下記のような感じで、pingが通るか、httpはphpからget_file_contentsしてアクセスできるか、mysqlは実際に接続が成功するかで、比較的簡単に書けた。

数分おきにcronで起動。
エラーが1件でも起きたらメールでお知らせしてくれるようにしました。
設定ファイルは3パターン
1.ping 2.http 3.mysql
それぞれ追加していけばモリモリ監視対象は増やせる仕組み。

下記ひとまず作ったものの、エラーが解消されない限り永遠にメールが送りつけられるので、
1度起こったエラーに対しては24時間後に再度送るとか、処理をいれたほうが良さそうだなぁ。。


設置

directory
|---check_server.php (phpのバッチ)
|---spyc.php   (http://code.google.com/p/spyc/downloads/list)
|---watch_list.yml(設定ファイル)


check_server.php

<?php
require_once 'spyc.php';

class Check {
  function ping_check($ping_ip){
    $ping_command_str = "ping -c 3 -w 5 $ping_ip";
    if(!strstr('$ping_command_str','100% packet loss')){
      return true;
    }else{
      return false;
    }
  }

  function http_check($url){
    if ($res = @file_get_contents("$url")) {
      return true;
    } else {
      return false;
    }
  }

  function mysql_check($host,$user,$pass){
     if($conn = mysql_connect($host,$user,$pass)){
       return true;
     }else{
       return false;
     }
  }

  function send_mail($mail_to,$mail_from,$contents,$header){
    $mail_header = "From: ".$mail_from;
    mail($mail_to,'check result',$contents,$header);
  }
}


print "CheckStart \n";
$error_count = 0;
$alert_txt = 'Error_Message:';
$yml_array = Spyc::YAMLLoad('watch_list.yml');
$check = new Check;

print ini_get('allow_url_fopen');
//ping
foreach($yml_array['ping'] as $ping_data){
  $ping_return = $check->ping_check($ping_data['ip']);
  if($ping_return == false){
    print $ping_data['name']."IS PING_FALSE \n";
    $alert_txt .= $ping_data['name']."IS PING_FALSE \n";
    $error_count+=1;
  }else{
    print $ping_data['name']."IS PING_OK \n";
  }
}
//http
foreach($yml_array['http'] as $http_data){
  $http_return = $check->http_check($http_data['url']);
  if($http_return == false){
    print $http_data['name']."IS HTTP_FALSE \n";
    $alert_txt .= $http_data['name']."IS HTTP_FALSE \n";
    $error_count+=1;
  }else{
    print $http_data['name']."IS HTTP_OK \n";
  }
}
//mysql
foreach($yml_array['mysql'] as $mysql_data){
  $http_return = $check->mysql_check($mysql_data['host'],$mysql_data['user'],$mysql_data['pass']);
  if($http_return == false){
    print $mysql_data['name']."IS MYSQL_FALSE \n";
    $alert_txt .= $mysql_data['name'].'IS MYSQL_FALSE';
    $error_count+=1;
  }else{
    print $mysql_data['name']."IS MYSQL_OK \n";
  }
}
if($error_count>=1){
  $header =  "error count >> $error_count";
  $check->send_mail($yml_array['info']['mail_to'],$yml_array['info']['mail_from'],$alert_txt,$header);
}
print "CheckFinished \n";


?>


watch_list.yml

info:
  mail_to:test@gmail.com
  mail_from:test@gmail.com

ping:
  - data:
    name: 監視サーバーA
    ip: 192.168.0.1
  - data:
    name: 監視サーバーB
    ip: 192.168.0.1

http:
  - data:
    name: 監視サーバーA
    url: http://test.com/
  - data:
    name: 監視サーバーB
    url: http://test.com/

mysql:
  - data:
    name: 監視サーバーA
    host: 192.168.0.1
    user: root
    pass: test
    database:
  - data:
    name: 監視サーバーB
    host: 192.168.0.1
    user: root
    pass: test
    database: