Author | wnelis |
Compatibility | Xymon 4.x |
Requirements | Perl |
Download | None |
Last Update | 2009-05-21 |
nlbping is a simple server-side test to see if the nodes of a Windows Network Load Balancing (NLB) cluster are all reachable. The TCP and UDP sessions are distributed over the nodes, causing only one node to respond. ICMP (ping) however, is handled by all nodes. Thus an NLB cluster of N nodes will give N replies to a ping. This is used to see if all nodes are accessible.
The cluster is pinged three times. It is found that the replies to the first ping are sometimes incomplete, and that the replies to the last ping may get lost. Therefore, the cluster is pinged three times, and only the results on the second ping are used.
The NLB clusters, that is a service on the clusters, are described in a separate perl module, nlbping.pm. It specifies for each cluster the service name, the IP address and the number of nodes in the cluster.
Server side
Save both script nlbping.pl and module nlbping.pm in the subdirectory with the server-side scripts, for instance /home/hobbit/server/ext/.
Add to hobbitlaunch.cfg:
[nlbping]
ENVFILE /home/hobbit/server/etc/hobbitserver.cfg
CMD /home/hobbit/server/ext/nlbping.pl
LOGFILE $BBSERVERLOGS/nlbping.log
INTERVAL 5m
#!/usr/bin/perl -w
#
# NlbPing: Ping an NLB cluster service. Let N be the number of nodes in the
# cluster. A ping then should result in N replies, thus in N-1 duplicates.
# If the number of duplicates is not correct, raise an error condition (red).
#
use strict ;
use POSIX qw/ strftime / ; # Format time
use lib "/home/hobbit/server/ext" ;
use nlbping ; # List of NLB cluster services
#
# Installation constants.
#
my $XyDisp= $ENV{BBSERVERHOSTNAME} ; # Name of monitor server
my $XySend= $ENV{BB} ; # Monitor interface program
my $FmtDate= "%Y.%m.%d %H:%M:%S" ; # Default date format
$FmtDate= $ENV{BBDATEFORMAT} if defined $ENV{BBDATEFORMAT} ;
#
my $PingCmd= "ping -c 3 -i 0.2 %s" ; # Template for ping command
#
# Variable allocation.
#
my $Now= strftime( $FmtDate, localtime ) ; # Timestamp of tests
my $Cmd ; # Full blown ping command
my $Color ; # Test status
my $Reply ; # Count of replies
my $RTT ; # Average round trip time
my @Lines ; # Ping output
my $Result ; # Test result
foreach my $Service ( keys %NlbService ) {
$Cmd= sprintf( $PingCmd, $NlbService{$Service}{IP} ) ;
@Lines= `$Cmd` ;
$Reply= 0 ; # Number of replies found
$RTT= 0 ; # Sum of RTT's
foreach ( @Lines ) {
next unless m/\bicmp_seq=1\b/ ;
$Reply++ ;
$RTT+= $1 if m/\btime=([\d\.]+)\s+ms/ ;
} # of foreach
$RTT/= 1000 * $Reply if $Reply > 0 ;
$RTT= sprintf "%8.5f", $RTT ;
$Color = "green" ; # Default status
$Result= "$Service is reachable" ;
if ( $Reply == 0 ) {
$Color = "red" ; # No replies at all
$Result= "$Service is not reachable" ;
} elsif ( $Reply < $NlbService{$Service}{Nodes} ) {
$Color = "yellow" ; # Too less replies
$Result= "$Service is partially reachable:\n" .
"$Reply out of $NlbService{$Service}{Nodes} nodes replied" ;
} # of elsif
$Result= "\"status $Service.nlbping $Color $Now\n" .
"Connectivity of NLB cluster service $Service\n\n" .
"&$Color $Result\n" .
"<!--\nrtt=$RTT\n-->\"\n" ;
`$XySend $XyDisp $Result` ; # Inform Xymon
} # of foreach
A template for module nlbping.pm:
package nlbping ;
require Exporter ;
our @ISA = qw/ Exporter / ;
our @EXPORT= qw/ %NlbService / ;
%NlbService= (
"<Service>" => { IP => "<IP address>" , Nodes => <N> },
"<Service>" => { IP => "<IP address>" , Nodes => <N> },
) ;
1 ;
Known Bugs and Issues