/[nagios-plugins-perl]/trunk/plugins/check_phpfpm_status.pl
ViewVC logotype

Contents of /trunk/plugins/check_phpfpm_status.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 196 - (show annotations) (download)
Tue May 29 10:17:21 2018 UTC (2 years, 6 months ago) by racvision
File MIME type: text/plain
File size: 27177 byte(s)
add commands & perl scripts for check_phpfpm_status check_mysql_health
1 #!/usr/bin/env perl
2 # check_phpfpm_status.pl
3 # Version : 1.1
4 # Author : regis.leroy at makina-corpus.com
5 # based on previous apache status work by Dennis D. Spreen (dennis at spreendigital.de)
6 # Based on check_apachestatus.pl v1.4 by
7 # De Bodt Lieven (Lieven.DeBodt at gmail.com)
8 # Karsten Behrens (karsten at behrens dot in)
9 # Geoff McQueen (geoff.mcqueen at hiivesystems dot com )
10 # Dave Steinberg (dave at redterror dot net)
11 # Licence : GNU GPL v3 - http://www.fsf.org/licenses/gpl.txt
12 #
13 # help : ./check_phpfpm_status.pl -h
14 #
15 # issues & updates: http://github.com/regilero/check_phpfpm_status
16 use strict;
17 use warnings;
18 use Getopt::Long;
19 use Time::HiRes qw(gettimeofday tv_interval);
20 use Digest::MD5 qw(md5 md5_hex);
21
22 # ---------------------------------------------------------------------------
23 package main;
24
25 # ensure all outputs are in UTF-8
26 binmode(STDOUT, ":utf8");
27
28 # Globals
29 my $Version='1.1';
30 my $Name=$0;
31
32 my $o_host = undef; # hostname
33 my $o_help= undef; # want some help ?
34 my $o_port= undef; # port
35 my $o_url = undef; # url to use, if not the default
36 my $o_user= undef; # user for auth
37 my $o_pass= ''; # password for auth
38 my $o_realm= ''; # password for auth
39 my $o_version= undef; # print version
40 my $o_warn_p_level= -1; # Min number of idle workers that will cause a warning
41 my $o_crit_p_level= -1; # Min number of idle workersthat will cause an error
42 my $o_warn_q_level= -1; # Number of Max Queue Reached that will cause a warning
43 my $o_crit_q_level= -1; # Number of Max Queue Reached that will cause an error
44 my $o_warn_m_level= -1; # Number of Max Processes Reached that will cause a warning
45 my $o_crit_m_level= -1; # Number of Max Processes Reached that will cause an error
46 my $o_timeout= 15; # Default 15s Timeout
47 my $o_warn_thresold=undef; # warning thresolds entry
48 my $o_crit_thresold=undef; # critical thresolds entry
49 my $o_debug= undef; # debug mode
50 my $o_fastcgi= undef; # direct fastcgi mode (without an http->fastcgi proxy)
51 my $o_servername= undef; # ServerName (host header in http request)
52 my $o_https= undef; # SSL (HTTPS) mode
53 my $o_verify_ssl= 0; # SSL verification, False by default
54 my $o_cacert_file= undef; # Path to cacert.pem file
55
56 my $TempPath = '/tmp/'; # temp path
57 my $MaxUptimeDif = 60*30; # Maximum uptime difference (seconds), default 30 minutes
58
59 my $phpfpm = 'PHP-FPM'; # Could be used to store version also
60
61 # functions
62 sub show_versioninfo { print "$Name version : $Version\n"; }
63
64 sub print_usage {
65 print "Usage: $Name -H <host ip> [-p <port>] [-s servername] [-t <timeout>] [-w <WARN_THRESOLD> -c <CRIT_THRESOLD>] [-V] [-d] [-f] [-u <url>] [-U user -P pass -r realm]\n";
66 }
67 sub nagios_exit {
68 my ( $nickname, $status, $message, $perfdata , $silent) = @_;
69 my %STATUSCODE = (
70 'OK' => 0
71 , 'WARNING' => 1
72 , 'CRITICAL' => 2
73 , 'UNKNOWN' => 3
74 , 'PENDING' => 4
75 );
76 if(!defined($silent)) {
77 my $output = undef;
78 $output .= sprintf('%1$s %2$s - %3$s', $nickname, $status, $message);
79 if ($perfdata) {
80 $output .= sprintf('|%1$s', $perfdata);
81 }
82 $output .= chr(10);
83 print $output;
84 }
85 exit $STATUSCODE{$status};
86 }
87
88 # Get the alarm signal
89 $SIG{'ALRM'} = sub {
90 nagios_exit($phpfpm,"CRITICAL","ERROR: Alarm signal (Nagios timeout)");
91 };
92
93 sub help {
94 print "PHP-FPM Monitor for Nagios version ",$Version,"\n";
95 print "GPL licence, (c)2012 Leroy Regis\n\n";
96 print_usage();
97 print <<EOT;
98 -h, --help
99 print this help message
100 -H, --hostname=HOST
101 name or IP address of host to check
102 -p, --port=PORT
103 Http port, or Fastcgi port when using --fastcgi
104 -u, --url=URL
105 Specific URL (only the path part of it in fact) to use, instead of the default "/fpm-status"
106 -s, --servername=SERVERNAME
107 ServerName, (host header of HTTP request) use it if you specified an IP in -H to match the good Virtualhost in your target
108 -f, --fastcgi
109 Connect directly to php-fpm via network or local socket, using fastcgi protocol instead of HTTP.
110 -U, --user=user
111 Username for basic auth
112 -P, --pass=PASS
113 Password for basic auth
114 -r, --realm=REALM
115 Realm for basic auth
116 -d, --debug
117 Debug mode (show http request response)
118 -t, --timeout=INTEGER
119 timeout in seconds (Default: $o_timeout)
120 -S, --ssl
121 Wether we should use HTTPS instead of HTTP. Note that you can give some extra parameters to this settings. Default value is 'TLSv1'
122 but you could use things like 'TLSv1_1' or 'TLSV1_2' (or even 'SSLv23:!SSLv2:!SSLv3' for old stuff).
123 -x, --verifyssl, --verifyhostname
124 verify certificate and hostname from ssl cert, default is 0 (no security), set it to 1 to really make SSL peer name and certificater checks.
125 'verifyhostname' is the old deprecated name of this option.
126 -X, --cacert
127 Full path to the cacert.pem certificate authority used to verify ssl certificates (use with --verifyssl).
128 if not given the cacert from Mozilla::CA cpan plugin will be used.
129 -w, --warn=MIN_AVAILABLE_PROCESSES,PROC_MAX_REACHED,QUEUE_MAX_REACHED
130 number of available workers, or max states reached that will cause a warning
131 -1 for no warning
132 -c, --critical=MIN_AVAILABLE_PROCESSES,PROC_MAX_REACHED,QUEUE_MAX_REACHED
133 number of available workers, or max states reached that will cause an error
134 -1 for no CRITICAL
135 -V, --version
136 prints version number
137
138 Note :
139 3 items can be managed on this check, this is why -w and -c parameters are using 3 values thresolds
140 - MIN_AVAILABLE_PROCESSES: Working with the number of available (Idle) and working process (Busy).
141 Generating WARNING and CRITICAL if you do not have enough Idle processes.
142 - PROC_MAX_REACHED: the fpm-status report will show us how many times the max processes were reached sinc start,
143 this script will record how many time this happended since last check, letting you fix thresolds for alerts
144 - QUEUE_MAX_REACHED: the php-fpm report will show us how many times the max queue was reached since start,
145 this script will record how many time this happended since last check, letting you fix thresolds for alerts
146
147 Examples:
148
149 This will lead to CRITICAL if you have 0 Idle process, or you have reached the max processes 2 times between last check,
150 or you have reached the max queue len 5 times. A Warning will be reached for 1 Idle process only:
151
152 check_phpfpm_status.pl -H 10.0.0.10 -u /foo/my-fpm-status -s mydomain.example.com -t 8 -w 1,-1,-1 -c 0,2,5
153
154 this will generate WARNING and CRITICAL alerts only on the number of times you have reached the max process:
155
156 check_phpfpm_status.pl -H 10.0.0.10 -u /foo/my-fpm-status -s mydomain.example.com -t 8 -w -1,10,-1 -c -1,20,-1
157
158 theses two equivalents will not generate any alert (if the php-fpm page is reachable) but could be used for graphics:
159
160 check_phpfpm_status.pl -H 10.0.0.10 -s mydomain.example.com -w -1,-1,-1 -c -1,-1,-1
161 check_phpfpm_status.pl -H 10.0.0.10 -s mydomain.example.com
162
163 And this one is a basic starting example :
164
165 check_phpfpm_status.pl -H 127.0.0.1 -s nagios.example.com -w 1,1,1 -c 0,2,2
166
167 All these examples used an HTTP proxy (like Nginx or Apache) in front of php-fpm. If php-fpm is listening on a tcp/ip socket
168 you can also make a direct request on this port (9000 by default) using the fastcgi protocol. You'll need the FastCGI client
169 tools enabled in Perl (check the README) and the command would use the -f or --fastcgi option (note that SSL or servername
170 options are useless in this mode).
171 This can be especially usefull if you use php-fpm in an isolated env, without the HTTP proxy support (like in a docker container):
172
173 check_phpfpm_status.pl -H 127.0.0.1 --fastcgi -p 9002 -w 1,1,1 -c 0,2,2
174
175 HTTPS/SSL:
176
177 Adding --ssl you can reach an https host:
178
179 check_phpfpm_status.pl -H 10.0.0.10 -s mydomain.example.com --ssl
180
181 Check --verify-ssl (false by defaut) --cacert and --sl for more options, like below
182 (note that certificate checks never wortked on my side, add -d for full debug and
183 tell me if it worked for you, you may need up to date CPAN adn openSSL libs)
184
185 check_phpfpm_status.pl -H 10.0.0.10 -s mydomain.example.com --ssl TLSv1_2 --verify-ssl 1 --cacert /etc/ssl/cacert.pem
186
187 EOT
188 }
189
190 sub check_options {
191 Getopt::Long::Configure ("bundling");
192 GetOptions(
193 'h' => \$o_help, 'help' => \$o_help,
194 'd' => \$o_debug, 'debug' => \$o_debug,
195 'f' => \$o_fastcgi, 'fastcgi' => \$o_fastcgi,
196 'H:s' => \$o_host, 'hostname:s' => \$o_host,
197 's:s' => \$o_servername, 'servername:s' => \$o_servername,
198 'S:s' => \$o_https, 'ssl:s' => \$o_https,
199 'u:s' => \$o_url, 'url:s' => \$o_url,
200 'U:s' => \$o_user, 'user:s' => \$o_user,
201 'P:s' => \$o_pass, 'pass:s' => \$o_pass,
202 'r:s' => \$o_realm, 'realm:s' => \$o_realm,
203 'p:i' => \$o_port, 'port:i' => \$o_port,
204 'V' => \$o_version, 'version' => \$o_version,
205 'w=s' => \$o_warn_thresold, 'warn=s' => \$o_warn_thresold,
206 'c=s' => \$o_crit_thresold, 'critical=s' => \$o_crit_thresold,
207 't:i' => \$o_timeout, 'timeout:i' => \$o_timeout,
208 'x:i' => \$o_verify_ssl, 'verifyhostname:i' => \$o_verify_ssl,
209 'verifyssl:i' => \$o_verify_ssl,
210 'X:s' => \$o_cacert_file, 'cacert:s' => \$o_cacert_file,
211 );
212
213 if (defined ($o_help)) {
214 help();
215 nagios_exit($phpfpm,"UNKNOWN","leaving","",1);
216 }
217 if (defined($o_version)) {
218 show_versioninfo();
219 nagios_exit($phpfpm,"UNKNOWN","leaving","",1);
220 };
221
222 if (defined($o_warn_thresold)) {
223 ($o_warn_p_level,$o_warn_m_level,$o_warn_q_level) = split(',', $o_warn_thresold);
224 } else {
225 $o_warn_thresold = 'undefined'
226 }
227 if (defined($o_crit_thresold)) {
228 ($o_crit_p_level,$o_crit_m_level,$o_crit_q_level) = split(',', $o_crit_thresold);
229 } else {
230 $o_crit_thresold = 'undefined'
231 }
232 if (defined($o_fastcgi) && defined($o_https)) {
233 nagios_exit($phpfpm,"UNKNOWN","You cannot use both --fastcgi and --ssl options, we do not use http (nor https) when we use direct fastcgi access!");
234 }
235 if (defined($o_debug)) {
236 print("\nDebug thresolds: \nWarning: ($o_warn_thresold) => Min Idle: $o_warn_p_level Max Reached :$o_warn_m_level MaxQueue: $o_warn_q_level");
237 print("\nCritical ($o_crit_thresold) => : Min Idle: $o_crit_p_level Max Reached: $o_crit_m_level MaxQueue : $o_crit_q_level\n");
238 }
239 if ((defined($o_warn_p_level) && defined($o_crit_p_level)) &&
240 (($o_warn_p_level != -1) && ($o_crit_p_level != -1) && ($o_warn_p_level <= $o_crit_p_level)) ) {
241 nagios_exit($phpfpm,"UNKNOWN","Check warning and critical values for IdleProcesses (1st part of thresold), warning level must be > crit level!");
242 }
243 if ((defined($o_warn_m_level) && defined($o_crit_m_level)) &&
244 (($o_warn_m_level != -1) && ($o_crit_m_level != -1) && ($o_warn_m_level >= $o_crit_m_level)) ) {
245 nagios_exit($phpfpm,"UNKNOWN","Check warning and critical values for MaxProcesses (2nd part of thresold), warning level must be < crit level!");
246 }
247 if ((defined($o_warn_q_level) && defined($o_crit_q_level)) &&
248 (($o_warn_q_level != -1) && ($o_crit_q_level != -1) && ($o_warn_q_level >= $o_crit_q_level)) ) {
249 nagios_exit($phpfpm,"UNKNOWN","Check warning and critical values for MaxQueue (3rd part of thresold), warning level must be < crit level!");
250 }
251 # Check compulsory attributes
252 if (!defined($o_host)) {
253 print_usage();
254 nagios_exit($phpfpm,"UNKNOWN","-H host argument required");
255 }
256 }
257
258 ########## MAIN ##########
259
260 # warning capture: avoid extra line added on output by warnings (like deprecation warning in FastCGI code)
261 local $SIG{__WARN__} = sub {
262 if (defined ($o_debug)) {
263 my $warn = shift;
264 print "\nDEBUG: Perl warning message captured: $warn";
265 }
266 };
267
268 check_options();
269
270 my $override_ip = $o_host;
271 my $timing0 = [gettimeofday];
272 my $response = undef;
273 my $url = undef;
274
275 if (!defined($o_url)) {
276 $o_url='/fpm-status';
277 } else {
278 # ensure we have a '/' as first char
279 $o_url = '/'.$o_url unless $o_url =~ m(^/)
280 }
281
282 if (defined($o_fastcgi)) {
283 # -- FASTCGI
284 eval "use FCGI::Client::Connection;";
285 nagios_exit($phpfpm,"UNKNOWN","You need to activate FCGI::Client::Connection CPAN module for this feature: " . $@) if $@;
286 eval "use IO::Socket::INET";
287 nagios_exit($phpfpm,"UNKNOWN","You need to activate IO::Socket::INET CPAN module for this feature: " . $@) if $@;
288
289 if (!defined($o_port)) {
290 $o_port = 9000;
291 }
292 my $sock = IO::Socket::INET->new(
293 PeerAddr => $override_ip,
294 PeerPort => $o_port,
295 );
296 if (!$sock) {
297 nagios_exit($phpfpm,"CRITICAL", "Cannot connect to $override_ip : $o_port !");
298 }
299 my $fastcgiClient = FCGI::Client::Connection->new(sock => $sock);
300 $url = $o_url;
301 my $sname = undef;
302 if (defined($o_servername)) {
303 $sname= $o_servername;
304 } else {
305 $sname = $o_host;
306 }
307 my ( $stdout, $stderr ) = $fastcgiClient->request(
308 +{
309 GATEWAY_INTERFACE => 'FastCGI/1.0',
310 REQUEST_METHOD => 'GET',
311 QUERY_STRING => '',
312 SCRIPT_FILENAME => $url,
313 SCRIPT_NAME => $url,
314 },
315 ''
316 );
317 if (defined ($o_debug)) {
318 print "\nDEBUG: FASCGI requested url\n";
319 print $url;
320 print "\nDEBUG: FASCGI response: STDERR\n";
321 print $stderr;
322 }
323 $response = fcgi_response->new($stdout, $o_debug);
324 } else {
325 # -- HTTP
326 eval "use LWP::UserAgent;";
327 nagios_exit($phpfpm,"UNKNOWN","You need to activate LWP::UserAgent CPAN module for this feature: " . $@) if $@;
328 #use LWP::UserAgent;
329
330 my $proto='http://';
331 if(defined($o_https)) {
332 if ($o_https eq "") {
333 $o_https = 'TLSv1';
334 }
335 $proto='https://';
336 if (defined($o_port) && $o_port!=443) {
337 if (defined ($o_debug)) {
338 print "\nDEBUG: Notice: port is defined at $o_port and not 443, check you really want that in SSL mode! \n";
339 }
340 }
341 }
342
343 if (defined($o_servername)) {
344 if (!defined($o_port)) {
345 $url = $proto . $o_servername . $o_url;
346 } else {
347 $url = $proto . $o_servername . ':' . $o_port . $o_url;
348 }
349 } else {
350 if (!defined($o_port)) {
351 $url = $proto . $o_host . $o_url;
352 } else {
353 $url = $proto . $o_host . ':' . $o_port . $o_url;
354 }
355 }
356
357 if (defined ($o_debug)) {
358 print "\nDEBUG: HTTP url: \n";
359 print $url;
360 }
361
362 my %lwp_opts = (
363 timeout => $o_timeout
364 );
365
366 if(defined($o_https)) {
367
368 use IO::Socket::SSL qw( SSL_VERIFY_NONE SSL_VERIFY_PEER );
369 if (defined ($o_debug)) {
370 $ENV{HTTPS_DEBUG} = 1;
371 use Data::Dumper;
372 eval "use IO::Socket::SSL qw( debug3 SSL_VERIFY_NONE SSL_VERIFY_PEER )"; die $@ if $@;
373 } else {
374 $ENV{HTTPS_DEBUG} = 0;
375 }
376
377 $lwp_opts{'protocols_allowed'} = ['https'];
378
379 my %ssl_opts = (
380 PeerAddr => $override_ip,
381 );
382
383 $ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = $o_verify_ssl;
384 $ssl_opts{"verify_hostname"} = $o_verify_ssl;
385 $ssl_opts{"SSL_verifycn_name"} = $o_verify_ssl;
386 # 'TLSv1' by default, but could be things like 'SSLv3' or 'TLSv1_2', etc.
387 $ssl_opts{"SSL_version"} = $o_https;
388 #$ssl_opts{"SSL_verifycn_scheme"} = 'www';
389
390 if (defined($o_servername)) {
391 $ssl_opts{"SSL_hostname"} = $o_servername;
392 }
393 if (not $o_verify_ssl) {
394 # seems the verify_hostname parameters is not enough
395 $ssl_opts{"SSL_verify_mode"} = SSL_VERIFY_NONE;
396 } else {
397
398 if (!defined($o_cacert_file)) {
399 eval "use Mozilla::CA;";
400 nagios_exit($phpfpm,"UNKNOWN","You need to activate Mozilla::CA CPAN module for this feature, or use --cacert option: " . $@) if $@;
401 $o_cacert_file = Mozilla::CA::SSL_ca_file();
402 }
403 #$ssl_opts{"SSL_ca_path"} = '/usr/share/ca-certificates/mozilla/';
404 #$ENV{'HTTPS_CA_DIR'} = '/usr/share/ca-certificates/mozilla/';
405 #$ENV{'PERL_LWP_SSL_CA_PATH'} = '/usr/share/ca-certificates/mozilla/';
406 $ENV{'HTTPS_CA_FILE'} = $o_cacert_file;
407 $ENV{'PERL_LWP_SSL_CA_FILE'} = $o_cacert_file;
408 $ssl_opts{"SSL_ca_file"} = $o_cacert_file;
409 $ssl_opts{"SSL_verify_mode"} = SSL_VERIFY_PEER;
410 }
411 IO::Socket::SSL::set_ctx_defaults(%ssl_opts);
412
413 if (LWP::UserAgent->VERSION >= 6.10) {
414 $lwp_opts{"ssl_opts"} = \%ssl_opts;
415 }
416 } else {
417 $lwp_opts{'protocols_allowed'} = ['http'];
418 }
419
420 if (defined ($o_debug)) {
421 print Dumper \%lwp_opts;
422 }
423 my $ua = LWP::UserAgent->new(%lwp_opts);
424
425 # we need to enforce the HTTP request is made to the Nagios Host IP and
426 # not on the DNS related IP for that domain
427 @LWP::Protocol::http::EXTRA_SOCK_OPTS = ( PeerAddr => $override_ip );
428
429 # this prevent 'used only once' warning in -w mode
430 my $ua_settings = @LWP::Protocol::http::EXTRA_SOCK_OPTS;
431
432 my $req = HTTP::Request->new( GET => $url );
433
434 if (defined($o_servername)) {
435 $req->header('Host' => $o_servername);
436 }
437 if (defined($o_user)) {
438 $req->authorization_basic($o_user, $o_pass);
439 }
440
441 if (defined ($o_debug)) {
442 print "\nDEBUG: HTTP request: \n";
443 print "IP used (better if it's an IP):" . $override_ip . "\n";
444 print $req->as_string;
445 }
446
447 $response = $ua->request($req);
448 if (defined ($o_debug)) {
449 print "\nDEBUG: HTTP response: \n";
450 print $response->as_string;
451 }
452 }
453
454 my $timeelapsed = tv_interval($timing0, [gettimeofday]);
455
456 my $InfoData = '';
457 my $PerfData = '';
458
459 my $webcontent = undef;
460 if ($response->is_success) {
461
462 $webcontent=$response->decoded_content( charset_strict=>1, raise_error => 1, alt_charset => 'none' );
463 if (defined ($o_debug)) {
464 print "\nDEBUG: HTTP response:";
465 print $response->status_line;
466 print "\nContent-Type => ".$response->header('Content-Type');
467 print "\n";
468 print $webcontent;
469 }
470 if ($response->header('Content-Type') =~ m/text\/html/) {
471 nagios_exit($phpfpm,"CRITICAL", "We have a response page for our request, but it's an HTML page, quite certainly not the status report of php-fpm");
472 }
473 # example of response content expected:
474 #pool: foobar
475 #process manager: dynamic
476 #start time: 31/Jan/2012:08:18:45 +0000
477 #start since: 845
478 #accepted conn: 7
479 #listen queue: 0
480 #max listen queue: 0
481 #listen queue len: 0
482 #idle processes: 2
483 #active processes: 2
484 #total processes: 4
485 #max active processes: 2
486 #max children reached: 0
487
488 my $Pool = '';
489 if($webcontent =~ m/pool: (.*?)\n/) {
490 $Pool = $1;
491 $Pool =~ s/^\s+|\s+$//g;
492 #$phpfpm .= "-".$Pool;
493 }
494
495 my $Uptime = 0;
496 if($webcontent =~ m/start since: (.*?)\n/) {
497 $Uptime = $1;
498 $Uptime =~ s/^\s+|\s+$//g;
499 }
500
501 my $AcceptedConn = 0;
502 if($webcontent =~ m/accepted conn: (.*?)\n/) {
503 $AcceptedConn = $1;
504 $AcceptedConn =~ s/^\s+|\s+$//g;
505 }
506
507 my $ActiveProcesses= 0;
508 if($webcontent =~ m/(.*)?\nactive processes: (.*?)\n/) {
509 $ActiveProcesses = $2;
510 $ActiveProcesses =~ s/^\s+|\s+$//g;
511 }
512
513 my $TotalProcesses= 0;
514 if($webcontent =~ m/total processes: (.*?)\n/) {
515 $TotalProcesses = $1;
516 $TotalProcesses =~ s/^\s+|\s+$//g;
517 }
518
519 my $IdleProcesses= 0;
520 if($webcontent =~ m/idle processes: (.*?)\n/) {
521 $IdleProcesses = $1;
522 $IdleProcesses =~ s/^\s+|\s+$//g;
523 }
524
525 my $MaxActiveProcesses= 0;
526 if($webcontent =~ m/max active processes: (.*?)\n/) {
527 $MaxActiveProcesses = $1;
528 $MaxActiveProcesses =~ s/^\s+|\s+$//g;
529 }
530
531 my $MaxChildrenReached= 0;
532 if($webcontent =~ m/max children reached: (.*?)\n/) {
533 $MaxChildrenReached = $1;
534 $MaxChildrenReached =~ s/^\s+|\s+$//g;
535 }
536
537 my $ListenQueue= 0;
538 if($webcontent =~ m/\nlisten queue: (.*?)\n/) {
539 $ListenQueue = $1;
540 $ListenQueue =~ s/^\s+|\s+$//g;
541 }
542
543 my $ListenQueueLen= 0;
544 if($webcontent =~ m/listen queue len: (.*?)\n/) {
545 $ListenQueueLen = $1;
546 $ListenQueueLen =~ s/^\s+|\s+$//g;
547 }
548
549 my $MaxListenQueue= 0;
550 if($webcontent =~ m/max listen queue: (.*?)\n/) {
551 $MaxListenQueue = $1;
552 $MaxListenQueue =~ s/^\s+|\s+$//g;
553 }
554 # Debug
555 if (defined ($o_debug)) {
556 print ("\nDEBUG Parse results => Pool:" . $Pool . "\nAcceptedConn:" . $AcceptedConn . "\nActiveProcesses:" . $ActiveProcesses . " TotalProcesses :".$TotalProcesses . " IdleProcesses :" .$IdleProcesses . "\nMaxActiveProcesses :" . $MaxActiveProcesses . " MaxChildrenReached :" . $MaxChildrenReached . "\nListenQueue :" . $ListenQueue . " ListenQueueLen : " .$ListenQueueLen . " MaxListenQueue: " . $MaxListenQueue ."\n");
557 }
558
559 my $TempFile = $TempPath.$o_host.'_check_phpfpm_status'.md5_hex($url);
560 my $FH;
561
562 my $LastUptime = 0;
563 my $LastAcceptedConn = 0;
564 my $LastMaxChildrenReached = 0;
565 my $LastMaxListenQueue = 0;
566 if ((-e $TempFile) && (-r $TempFile) && (-w $TempFile))
567 {
568 open ($FH, '<',$TempFile) or nagios_exit($phpfpm,"UNKNOWN","unable to read temporary data from :".$TempFile);
569 $LastUptime = <$FH>;
570 $LastAcceptedConn = <$FH>;
571 $LastMaxChildrenReached = <$FH>;
572 $LastMaxListenQueue = <$FH>;
573 close ($FH);
574 if (defined ($o_debug)) {
575 print ("\nDebug: data from temporary file:\n");
576 print ("LastUptime: $LastUptime LastAcceptedConn: $LastAcceptedConn LastMaxChildrenReached: $LastMaxChildrenReached LastMaxListenQueue: $LastMaxListenQueue \n");
577 }
578 }
579
580 open ($FH, '>'.$TempFile) or nagios_exit($phpfpm,"UNKNOWN","unable to write temporary data in :".$TempFile);
581 print $FH "$Uptime\n";
582 print $FH "$AcceptedConn\n";
583 print $FH "$MaxChildrenReached\n";
584 print $FH "$MaxListenQueue\n";
585 close ($FH);
586
587 my $ReqPerSec = 0;
588 my $Accesses = 0;
589 my $MaxChildrenReachedNew = 0;
590 my $MaxListenQueueNew = 0;
591 # check only if this counter may have been incremented
592 # but not if it may have been too much incremented
593 # and something should have happened in the server
594 if ( ($Uptime>$LastUptime)
595 && ($Uptime-$LastUptime<$MaxUptimeDif)
596 && ($AcceptedConn>=$LastAcceptedConn)
597 && ($MaxListenQueue>=$LastMaxListenQueue)
598 && ($MaxChildrenReached>=$LastMaxChildrenReached)) {
599 $ReqPerSec = ($AcceptedConn-$LastAcceptedConn)/($Uptime-$LastUptime);
600 $Accesses = ($AcceptedConn-$LastAcceptedConn);
601 $MaxChildrenReachedNew = ($MaxChildrenReached-$LastMaxChildrenReached);
602 $MaxListenQueueNew = ($MaxListenQueue-$LastMaxListenQueue);
603 }
604
605 $InfoData = sprintf ("%s, %.3f sec. response time, Busy/Idle %d/%d,"
606 ." (max: %d, reached: %d), ReqPerSec %.1f, "
607 ."Queue %d (len: %d, reached: %d)"
608 ,$Pool,$timeelapsed, $ActiveProcesses, $IdleProcesses
609 ,$MaxActiveProcesses,$MaxChildrenReachedNew
610 ,$ReqPerSec,$ListenQueue,$ListenQueueLen,$MaxListenQueueNew);
611
612 $PerfData = sprintf ("Idle=%d Busy=%d MaxProcesses=%d MaxProcessesReach=%d "
613 ."Queue=%d MaxQueueReach=%d QueueLen=%d ReqPerSec=%f"
614 ,($IdleProcesses),($ActiveProcesses),($MaxActiveProcesses)
615 ,($MaxChildrenReachedNew),($ListenQueue),($MaxListenQueueNew)
616 ,($ListenQueueLen),$ReqPerSec);
617 # first all critical exists by priority
618 if (defined($o_crit_q_level) && (-1!=$o_crit_q_level) && ($MaxListenQueueNew >= $o_crit_q_level)) {
619 nagios_exit($phpfpm,"CRITICAL", "Max queue reached is critically high " . $InfoData,$PerfData);
620 }
621 if (defined($o_crit_m_level) && (-1!=$o_crit_m_level) && ($MaxChildrenReachedNew >= $o_crit_m_level)) {
622 nagios_exit($phpfpm,"CRITICAL", "Max processes reached is critically high " . $InfoData,$PerfData);
623 }
624 if (defined($o_crit_p_level) && (-1!=$o_crit_p_level) && ($IdleProcesses <= $o_crit_p_level)) {
625 nagios_exit($phpfpm,"CRITICAL", "Idle workers are critically low " . $InfoData,$PerfData);
626 }
627 # Then WARNING exits by priority
628 if (defined($o_warn_q_level) && (-1!=$o_warn_q_level) && ($MaxListenQueueNew >= $o_warn_q_level)) {
629 nagios_exit($phpfpm,"WARNING", "Max queue reached is high " . $InfoData,$PerfData);
630 }
631 if (defined($o_warn_m_level) && (-1!=$o_warn_m_level) && ($MaxChildrenReachedNew >= $o_warn_m_level)) {
632 nagios_exit($phpfpm,"WARNING", "Max processes reached is high " . $InfoData,$PerfData);
633 }
634 if (defined($o_warn_p_level) && (-1!=$o_warn_p_level) && ($IdleProcesses <= $o_warn_p_level)) {
635 nagios_exit($phpfpm,"WARNING", "Idle workers are low " . $InfoData,$PerfData);
636 }
637
638 nagios_exit($phpfpm,"OK",$InfoData,$PerfData);
639
640 } else {
641 nagios_exit($phpfpm,"CRITICAL", $response->status_line);
642 }
643
644 # ---------------------------------------------------------------------------
645 # Adding a small parser for response coming in fastcgi mode
646 # to have some methods with same signature as the response from LWP::UserAgent
647 package fcgi_response;
648
649 sub new() {
650 my ($class) = shift;
651 my ($raw) = shift;
652 my ($debug) = shift;
653
654 my @parts = split /\r\n\r\n/, $raw;
655 my @headers = split /\r\n/, $parts[0];
656 my $body = $parts[1];
657
658 #if (defined ($debug)) {
659 # print "\nDEBUG FCGI Resp HEADERS:\n";
660 # print join("\r\n",@headers);
661 # print "\nDEBUG FCGI Resp BODY:\n";
662 # print $body;
663 #}
664
665 my $self = {
666 "raw" => $raw,
667 "headrs" => [@headers],
668 "body" => $body,
669 "debug" => $debug,
670 };
671
672 bless($self, $class);
673
674 return $self;
675 }
676
677 sub is_success() {
678 my ($self) = shift;
679 return not $self->status_line()
680 }
681 sub status_line() {
682 my ($self) = shift;
683 return $self->header('Status');
684 }
685 sub decoded_content() {
686 my ($self) = shift;
687 # we do not, in fact, apply any decoding
688 return $self->{body}
689 }
690 sub header() {
691 my ($self) = shift;
692 my ($seek) = shift;
693
694 for my $i (0 .. $#{$self->{headrs}}) {
695 my $line = $self->{headrs}[$i];
696 my @parts = split /:/, $line;
697 if (lc $parts[0] eq lc $seek) {
698 if (defined($self->{debug})) {
699 print "\nDEBUG: header $seek found => " . $parts[1];
700 }
701 return $parts[1];
702 }
703 }
704 return 0;
705 }

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.8