Re: Internet is up verification

Top Page
Attachments:
Message as email
+ (text/plain)
+ (application/pgp-signature)
+ (text/plain)
Delete this message
Reply to this message
Author: Darrin Chandler
Date:  
To: alandd, Main PLUG discussion list
Subject: Re: Internet is up verification
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 <>

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

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


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

---------------------------------------------------
PLUG-discuss mailing list -
To subscribe, unsubscribe, or to change you mail settings:
http://lists.PLUG.phoenix.az.us/mailman/listinfo/plug-discuss