diff options
Diffstat (limited to 'contrib/check_apache.pl')
-rw-r--r-- | contrib/check_apache.pl | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/contrib/check_apache.pl b/contrib/check_apache.pl new file mode 100644 index 0000000..b9e69a0 --- /dev/null +++ b/contrib/check_apache.pl | |||
@@ -0,0 +1,283 @@ | |||
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 | # | ||
31 | |||
32 | use LWP::UserAgent; | ||
33 | use URI::URL; | ||
34 | use Getopt::Long; | ||
35 | Getopt::Long::Configure('bundling'); | ||
36 | |||
37 | $version=0.01; | ||
38 | |||
39 | my %ERRORS = ('UNKNOWN' , '-1', | ||
40 | 'OK' , '0', | ||
41 | 'WARNING', '1', | ||
42 | 'CRITICAL', '2'); | ||
43 | |||
44 | |||
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; | ||
53 | |||
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); | ||
66 | |||
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 | } | ||
83 | |||
84 | if ($opt_h) { | ||
85 | print_help(); | ||
86 | exit $ERRORS{'UNKNOWN'}; | ||
87 | } | ||
88 | |||
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); | ||
95 | |||
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]+)/); | ||
108 | } | ||
109 | |||
110 | ($opt_u) || ($opt_u = shift) || ($opt_u = "/server-status"); | ||
111 | |||
112 | |||
113 | # | ||
114 | # dont let us wait forever... | ||
115 | # | ||
116 | $SIG{'ALRM'} = sub { | ||
117 | print ("ERROR: No response from HTTP server (alarm)\n"); | ||
118 | exit $ERRORS{"UNKNOWN"}; | ||
119 | }; | ||
120 | alarm($TIMEOUT); | ||
121 | |||
122 | |||
123 | # | ||
124 | # now we set things up for the real work | ||
125 | # and fire up the request | ||
126 | # | ||
127 | $ua = new LWP::UserAgent; | ||
128 | $ua->agent("Nagios/0.1 " . $ua->agent); | ||
129 | |||
130 | |||
131 | $urlstring = "http://" . $opt_H . $opt_u . $autostring; | ||
132 | $url = url($urlstring); | ||
133 | |||
134 | my $req = new HTTP::Request 'GET', $url; | ||
135 | my $res = $ua->request($req); | ||
136 | |||
137 | # | ||
138 | # hopefully we´ve got something usefull | ||
139 | # | ||
140 | if ($res->is_success) { | ||
141 | if($opt_l) { | ||
142 | foreach $_ (split /^/m, $res->content) { | ||
143 | next if /^\s*$/; | ||
144 | # | ||
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 | ||
148 | # | ||
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 | } | ||
162 | # | ||
163 | # now we even parse the whole scoreboard, just for fun | ||
164 | # | ||
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 | } | ||
176 | |||
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"}; | ||
187 | |||
188 | } else { | ||
189 | # | ||
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. | ||
198 | # | ||
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"}; | ||
230 | } | ||
231 | |||
232 | |||
233 | # | ||
234 | # ok, now we are almost through | ||
235 | # These last subroutines do the things for those that do not | ||
236 | # read source code. | ||
237 | # | ||
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 | } | ||
281 | # | ||
282 | # the end | ||
283 | # | ||