Friday, March 21, 2008

Checking Whether Your Web Server Is Up Using Perl Sockets Programming

Hello again,

Today's entry harkens back to a post we did a while ago regarding checking your network status using CGI. Although the Perl script we're going to run through today is somewhat similar, there are more than a few notable differences.

This Perl script should be able to be run on pretty much any flavor of Linux or Unix that supports Perl and simple Berkeley Sockets. It's also meant to be run out of cron, so that you can keep Web Server error reports (or, hopefully, a lack thereof) coming on a dependable basis. This script doesn't rely on anything in the *nix "environment" that should make it fail, so a simple entry in your crontab, like:

0,30 * * * * /wherever/you/keep/this/wsMonitor.pl

should check your Web Server every 30 minutes.

Another way you can do this (which is explored in more detail in our previous post on alternatives to using the nohup command) is to run the command (either from an init script or straight from the command line) in a backgrounded subshell, with slight wrapper script around the code, like so:

---> Sample Wrapper Shell Code <---

#!/bin/sh

while :
do
/wherever/you/keep/this/wsMonitor.pl
sleep 1800
done

---> End Sample Wrapper Shell Code <---

and then kick it off with a command line similar to this (again, either from an init script or directly from your shell prompt):

host # (/full/path/to/your/wrapper_script.sh &)

Okay, now back to the Perl script itself ;) You'll note that it works very simply by sending a string (whatever you want it to be - Maybe something meaningful, like "This is just us testing," to make it easy to keep out of your Web Server access reporting) to your Web Server and sending out an email if the Web Server doesn't respond. Note that this Perl script doesn't care what kind of response it gets, since it's not sending a valid HTTP request; it only checks to make sure that the Web Server is receiving the same amount of characters we send it in our test string. It will also send a slightly different mail message if it can't open the port at all.

I've commented on each line for all the stuff you might need (or want) to modify. Hopefully this script finds you, and your Web Server, well :)

Best wishes,


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

#!/usr/bin/perl

# wsMonitor.pl - Make Sure Our Web Server Is Answering On Port 80
#
# 2008 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#

use Socket;
require 5.002;

$mailer = "/usr/lib/sendmail"; # Your path to your local mail program
$remote = "webserver.xyz.com"; # Whatever host you want to check
$port = 80; # You can also check any other port, since we aren't looking for a particular response
if ($port =~ /\D/) { $port = getservbyname($port, 'tcp') }
&mail_out unless $port;
$iaddr = inet_aton($remote);
$paddr = sockaddr_in($port, $iaddr);
$proto = getprotobyname('tcp');
socket(BINGER, PF_INET, SOCK_STREAM, $proto) or &fail_mail;
connect(BINGER, $paddr) or &fail_mail;
$hey = send(BINGER, "TESTING TESTING 1 2 3", 21) or &fail_mail; # Note: Change the number after your message to the amount of characters being sent in between the quotes preceding it.
# In this case "TESTING TESTING 1 2 3" comes out to 21 characters, including the whitespace
exit;

sub fail_mail {

open (MAIL, "| $mailer -t") || die "Can't Open $mailer: $!\n";
print MAIL "To: interested_party\@xyz.com\n";
print MAIL "From: socketWatch\@monitorhost\n";
print MAIL "Subject: Possible problem with $remote!!!\n";
print MAIL "------------------------\n";
print MAIL "$remote incomplete Socket transmission:\n";
print MAIL "Returned $hey from 21...\n"; # Note that this 21 is the same as the 21 referenced in the socket send command above
close (MAIL);
exit;
}

sub mail_out {

open (MAIL, "| $mailer -t") || die "Can't Open $mailer: $!\n";
print MAIL "To: interested_parties\@pager.xyz.com\n";
print MAIL "From: socketWatch\@$remote\n";
print MAIL "Subject: Possible problem with $remote!!!\n";
print MAIL "------------------------\n";
print MAIL "$remote may be down: $!\n";
close (MAIL);
exit;
}


, Mike