#!/usr/bin/perl # # monitor.pl - makes a series of checks to see that a machine, TCP network # layer, Apache, and a particular web page are available. It's designed # to be run on a separate host from the one being monitored. # # This script must run as root so that ICMP can be used as the protocol # for ping. Most machines don't respond to TCP and UDP echo services # (for a variety of reasons). # # remove hardcoded directory # pass host as arg to child # genericize naming # check for specific web page (in webdb's case this means that the database # is up and functional. # actually send email # pass interactive through cron entry # use Net::Ping; use IO::Socket; use strict; my $p; my $result; my $s; my $got_it = 0; my $output = ""; my $mode = ""; my $pid; my $program = "/clients/users/charliep/monitor-webdb-child.pl"; my @options = ""; my @args = ""; my $host = "dba.earlham.edu"; my $url = "webdb.earlham.edu"; my $check_text_webdb = "username:"; my $check_text_child = "success"; $mode = $ARGV[0]; $mode = "interactive"; # # Ping the host to see if it at least has a pulse. # if (!($p = Net::Ping->new("icmp"))) { $output .= "monitor-webdb: unable to create new ping object - $!\n"; goto done; } $result = $p->ping($host); $p->close(); if ($result) { $output .= "monitor-webdb: $host is alive\n"; } else { $output .= "monitor-webdb: $host is down\n"; goto done; } # # See if the network is responding at all. In its current failure # mode dba.earlham.edu will respond to pings but hang (forever) on the # new IO::Socket call. To avoid getting caught by this do the fork/exec # shuffle. # if (!(defined($pid = open(CHILD, "-|")))) { $output .= "monitor-webdb: unable to create pipe - $!\n"; goto done; } if ($pid) { # parent # check to see if the pipe has anything to read, if so read it, $result = ""; $got_it = 0; sleep(5); while () { $result = $_; if ($result =~ /success/g) { $got_it = 1; } } # # or timer or failure return # if ($got_it) { $output .= "monitor-webdb: $host is accepting TCP connections\n"; } else { $output .= "monitor-webdb: $host is _NOT_ accepting TCP connections\n"; goto done; } # set a timer and a counter, come back in n cycles # when the counter exceeds umm, kill the child (optional) and bail # update $output either way } else { # child exec($program, @options, @args) || die "monitor-webdb (child): unable to exec $program - $!\n"; } close(CHILD); # # Check if the Apache server is up and responding. # if (!($s = new IO::Socket::INET (PeerAddr => $host, PeerPort => '80', Proto => 'tcp', Type => SOCK_STREAM, Timeout => 5))) { $output .= "monitor-webdb: unable to create new socket object - $@\n"; goto done; } $result = ""; $got_it = 0; print $s "GET HTTP/1.0\r\n"; while (<$s>) { $result = $_; if ($result =~ /!DOCTYPE HTML PUBLIC/g) { $got_it = 1; } } close($s); if ($got_it) { $output .= "monitor-webdb: $host is responding to http GET requests\n"; } else { $output .= "monitor-webdb: $host is _NOT_ responding to http GET requests\n"; goto done; } # # See if the URL returns the WebDB login page. # # search for check_text_webdb (better variable name) # # Jump to here if any test fails, fall through to here if they all succeed. # done: if ($mode eq "interactive") { print "$output"; } else { print "sending email\n"; } exit;