munin で死活チェック(死活監視)
munin で死活チェックをやりたいからプラグイン作った。
wget_pageってプラグインがあったんだけど、ちょっと追加したい機能があったので perlとmuninプラグインの練習もかねて apache_accesses を改造して作ってみた。
「perl初心者」が作ったので、熟練者から見れば「なんてことでしょう」ってところがあると思う。
一応、、動くみたい。
まだまだバグとかいろいろありそう。
もちろん動作保障なし。
こいつにできること。
特定のURLにアクセスして生きてるか死んでいるか調べます。
サーバの応答時間(秒)をグラフに描画します。
Host: ヘッダに対応しているので名前ベースのバーチャルドメインも超えられます。きゅんきゅん。
応答結果に特定の文字列が含まれているかどうか調べることもできます。
プラグインを作成する上で参考にさせていただいたウェブサイト
http://blog.enjoitech.jp/article/85
http://www.sdlab.org/wiki/doku.php?id=fedora8-munin
http://munin.projects.linpro.no/wiki/HowToWritePlugins
↓ここにインスコしてください。
/usr/share/munin/plugins/web_accesses
#!/usr/bin/perl # # Parameters supported: # # config # autoconf # # hide option # # autoconfigfile # ---> /etc/munin/plugin-conf.d/munin-node auto make. =head1 NAME web_accesses is web health check plugin. INSPIRE wget_page. This source was made based on apache_accesses. This configuration section shows the defaults of the plugin: [web_accesses] env.web0_url http://127.0.0.1/ env.web0_host myhost.local env.web0_grep <html> env.web0_proxy http://192.168.1.1:8080 env.web0_proxy_auth userid:password env.web1_url https://127.0.0.1/ env.web1_host secure.myhost.local env.web1_grep <html> env.web2_url https://127.0.0.1/ env.web2_host super.myhost.local <snip> env.web99_url https://127.0.0.1:8080/ env.web99_grep <html> env.web0_host and env.web0_grep is option paramater. The graph can hang by the response speed. The time-out is 60 seconds. The figure of 61 abnormalities is returned when becoming an error. 61 timeout or server status error (404 403 ... more) 62 When contents specified for grep are not included. health check ga dekiruyo! yattane taechan!! =head1 BUGS Does not support digest authentication. =head1 AUTHOR rti This source was made based on apache_accesses. =head1 LICENSE GPLv2 =cut my $ret = undef; if (! eval "require LWP::UserAgent;") { $ret = "LWP::UserAgent not found"; } # for ssl eval "require Crypt::SSLeay;"; if ( defined $ARGV[0] and $ARGV[0] eq "autoconf" ) { if ($ret) { print "no ($ret)\n"; exit 1; } if ( length(getHttpdSOption()) <= 0 ) { print "no (httpd)\n"; exit 1; } print "yes\n"; exit 0; } #hide option. if ( defined $ARGV[0] and $ARGV[0] eq "autoconfigfile" ) { # httpd -S my $virtualhosts = getHttpdSOption(); if ( length($virtualhosts) <= 0 ) { print "no (httpd)\n"; exit 1; } print "[web_accesses]\n"; my $scanmode = 0; my $i = 0; foreach my $line (split("\n",$virtualhosts)) { if ($scanmode == 0) { if ( $line =~ /^VirtualHost configuration/im || $line =~ /^wildcard NameVirtualHosts/im) { $scanmode = 1; } } elsif ($scanmode == 1) { #VirtualHost configuration if ( $line =~ /^.*?:([0-9]+?) +?([0-9a-zA-Z\.\-_]+?) /im || $line =~ /^ .*?port ([0-9\*]+?) +?namevhost ([0-9a-zA-Z\.\-_]+?) /im) { my $protocol = "http"; my $port = $1; my $host = $2; if ($port == "*") { $port = 80; } if ($port == 443) { $protocol = "https"; } print "env.web${i}_url $protocol://127.0.0.1:$port/\n"; print "env.web${i}_host $host\n"; print "#env.web${i}_ua mozilla\n"; print "#env.web${i}_grep <html>\n"; print "#env.web${i}_proxy http://192.168.1.1:8080\n"; print "#env.web${i}_proxy_auth userid:password\n"; $i ++; } } } exit; } if ( defined $ARGV[0] and $ARGV[0] eq "config" ) { print "graph_title Web Access Time\n"; print "graph_args --base 1000 --lower-limit -10 --upper-limit 70\n"; print "graph_vlabel sec of web access\n"; print "graph_category HealthCheck\n"; print "graph_info web access time\n"; for(my $i = 0; $i < 100 ; $i ++ ) { if (!exists $ENV{"web${i}_url"}) { next; } my $url = $ENV{"web${i}_url"}; my $host = "web{$i}"; if (exists $ENV{"web${i}_host"}) { $host = $ENV{"web${i}_host"}; } print "web${i}.label $host\n"; print "web${i}.info $host($url)\n"; print "web${i}.type gauge\n"; print "web${i}.draw LINE2\n"; print "web${i}.max 70\n"; print "web${i}.min -10\n"; print "web${i}.warning 50\n"; print "web${i}.critical 60\n"; } exit 0; } for(my $i = 0; $i < 100 ; $i ++ ) { if (!exists $ENV{"web${i}_url"}) { next; } my $ua = LWP::UserAgent->new(timeout => 60); my $request = HTTP::Request->new('GET',$ENV{"web${i}_url"}); if (exists $ENV{"web${i}_host"}) { $ua->default_header("Host"=>$ENV{"web${i}_host"}); } if (exists $ENV{"web${i}_ua"}) { $ua->agent($ENV{"web${i}_ua"}); } #proxy and proxy auth support. if (exists $ENV{"web${i}_proxy"}) { $ua->proxy('http', $ENV{"web${i}_proxy"}); if (exists $ENV{"web${i}_proxy_auth"}) { my $auth_sep = index($ENV{"web${i}_proxy_auth"} , ":"); if ($auth_sep >= 1) { $request->proxy_authorization_basic( substr($ENV{"web${i}_proxy_auth"},0 , $auth_sep) , substr($ENV{"web${i}_proxy_auth"},$auth_sep + 1) ); } } } #redirect off. $ua->requests_redirectable([]); my $requesttime = time; my $response = $ua->request($request); $requesttime = time - $requesttime; if ( $response->code <= 199 || $response->code >= 400 ) { #bad respons code $requesttime = 61; } else { if (exists $ENV{"web${i}_grep"}) { my $grep = $ENV{"web${i}_grep"}; if ( ! ($response->content =~ /$grep/im) ) { #bad respons contents $requesttime = 62; } } } print "web${i}.value $requesttime\n"; } #`httpd -S` result. sub getHttpdSOption() { my $virtualhosts = `httpd -S 2>&1`; if (length($virtualhosts) > 0) { return $virtualhosts; } my $virtualhosts = `/usr/sbin/httpd -S 2>&1`; if (length($virtualhosts) > 0) { return $virtualhosts; } #for debian $virtualhosts = `apache2 -S 2>&1`; if (length($virtualhosts) > 0) { return $virtualhosts; } #for source build $virtualhosts = `/usr/local/apache2/sbin/apache -S 2>&1`; if (length($virtualhosts) > 0) { return $virtualhosts; } #not found... return ""; } # vim:syntax=perl
プラグインを有効にします。
ln -s /usr/share/munin/plugins/web_accesses /etc/munin/plugins/web_accesses
設定を書きます。
vi /etc/munin/plugin-conf.d/munin-node
設定ファイルの書式は、、、えっ、、そんな面倒なことやってられるかって。
ごもっともです。
↓こんな感じで実行すると、httpd -S の結果から設定ファイルに書くべき内容を自動生成してくれますwww
perl /usr/share/munin/plugins/web_accesses autoconfigfile
例
debian:/etc/munin/plugins# perl /usr/share/munin/plugins/web_accesses autoconfigfile
[web_accesses]
env.web0_url http://127.0.0.1:80/
env.web0_host debian.localdomain
#env.web0_ua mozilla
#env.web0_grep
env.web1_url http://127.0.0.1:81/
env.web1_host debian.localdomain
#env.web1_ua mozilla
#env.web1_grep
env.web2_url http://127.0.0.1:80/
env.web2_host mytest.local
#env.web2_ua mozilla
#env.web2_grep
設定ファイルを開いて、一番下に、先ほど自動生成した内容をコピペします。
vi /etc/munin/plugin-conf.d/munin-node
muninを再起動します。
/etc/init.d/munin-node restart
今すぐ値が見たいせっかちさんは↓を実行
グラフのパラメータの確認
perl /usr/share/munin/plugins/web_accesses config
取得した値の確認
perl /usr/share/munin/plugins/web_accesses
ここでなんかエラーが出たりすると、、、動いていないです。残念。
うまくそれっぽい値が表示されたら、多分大丈夫です。
あとは、5分ぐらい待って、グラフに HealthCheck ってカテゴリーができていれば完成です。
グラフを -10からスタートしているのは、たいていリクエストは 0秒で即答されてしまうので、つまんないからです。
底上げってやつですね。パッド!!パッド!!
リクエストには、60秒のタイムアウトが設定されてます。
でも、グラフは70秒まであります。
実は 61以上はフラグに使っています。
- 61 サーバーが 404 Not Found等の失敗のコードを返した。
- 62 サーバの応答にgrepで指定した文字列が含まれなかった。
一応、設定ファイルの説明を!!
[web_accesses]
env.web0_url http://127.0.0.1:80/ ←アクセスするURL(必須)
env.web0_host debian.localdomain ←host名 Host: ヘッダにも使う。つけたほうがいいけど必須にあらず
#env.web0_ua mozilla ←UserAgent偽造 UAではじいているサイトは googlebot とかに(ry
#env.web0_grep ←サーバの応答に含まれていてほしい文字列
下の二つのパラメタは作ったけどまだ動かしてませんwww
コメントアウトしといてください。
いや、だってももう1:30ですよ、眠いです。しんぢゃいます。明日直すよ。
9/9追記
やっぱりバグっていたんで直しましたw