Sometime last week Apache on one of the

servers that manages some websites I host stop responding to

requests, resulting in said websites being unavailable for a day and

half (or so). Unfortunately I didn’t know about the problem until

someone else notified me of the issue. Opps. Not good system

administration that.

There are plenty of solutions for

monitoring network services, but given that I’m just running Apache

for a half dozen non-critical websites on the side, there’s no reason

to go overboard. Any sysadmin worth their weight in salt should be able

to whip something up with Perl in no time.

So, what’s needed? Well, something that will remotely monitor the

pool of websites and notify me if something is amiss:

First up, making a simple HTTP GET request:

my $url = "http://$host"; my $ua = LWP::UserAgent->new; my $response = $ua->get( $url );

Now we test the response, was it successful? If so, Apache returns an appropriate status code and the requested resource. If Apache is available, but unable to properly process the request it will responded with some relevant status code, which we wish to pass on for further troubleshooting:

if ( !$response->is_success ) { # Do we have an error code? if ( $response->code ) { reportError("$host reports $response->message

"); } else {

However a failed GET request will result in no status code since Apache probably failed to respond at all. In this case it would be helpful to determine if the issue is with Apache or something else. For that test a network ping is issued:

# HTTP is down, is the network connection down too? my $p = Net::Ping->new("icmp"); if ( $p->ping( $host, 2 )) { reportError ("$host is responding, but Apache is not.

"); } else { reportError ("$host is unreachable.

"); } }

Not too difficult that. Now, how do we go about communicating the issue at hand? SMS has always been my preferred method since my phone is usually close at hand and, iPhone or not, SMS is widely implemented and easy to use.

# Send SMS via cellular Email to SMS gateway my ( $msg ) = @_; my $to = "7735551234\@txt.att.net"; my $from = "pdw\@weinstein.org"; my $subject = "Service Notification"; my $sendmail = '/usr/lib/sendmail'; open( MAIL, "|$sendmail -oi -t" ); print MAIL "From: $from

"; print MAIL "To: $to

"; print MAIL "Subject: $subject



"; print MAIL $msg; close( MAIL );

All’s done? Not quite. For the fun of it, I figured broadcasting a message that the server was unavailable might be of use to regular visitors. What better way to broadcast a short message than via Twitter?

my ( $msg ) = @_; my $nt = Net::Twitter::Lite->new( username => $username, password => $password ); my $result = eval { $nt->update( $msg ) };

Bring this all together, with cron gives us:

# monitor remote httpd servers every 30 minutes */30 * * * * pdw /home/pdw/bin/monitor.pl >/dev/null 2>&1