Code

Fix for regex input of '|', being output causing problems with Nagios' parsing of
[nagiosplug.git] / contrib / check_apache.pl
1 #!/usr/bin/perl
2 #
3 # (c)2001 Sebastian Hetze, Linux Information Systems AG
4 # send bug reports to <S.Hetze@Linux-AG.com>
5
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty
13 # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # you should have received a copy of the GNU General Public License
17 # along with this program (or with Nagios);  if not, write to the
18 # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 # Boston, MA 02111-1307, USA
20 #
21 #
22 # Check apache status information provided by mod_status to find
23 # out about the load (number of servers working) and the
24 # performance (average response time for recent requests).
25 #
26 # Usage:
27 # check_apache -H <host> [-lhV] [-w <warn>] [-c <crit>] [-u <url>]
28 #
29 # check_apache <host> <warn> <crit> <url> (if you cannot avoid it)
30 #
32 use LWP::UserAgent;
33 use URI::URL;
34 use Getopt::Long;
35 Getopt::Long::Configure('bundling');
37 $version=0.01;
39 my %ERRORS = ('UNKNOWN' , '-1',
40               'OK' , '0',
41               'WARNING', '1',
42               'CRITICAL', '2');
45 #
46 #              some default values
47 #
48 $perf_w=500;
49 $perf_c=1000;
50 $load_w=20;
51 $load_c=30;
52 $TIMEOUT=15;
54 #
55 #              get command line options the regular way
56 #
57 GetOptions
58         ("V"   => \$opt_V, "version"       => \$opt_V,
59          "h"   => \$opt_h, "help"          => \$opt_h,
60          "l"   => \$opt_l, "load"          => \$opt_l,
61          "v" => \$verbose, "verbose"       => \$verbose,
62          "w=s" => \$opt_w, "warning=s"     => \$opt_w,
63          "c=s" => \$opt_c, "critical=s"    => \$opt_c,
64          "H=s" => \$opt_H, "hostname=s"    => \$opt_H,
65          "u=s" => \$opt_u, "url=s"         => \$opt_u);
67 #
68 #              handle the verbose stuff first
69 #
70 if ($opt_V) {
71         print "\n";
72         print "check_apache nagios plugin version $version\n";
73         print "\n";
74         print "The nagios plugins come with ABSOLUTELY NO WARRANTY.  You may redistribute\n";
75         print "copies of the plugins under the terms of the GNU General Public License.\n";
76         print "For more information about these matters, see the file named COPYING.\n";
77         print "\n";
78         print "Copyright (c) 2001 Sebastian Hetze  Linux Information Systems AG\n";
79         print "\n";
80         print "\n";
81         exit $ERRORS{'UNKNOWN'};
82
84 if ($opt_h) {
85         print_help();
86         exit $ERRORS{'UNKNOWN'};
87 }
89 #
90 #              now get options the weired way and set the defaults
91 #              if nothing else is provided
92 #
93 $opt_H = shift unless ($opt_H);
94 print_usage() unless ($opt_H);
96 if($opt_l) {
97    $autostring="?auto";
98    ($opt_w) || ($opt_w = shift) || ($opt_w = $load_w);
99    $warn = $1 if ($opt_w =~ /([0-9]+)/);
100    ($opt_c) || ($opt_c = shift) || ($opt_c = $load_c);
101    $alert = $1 if ($opt_c =~ /([0-9]+)/);
102 } else {
103    $autostring="";
104    ($opt_w) || ($opt_w = shift) || ($opt_w = $perf_w);
105    $warn = $1 if ($opt_w =~ /([0-9]+)/);
106    ($opt_c) || ($opt_c = shift) || ($opt_c = $perf_c);
107    $alert = $1 if ($opt_c =~ /([0-9]+)/);
110 ($opt_u) || ($opt_u = shift) || ($opt_u = "/server-status");
114 #              dont let us wait forever...
116 $SIG{'ALRM'} = sub {
117      print ("ERROR: No response from HTTP server (alarm)\n");
118      exit $ERRORS{"UNKNOWN"};
119 };
120 alarm($TIMEOUT);
124 #              now we set things up for the real work
125 #              and fire up the request
127 $ua = new LWP::UserAgent;
128 $ua->agent("Nagios/0.1 " . $ua->agent);
131 $urlstring = "http://" . $opt_H . $opt_u . $autostring;
132 $url = url($urlstring);
134 my $req = new HTTP::Request 'GET', $url;
135 my $res = $ua->request($req);
138 #              hopefully we´ve got something usefull
140 if ($res->is_success) {
141   if($opt_l) {
142      foreach $_ (split /^/m, $res->content) {
143         next if /^\s*$/;
145 #              this is the load checking section
146 #              we parse the whole content, just in case someone
147 #              wants to use this some day in the future
149         if (/^Total Accesses:\s+([0-9.]+)/) { $accesses = $1; next; }
150         if (/^Total kBytes:\s+([0-9.]+)/) { $kbytes = $1; next; }
151         if (/^CPULoad:\s+([0-9.]+)\s+/) { $load = $1; next; }
152         if (/^Uptime:\s+([0-9.]+)\s+/) { $uptime = $1; next; }
153         if (/^ReqPerSec:\s+([0-9.]+)\s+/) { $rps = $1; next; }
154         if (/^BytesPerSec:\s+([0-9.]+)\s+/) { $bps = $1; next; }
155         if (/^BytesPerReq:\s+([0-9.]+)\s+/) { $bpr = $1; next; }
156         if (/^BusyServers:\s+([0-9.]+)\s+/) { $busy = $1; next; }
157         if (/^IdleServers:\s+([0-9.]+)\s+/) { $idle = $1; next; }
158         if (/^Scoreboard:\s+([SRWKDLG_.]+)\s+/) { $score = $1; next; }
159         print "Unknown Status\n";
160         exit $ERRORS{"UNKNOWN"};
161      }
163 #              now we even parse the whole scoreboard, just for fun
165      foreach $scorepoint (split //m, $score) {
166         if($scorepoint eq '.') { $scores{'.'}+=1; next; }  # Unused
167         if($scorepoint eq '_') { $scores{'_'}+=1; next; }  # Waiting
168         if($scorepoint eq 'S') { $scores{'S'}+=1; next; }  # Starting
169         if($scorepoint eq 'R') { $scores{'R'}+=1; next; }  # Reading
170         if($scorepoint eq 'W') { $scores{'W'}+=1; next; }  # Writing
171         if($scorepoint eq 'K') { $scores{'K'}+=1; next; }  # Keepalive
172         if($scorepoint eq 'D') { $scores{'D'}+=1; next; }  # DNS Lookup
173         if($scorepoint eq 'L') { $scores{'L'}+=1; next; }  # Logging
174         if($scorepoint eq 'G') { $scores{'G'}+=1; next; }  # Going
175      }
177      if($busy>$alert) {
178         printf "HTTPD CRITICAL: %.0f servers running\n", $busy;
179         exit $ERRORS{"CRITICAL"};
180      }
181      if($busy>$warn) {
182         printf "HTTPD WARNING: %.0f servers running\n", $busy;
183         exit $ERRORS{"WARNING"};
184      }
185      printf "HTTPD ok: %.0f servers running, %d idle\n", $busy, $idle;
186      exit $ERRORS{"OK"};
188   } else {
190 #              this is the performance check section
191 #              We are a bit lazy here, no parsing of the initial data
192 #              block and the scoreboard.
193 #              However, you have the whole set of per server
194 #              information to play with ;-)
195 #              The actual performance is measured by adding up the
196 #              milliseconds required to process the most recent
197 #              requests of all instances and then taking the average.
199      foreach $tablerow (split /<tr>/m, $res->content) {
200          ($empty,$Srv,$PID,$Acc,$M,$CPU,$SS,$Req,$Conn,$Child,$Slot,$Client,$VHost,$Request)
201          = split /<td>/, $tablerow;
202          if($Req) {
203               $lines+=1;
204               $req_sum+=$Req;
205          }
206          undef $Req;
207      }
208      $average=$req_sum/$lines;
209      if($average>$alert) {
210         printf "HTTPD CRITICAL: average response time %.0f
211         milliseconds\n", $average;
212         exit $ERRORS{"CRITICAL"};
213      }
214      if($average>$warn) {
215         printf "HTTPD WARNING: average response time %.0f
216         milliseconds\n", $average;
217         exit $ERRORS{"WARNING"};
218      }
219      if($average>0) {
220         printf "HTTPD ok: average response time %.0f milliseconds\n",
221         $average;
222         exit $ERRORS{"OK"};
223      }
224      print "Unknown Status\n";
225      exit $ERRORS{"UNKNOWN"};
226   }
227 } else {
228         print "HTTP request failed\n";
229         exit $ERRORS{"CRITICAL"};
234 #              ok, now we are almost through
235 #              These last subroutines do the things for those that do not
236 #              read source code.
238 sub print_usage () {
239         print "Usage: $0 -H <host> [-lhV] [-w <warn>] [-c <crit>] [-u <url>]\n"; }
240  
241 sub print_help () {
242         print "\n";
243         print "\n";
244         print "check_apache nagios plugin version $version\n";
245         print "\n";
246         print "The nagios plugins come with ABSOLUTELY NO WARRANTY.  You may redistribute\n";
247         print "copies of the plugins under the terms of the GNU General Public License.\n";
248         print "For more information about these matters, see the file named COPYING.\n";
249         print "\n";
250         print "Copyright (c) 2001 Sebastian Hetze  Linux Information Systems AG\n";
251         print "\n";
252         print "\n";
253         print "This plugin checks the apache HTTP service on the specified host.\n";
254         print "It uses the mod_status facilities provided by the apache server.\n";
255         print "The monitoring server must be authorized in httpd.conf.\n";
256         print "\n";
257         print "\n";
258         print_usage();
259         print "\n";
260         print "Options:\n";
261         print " -H, --hostname=ADDRESS\n";
262         print "     host name argument for server.\n";
263         print " -l, --load\n";
264         print "     check load instead of performance.\n";
265         print " -h, --help\n";
266         print "     print detailed help screen.\n";
267         print " -V, --version\n";
268         print "     print version information.\n";
269         print " -w, --warning=INTEGER\n";
270         print "     load / performance level at which a warning message will be gererated.\n";
271         print " -c, --critical=INTEGER\n";
272         print "     load / performance level at which a critical message will be gererated.\n";
273         print " -u, --url=PATH\n";
274         print "     location to call mod_status.\n";
275         print "\n";
276         print "     Defaults for performance checking are $perf_w/$perf_c msec.\n";
277         print "     Defaults for load checking are $load_w/$load_c servers running.\n";
278         print "\n";
279         print "\n";
280
282 #              the end