Hi, I have a command set up in crontab as goes: 0,20,40 9-16 * * 1-5 ping -c2 111.111.111.111 >> file.log basically this pings one of our external network servers every 20 mins between 9am and 4pm.... it then outputs the ping to a text file for me to observe and ensure connectivity is in place, however I tend to forget about this and now want to set a command up to email me via sendmail when the ping command fails.... Is this possible? and can anybody show me how? Thanx Damian Buckley
The 03.10.13 at 15:54, Damian Buckley wrote:
about this and now want to set a command up to email me via sendmail when the ping command fails....
Is this possible? and can anybody show me how?
Yes, it is. You would have to use a better tool, like fping: |> Unlike ping , fping is meant to be used in scripts, so its output |> is designed to be easy to parse. nimrodel:~ # fping telperion nimrodel nimrodel is alive telperion is unreachable nimrodel:~ # You would have to run a script from cron. This script (running as root, mind) does the fping stuff (fping needs root privileges). Then you would parse the output: finding the string 'unreachable' could trigger the email sending; I would use mailx for that. You can increase the information: nimrodel:~ # fping -e telperion nimrodel nimrodel is alive (0.11 ms) telperion is unreachable nimrodel:~ # or include statistics: nimrodel:~ # fping -e -s telperion nimrodel nimrodel is alive (0.10 ms) telperion is unreachable 2 targets 1 alive 1 unreachable 0 unknown addresses 4 timeouts (waiting for response) 5 ICMP Echos sent 1 ICMP Echo Replies received 3 other ICMP received 0.10 ms (min round trip time) 0.10 ms (avg round trip time) 0.10 ms (max round trip time) 4.087 sec (elapsed real time) nimrodel:~ # -- Cheers, Carlos Robinson
The 03.10.13 at 15:54, Damian Buckley wrote:
want to set a command up to email me via sendmail when the ping command fails....
This is a bit of overkill for what you asked but I have a perl script to monitor a webserver. Set it up in crontab to run as often as you like, eg: 5 minutely. Without "-d" it should run silently. Put in another daily job to cat the logfile it generates. That will get mailed to the user who has the crontab. You need to be in the group "trusted" to have a crontab. First the script tries to ping it's DNS servers, (to test it's own network connection) then resolves the target host, then pings the target host then http GETs a small test file and compares it to the local copy. (you will need a similarly named copy of the file you are GETing) It logs the sucess (in lowercase) or failure (uppercase) of each step. Logfiles don't grow too big as it only adds a line if the success or failure of any step changes. Then it leaves a line in the log showing the time of the last old-state run. If nothing changes it just updates the timestamp of the last line. -- Michael James michael.james@csiro.au System Administrator voice: 02 6246 5040 CSIRO Bioinformatics Facility fax: 02 6246 5166 Script follows: #!/usr/bin/perl # timekeeper a script to monitor a webhost # # GPL by michael@james.st 2003-02-21 # Set some formal variables my $INDEX = 'index.html'; my $RESOLV_CONF = '/etc/resolv.conf'; my $PING = 'ping'; # Linux Ping my @PING_ARGS =('-c2', '-w2'); my @POST_ARGS = (); # SunOS Ping #my @PING_ARGS = ('-s'); #my @POST_ARGS = ('64', '2'); $ENV{'PATH'}='/bin:/usr/bin:/usr/sbin'; # That's most of what should need tuning use strict; use Socket; use Time::localtime; use File::Basename; use LWP::Simple; chdir dirname($0) or die "Couldn't cd to script directory\n"; my $user=`whoami`; chop($user); my($debug, @url_list, $url); # Get the target list of URLs, and any flags foreach (@ARGV) { s/^-d.*//i and $debug='on'; $_ or next; push(@url_list, $_); } @url_list or die "Usage: $0 <target url list>\n"; foreach $url (@url_list) { my $host = $url; my $file = $INDEX; unless ( $host =~ s%http://%%i or $host =~ s%ftp://%%i ) { print "Only ftp or http URLs allowed!\n"; next; } $host =~ s%/(.*)$%% and $file = $1; $debug and print "$0 running for $user\n\nTarget host:\t$host\n"; my $tm = localtime; my $date = sprintf "%4d-%02d-%02d", $tm->year+1900, $tm->mon+1, $tm->mday; my $time = sprintf "%02d:%02d", $tm->hour, $tm->min; my $timesheet = "$host"; my $temp = ".$host"; -r $timesheet or create($timesheet, $date, $time); -r $temp and die "$temp file found, another copy is running\n"; my $self = ping_a_nameserver(); my $dns = resolve(\$host); my $ping = test_ping($host) || 'PING'; my $get = http_get($url, $file); my $result = join("\t", $self, $dns, $ping, $get); $debug and print "Complete result:\t(", $result, " )\n\n\n"; open(IN, "< $timesheet") or die "can't read $timesheet\n"; open(OUT, "> $temp") or die "can't write $temp\n"; my $lastline = <IN>; while(<IN>) { print OUT $lastline; $lastline = $_; } # We have printed out all the log except the last line chop($lastline); # Split the datestamp off the results my ($lastdate, $lasttime, $lastresult) = split(/\s+/, $lastline, 3); $debug and print "Date\t=($date)\nLast\t=($lastdate $lasttime)\n", "Result\t=($result)\nLast\t=($lastresult)\n"; # If they're different or it's a new day, print out the old line if ( ($result ne $lastresult) or ($lastdate ne $date) ) { print OUT $lastline, "\n"; } print OUT join("\t", $date, $time, $result), "\n"; close(IN); close(OUT); rename($temp, $timesheet); } sub create { my($file, $date, $time) = @_; open(OUT, "> $file") or die "Can't create a new timesheet $file\n"; print OUT join("\t", 'Time of last check', 'Self', 'DNS', 'Ping', "Get\n\n$date", $time, " Started Running...\n"); close OUT; } sub ping_a_nameserver { open(IN, "$RESOLV_CONF") or die "Can't read $RESOLV_CONF\n"; while (<IN>) { chop; s/^nameserver\s+//i or next; $debug and print "Nameserver:\t[", $_, "]\n"; test_ping($_) or next; close(IN); return 'self'; } return 'SELF'; } sub resolve # expects a ref to a hostname # replaces it with the IP number # returns "dns" or "DNS" followed by the IP { my $ref = shift; $debug and print "Resolving:\t[", $$ref, "]\n"; if ( my $ip = inet_aton($$ref) ) { $$ref = inet_ntoa($ip); return 'dns'; } $debug and print "\t no answer\n"; return 'DNS'; } sub test_ping # expects a host by name or number # returns "ping" or "PING" # depending if the ping worked or NOT { my $host = shift; my($out, $in); $debug and print "Pinging:\t[$host]\n"; defined( my $pid = open(PING, "-|") ) or die "Can't fork: $!"; unless ( $pid ) # Child command that generates the output { exec($PING, @PING_ARGS, $host, @POST_ARGS); } else { while (<PING>) { $debug and print $_; ($out, $in) = /(\d+).*?transmitted.*?(\d+).*?received/ and last; } close(PING); } $debug and print "Final count Out: $out, In: $in\n"; $in > 0 and $in == $out and return 'ping'; $debug and print "\tNo ping\n"; return; } sub http_get { my($url, $file) = @_; my $content; $debug and print "Getting:\t$url\n"; defined( $content = get($url) ) or return 'GET'; $debug and print "Here's the file we got:\n\n\n", $content, "\n\n\n"; # Get the correct content from a local file open(FILE, "< $file") or warn "Can't read $file\n"; my $correct = join('', <FILE>); close(FILE); $content eq $correct or return 'GARBLE'; return 'get'; }
On Mon, Oct 13, 2003 at 03:54:51PM +0100, Damian Buckley wrote:
Hi, I have a command set up in crontab as goes:
0,20,40 9-16 * * 1-5 ping -c2 111.111.111.111 >> file.log
basically this pings one of our external network servers every 20 mins between 9am and 4pm.... it then outputs the ping to a text file for me to observe and ensure connectivity is in place, however I tend to forget about this and now want to set a command up to email me via sendmail when the ping command fails....
Is this possible? and can anybody show me how?
Have a look at mon which is included in SuSE Pro. It does exactly what you want and even more. The most recent version (mon-0.99.33-34) can be found here: ftp://ftp.kernel.org/pub/software/admin/mon/devel/ Regards, -Kastus
participants (4)
-
Carlos E. R.
-
Damian Buckley
-
Kastus
-
Michael.James@csiro.au