* [[サービス監視]] - 外部監視 [#fcc00e43]

  外部監視は「WEBアプリとして外部から利用可能か」を監視するので、監視処理自体は象サーバのあるネットワーク外に設置する。~
  外部監視は「WEBアプリとして外部から利用可能か」を監視するので、監視処理自体は対象サーバのあるネットワーク外に設置する。~
  ※監視処理への応答用の処理は対象サーバに設置しておく。~
  ※httpリクエストの結果からサーバ状態を判断するので余計なポートを空けたりしなくてもよい。~
 
#html(<table><tr><td colspan="2" style="font-size:100%;">  (1) 外部の監視処理からアクセスがあったときに状態を通知する下記のような処理を監視対象サーバに作成し、WEB公開ディレクトリに設置する。</td></tr><tr><td style="font-size:100%;">)
 <?php
 
 // 状態初期化
 $web_status  = "OK";
 $db_status   = "OK";
 $mail_status = "OK";
 
 // DB稼動チェック
 $DAO = new Dao("oracle");
 $DAO->err_log = "/var/log_db/status_chk_err.log";
 $DAO->log_write = TRUE;
 $DAO->connect(DB_NAME,DB_USER,DB_PASS);
 $res = $DAO->s_query("select 'OK' STATUS from dual");
 if ($res["tbl"][0]["STATUS"]!="OK"){ $db_status  = "NG";}
 $DAO->close();
 $DAO = NULL;
 
 // SMTPサーバ稼動チェック
 $cmd = 'ps -A | grep sendmail | wc -l | awk \'{print $1;}\'';
 $cnt = exec($cmd);
 if ($cnt==0){
 	$mail_status = "NG";
 }
 
 // 状態表示
 echo "{$web_status} {$db_status} {$mail_status}";
 ?>
#html(</td><td valign="top" style="font-size:100%;">)
[処理内容の補足]~

 ・ここではPHPにしたが稼動しているべきアプリの言語で&br;
  書くのがよいと思う。&br;

 ・SSLやBASIC認証と組み合わせて&br;
  一般ユーザからのアクセスを拒否したほうがよい。&br;

 ・DBにアクセスするアプリならDB接続を&br;
  メール送信するアプリならメールサーバの稼動確認を行う。&br;

 ・PHPのセーフモードがOnの場合はexecはダメだった気がする。&br;

 ※DB周りは自前のクラスライブラリを利用。

#html(</td></tr></table>)

#html(<table><tr><td colspan="2" style="font-size:100%;">  (2) 以下のようなスクリプトを対象サーバのネットワーク外にあるマシンに作成する</td></tr><tr><td style="font-size:100%;">)
 #!/bin/bash
 #
 # chkconfig: 345 99 01
 # description: Process Check
 # processname: chk_app
 #
 
 ### 設定 START ##############################
 
 # ステータス一時保存ファイル
 status_txt="/tmp/svr_status.txt"
 
 # このシェルの名前
 own_name=`basename ${0}`
 
 # 監視先サーバ名
 server_name="www.example-server.com"
 
 # 状態取得用URL
 chk_url="http://${server_name}/xxxxxxx/xxxxx.php"
 
 # チェック間隔(秒)
 chk_range=600
 
 # エラー時報告先ユーザ
 email_to_file="/xxxx/xxxx/ADMIN_MAIL"
 
 # 送信者
 email_from="svr-chk@example.com"
 
 # メール件名
 subject="サーバ(${server_name})外部監視"
 
 # メール送信用プログラム
 sendmail="/usr/sbin/sendmail"
 ### 設定 END ################################
 
 
 ### 関数定義 START ##########################
 
 ## HELP表示
 disp_help(){
         echo "
  使用法: `basename ${0}` start|stop
 
  プロセス監視を開始/終了する
 
  ※サーバの状態を外部監視します
 "
 }
 
 ## 報告メール送信
 report_mail(){
 
 email_to=`cat $email_to_file`
 
 mail_body=`echo "$1" | nkf -s`
 subject=`echo "$subject" | nkf -j`
 $sendmail -t <<_EOMAIL_
 To: $email_to
 From: $email_from
 Subject: $subject
 MIME-Version: 1.0
 Content-Transfer-Encoding: 7bit
 Content-Type: text/plain; charset="iso-2022-jp
 
 $mail_body
 .
 _EOMAIL_
 }
 
 
 ## 重複起動の回避処理
 kill_prc(){
 	all_prc=`ps -A -l`
 	while [ $# -gt 0 ]
 	do
 		all_prc=`ps -A -l | grep $1`
 		chk_prc="$1
 $all_prc"
 		kill_prc=`echo "$chk_prc" | awk '{
 		if(NR==1){
 			pid=$1;
 		} else {
 			if ($4==pid){
 				print $4" ";
 			}
 			if ($5==pid){
 				print $4" ";
 			}
 		}
 }'`
 		kill -9 $kill_prc >/dev/null 2>&1
 		shift
 	done	
 }
 
 ## サーバチェックメイン処理
 chk_app_main(){
 
 CR='
 '
 	## 状態の初期化
 	touch $status_txt
 	pre_status=`cat $status_txt`
 	if [ "$pre_status" == "" ];then
 		pre_status="INIT INIT INIT"
 	fi
 	pre_web_server=`echo "$pre_status" | awk '{print $1;}'`
 	pre_db_server=`echo "$pre_status" | awk '{print $2;}'`
 	pre_ml_server=`echo "$pre_status" | awk '{print $3;}'`
 
 	while [ ture ]
 	do
 
 		wget -O $status_txt $chk_url >/dev/null 2>&1
 
 		status=`cat $status_txt`
 
 		if [ "$pre_status" != "$status" ]; then
 
 			msg1=""
 			msg2=""
 			msg3=""
 
 			ml_status="停止"
 			db_status="停止"
 			web_status="停止"
 
 			web_server=`echo "$status" | awk '{print $1;}'`
 			db_server=`echo "$status" | awk '{print $2;}'`
 			ml_server=`echo "$status" | awk '{print $3;}'`
 
 			if [ "$web_server" != "$pre_web_server" ]; then
 				if [ "$web_server" == "OK" ]; then
 					web_status="起動"
 				fi
 				msg1="WEBサーバが${web_status}しました${CR}"
 			fi
 
 			if [ "$web_server" == "OK" ]; then
 
 				if [ "$db_server" != "$pre_db_server" ]; then
 					if [ "$db_server" == "OK" ]; then
 						db_status="起動"
 					fi
 					msg2="DB(Oracle)サーバが${db_status}しました${CR}"
 				fi
 
 				if [ $ml_server != "$pre_ml_server" ]; then
 					if [ "$ml_server" == "OK" ]; then
 						ml_status="起動"
 					fi
 					msg3="メール(SMTP)サーバが${ml_status}しました${CR}"
 				fi
 			fi
 
 			msg="${msg1}${msg2}${msg3}"
 
 			report_mail "$msg"
 		fi
 
 		#
 		pre_status="$status"
 		pre_web_server="$web_server"
 		pre_db_server="$db_server"
 		pre_ml_server="$ml_server"
 
 		# n秒待機
 		sleep $chk_range
 	done
 }
 ### 関数定義 END ############################
 
 
 ### メイン処理 START ########################
 
 
 # 引数取得
 case $1 in
 stop)
 	mode="stop"
 	;;
 start)
 	mode="start"
 	;;
 restart)
 	mode="start"
 	;;
 *)
 	disp_help
 	exit 0
 esac
 
 
 # 引数が指定されていないときはHELPを表示して終了
 if [ "$mode" == "" ]; then
 	disp_help
 	exit 0
 fi
 
 
 ## 重複起動の回避
 all_pid=`ps -A -l | grep $own_name`
 edt_pid=`echo "$$
 $all_pid"`
 kill_pid=`echo "$edt_pid" | awk '{
 if (NR == 1){
 	OWN=$1;
 } else {
 	if ($4 != OWN){
 	if ($5 != OWN){
 		print $4" ";
 	}
 	}
 }
 }'`
 if [ "$kill_pid" != "" ]; then
 	kill_prc $kill_pid
 fi
 
 
 # STOP時は終了
 if [ "$mode" == "stop" ];then
 	exit 0
 fi
 
 # チェック処理
 chk_app_main &
#html(</td><td valign="top" style="font-size:100%;">)
#html(</td></tr></table>)


#html(<table><tr><td colspan="2" style="font-size:100%;">  (3) 上記のシェルを /etc/init.d 以下に配置し、サービスとして初期起動するようにしておく。</td></tr><tr><td style="font-size:100%;">)
 # cp chk_app /etc/init.d/
 # chkconfig --add chk_app
 # chkconfig --level 345 chk_app on
#html(</td><td valign="top" style="font-size:100%;">)
[補足]~
 ・チェック処理自体が止まってしまった時の為に、&br;
  cronで定期的に実行するなどの工夫が必要かも。。~
#html(</td></tr></table>)

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS