hostcheck.pl

If you've made a patch to quick fix a bug or to add a new feature not yet in the main tree then post it here so others can try it out.
Post Reply
User avatar
rdmelin
Posts: 863
Joined: Wed Oct 29, 2003 2:23 pm
Location: Ellensburg, WA USA

hostcheck.pl

Post by rdmelin »

If you have use for a program that will notify you if your website / ZM machine / network camera goes offline, this may fill the need. It is designed to be run by cron, and can email a notice via your SMTP gateway.

A crontab entry like this will run it every 5 minutes:
*/5 * * * * $HOME/bin/hostcheck.pl -e

You will need to edit the config section for your monitored hosts, mail server, email address, etc.

I have not tested it with SMS text messaging, but I believe (hope) it will work.

Code: Select all

#!/usr/bin/perl -wT
# hostcheck.pl
# Web host availability monitor
#
# Copyright (C) 2004  Ross Melin <rdmelin@yahoo.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#

use strict;
use Net::Ping;
use Net::SMTP;
use Getopt::Std;

#           ************  Config section  ***********
#
# List some test hosts on the Internet or your network to see if this host
# is connected.
my @test_hosts = qw(
www.yahoo.com
www.google.com
www.cnn.com
www.microsoft.com
www.aol.com
);

# List the host(s) you want to monitor
my @monitored_hosts = qw(
www.zoneminder.com
bogus.fake.con
192.168.2.11
);

# SMTP mailhost goes here
my $mailhost = "mail.someISP.com";

# From email address goes here. You MUST use single quotes.
my $from_email = 'hostcheck@local.domain';

# To email address goes here. You MUST use single quotes.
my $to_email = 'myemail@someISP.com';

# Host status is tracked in a file defined here:
my $host_status_file = "/tmp/.hostcheck_status";
my $tmp_status_file = "/tmp/.hostcheck_status.tmp";

# Comment out this line to disable the help hint
print "Use \"hostcheck.pl -h\" for help\n";

#
#              ***********  End of config section  ************
# 

my $my_status = is_connected();
my $oldstatus;
my $newstatus;
my %option = ();
getopts("evh", \%option);

if ($option{e})
{
    print "Email mode enabled.\n";
}


if ($option{h})
{
	print "\n  hostcheck.pl will test one or more web hosts for reachablity.\n
First it will try a list of well known hosts to check that the network
is reachable. If not it will exit with a warning.\n
  Next it will check each host from a list you configure, and see if it's
status has changed since the previous test. It is designed to be run by
cron, so if no host has changed status since the last run there is no output.\n
  If you want the output logged, you can redirect output thus:
\"hostcheck.pl >>hostcheck.log\"\n
  If you use the -e switch it will email a message if any host changes
status. If you use this feature you must configure a valid smtp mailhost
or the program will exit with an error message.\n
  If you use the -v switch the current status of all monitored hosts
will be printed\n
  All required configuration is done by editting the config section of
the file.\n ";
	exit;
}

if ($my_status eq "offline")
{
	die "I seem to be offline $!\n";
}

foreach ( @monitored_hosts )
{
	$oldstatus = check_oldstatus();
	$newstatus = check_host();
	if ($newstatus ne $oldstatus)
	{
		update_status();
		if ($option{e})
		{
			email_update();
		}
		print "$_"," is now ", "$newstatus ",scalar(localtime()), "\n";
	}
	elsif ($option{v})
	{
		print "$_"," is still ", "$newstatus ",scalar(localtime()), "\n";
	}
};

sub check_host
{
	my $p = Net::Ping->new("tcp", 2);
	$p->{port_num} = getservbyname("http", "tcp");
	if ($p->ping($_, 2))
	{
		return "online";
	}
	undef($p);
	
	return "offline";	
}
	
sub is_connected
{
	my $p = Net::Ping->new("tcp", 2);
	$p->{port_num} = getservbyname("http", "tcp");
	foreach my $host (@test_hosts)
	{
		if ($p->ping($host, 2))
		{
			return "online";
		}
	}
	undef($p);
	return "offline";	
		
}


sub check_oldstatus
{
	$oldstatus = "unknown";
	open OLDSTATUS, "<$host_status_file"; # Don't die if not exists "
	while ( defined ( my $line = <OLDSTATUS> ))
	{
		if ($line =~ /$_/)
		{
			$oldstatus = "online" if $line =~ /online/;
			$oldstatus = "offline" if $line =~ /offline/;
		}
	};
	return $oldstatus
}

sub update_status
{
	open NEWSTATUS, ">$tmp_status_file"
		or die "Can't open tmp file for writing $!\n";
	open OLDSTATUS, "<$host_status_file";
	while (defined ( my $line = <OLDSTATUS>))
	{
		print NEWSTATUS $line unless $line =~ /$_/;
	}
	print NEWSTATUS "$_"," is ", "$newstatus ",scalar(localtime()), "\n";
	close OLDSTATUS;
	close NEWSTATUS;
	rename($tmp_status_file, $host_status_file)          or die "can't rename $tmp_status_file to $host_status_file: $!";
}

sub email_update
{
	my $smtp = Net::SMTP->new($mailhost);
	print $smtp->domain,"\n";
	
	$smtp->hello($from_email);
	$smtp->mail($to_email); # This line is needed but ?
	$smtp->to($to_email);
	$smtp->data();
	$smtp->datasend("From: $from_email\n");
	$smtp->datasend("To: $to_email\n");
	$smtp->datasend("Subject: $_ $newstatus\n");
	$smtp->datasend("\n");
	$smtp->datasend("$_"," is now ", "$newstatus ",scalar(localtime()), "\n");
	$smtp->dataend();

	print "Emailed message to $to_email\n";
}
unclerichy
Posts: 74
Joined: Wed Feb 25, 2004 5:06 pm

Post by unclerichy »

You may want to take a look at http://www.nagios.org for full-blown network monitoring. I use it to monitor my home network.
Post Reply