Internet is up verification

Darrin Chandler dwchandler at stilyagin.com
Thu Oct 12 17:39:04 MST 2006


On Thu, Oct 12, 2006 at 05:02:46PM -0700, Alan Dayley wrote:
> Why do you need to know within every couple of seconds?  I'll be most high
> volume sites would not notice a ping every minute or 30 seconds or even 10
> seconds but the more often you did it, the more likely someone will not
> like it.
> 
> If your requirement really is to know that it is down within a couple of
> seconds, maybe paying for a monitoring service can be cost justified.
> 
> Just random thoughts from the sidelines...

Actually, my current employer provides that service. We're primarily an
alarm monitoring company, but we've just arranged with a company to
monitor their network (i.e., we get an "alarm" and call people until
someone answers or calls back). That way they don't have to staff
27/7/365 but can still be responsive. We have a tiny hardware module,
but also a software-only solution.

Also, if anyone is interested I wrote a little ping script in Perl...


----------| cut |----------
#!/usr/bin/perl -w
#
# Copyright (c) 2006 Darrin Chandler
# All rights reserved.
#
# The pingmon-perl script is written in Perl v5.8 and released
# under the BSD 2.0 new license, which can be found at:
#
#   http://www.opensource.org/licenses/bsd-license.php
#

use Pod::Usage;
use Getopt::Long;
use Net::Ping;

my $time = 15;
my $count = 4;

Getopt::Long::Configure(
  qw(bundling no_auto_abbrev no_ignore_case));

GetOptions(
  'verbose|v'	=> \$verbose,
  'help|?'	=> \$help,
  'host|h=s'	=> \$host,
  'email|e=s'	=> \$email,
  'time|t=i'	=> \$time,
  'count|c=i'	=> \$count
) or print_usage();

# Check options
print_usage() if defined $help;
print_usage() if !(defined $host and defined $email);

# Catch some sigs
$SIG{HUP} = \&exithandler;
$SIG{TERM} = \&exithandler;
$SIG{INT} = \&exithandler;

# Init for main loop
my $pings = 0;
my $up = 1;
my $p = Net::Ping->new("icmp");

#
# Main Loop
#
while (1) {
    # Here's the ping
    ($status, $duration, $ip) = $p->ping($host);

    # Reset to 0 if changed $status, then
    # Inc $pings on success, Dec on failure.
    if ($status) {
	$pings = 0 if $pings < 0;
	$pings += 1;
    } else {
	$pings = 0 if $pings > 0;
	$pings -= 1;
    }

    # Get specific conditionfor reporting
    if (!defined $status) {
	$statstr = qq[Failed to resolve $host];
    } elsif ($status) {
	$statstr = qq[$host [$ip] ping response $duration secs];
    } else {
	$statstr = qq[$host [$ip] ping timeout!];
    }

    # Status message for verbose mode
    print qq[$statstr\n] if $verbose;

    # If status changed and enough tries then email
    if (($status xor $up) and (abs($pings) >= $count)) {
	# Status Changing
	$up = !$up;
	$upstr = $up ? q[UP] : q[DOWN];
	# Send Status Email
	$subject = qq[$host is $upstr];
	$msgbody = qq[$host $upstr!\nLast: $statstr];
	sendmail();
    }
    sleep($time);
}
$p->close();

exit(0);

sub print_usage {
    pod2usage(
	-verbose => 0,
	-exitval => 0
	);
}

sub sendmail {
    # Build message headers/body
    (my $whole = <<"EOF") =~ s/^\s+//gm;
	To: $email
	Subject: $subject

	$msgbody
EOF
    print qq[Sending re: $subject\n] if $verbose;

    # Send message with sendmail
    open(SENDMAIL, q[|/usr/sbin/sendmail -oi -t]) or die qq[Can't fork for sendmail: $!\n];
    print SENDMAIL $whole;
    close(SENDMAIL) or warn q[sendmail didn't close nicely];
}

sub exithandler {
    $signame = shift;
    $subject = qq[pingmon-perl $host terminating];
    $msgbody = qq[Exiting on SIG$signame];
    sendmail();
    exit(0);
}

# ---------------------------------------------------------------------------

=head1 NAME

pingmon-perl - Ping Monitor in Perl

=head1 SYNOPSIS

B<pingmon-perl> -h I<host> -e I<email> [options]

Options:

 -e, --email=email      Specify email address to notify
 -h, --host=hostname    Specify hostname or IP address

 -?, --help             Print usage message
 -c, --count=n          Consecutive successes/failures before
                        reporting (default 4)
 -t, --time=n           Seconds between Pings (default 15)
 -v, --verbose          Print status messages

=head1 DESCRIPTION

pingmon-perl monitors a system by performing icmp echo
requests, a la ping(8). If the ping fails for I<count>
consecutive attempts then a message is sent to I<email>.
If the system later responds to I<count> pings then
another message is sent. Finally, if pingmon-perl
catches SIGINT, SIGTERM, or SIGHUP it will send another
informative message and then exit.

=head1 CAVEATS

pingmon-perl must be run as or setuid root since it needs to
perform icmp echo requests. Other methods are available,
depending on circumstances. Change the "icmp" in
Net::Ping->new("icmp") to one of "tcp" or "udp" if the
target system has that port open and responsive. Change
to "external" if you have module Net::Ping::External.

Sending email and other complex operation upon catching a
signal should be safe in Perl these days. If pingmon-perl
core dumps on catching a signal then it's not as safe as
it is supposed to be. (No, it's never done it to me)

=head1 BUGS

There should be an option to detach/daemonize.

=head1 AUTHOR

Darrin Chandler <darrin at stilyagin.com>

=cut
--------| cut |--------

-- 
Darrin Chandler            |  Phoenix BSD Users Group
dwchandler at stilyagin.com   |  http://bsd.phoenix.az.us/
http://www.stilyagin.com/  |

-- 
Darrin Chandler            |  Phoenix BSD Users Group
dwchandler at stilyagin.com   |  http://bsd.phoenix.az.us/
http://www.stilyagin.com/  |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.PLUG.phoenix.az.us/pipermail/plug-discuss/attachments/20061012/b686124d/attachment.pgp 


More information about the PLUG-discuss mailing list