$0 = "spong-network";
use Sys::Hostname;
-use Net::Ping;
use Socket;
+use IO::Socket;
use POSIX;
use Getopt::Long;
use Spong::Status qw(status);
use Spong::Log;
+# Check to see if the Time::HiRes module is available
+eval "use Time::HiRes qw( time );";
+if (! $@ ) { $hires = 1; } else { $hires = 0; };
+
srand( time() ^ ($$ + ($$ << 15 )) );
$debug = $restart = $kill = 0;
-#Getopt::Long::Configure('pass_through');
if ( ! GetOptions("debug=i" => \$debuglevel, "restart" => \$restart,
"kill" => \$kill, "nosleep|refresh" => \$nosleep ) ) {
&usage();
sub check_simple {
my( $host, $port, $send, $check, $service ) = @_;
my( $color, $summary ) = ( "red", "" );
- my( $attempt, $start, $message, $diff );
+ my( $attempt, $start, $message, $diff, $errcd );
- for $a ( 1..3 ) {
- $start = time();
- $message = &check_tcp( $host, $port, $send );
- $diff = time() - $start;
+ for $timeout ( 3, 5, 12 ) {
+ $start = main::time();
+ ($errcd,$message) = &check_tcp( $host, $port, $send, $timeout );
+ $diff = main::time() - $start;
- $attempt = $a;
+ $attempt++;
if( $message =~ /$check/ ) { $color = "green"; last; }
&debug("Attempt $a failed.");
}
- $summary = "$service down" if $color eq "red";
+ $diff = sprintf("%.2f",$diff);
+
+ $summary = "$service is down, timed out" if $color eq "red" and $errcd == 3;
+ $summary = "$service is down, connection refused" if $color eq "red" and $errcd == 2;
$summary = "$service ok - $diff second response time" if $color eq "green";
$summary .= ", attempt $attempt" if ($attempt != 1 && $color eq "green");
# ---------------------------------------------------------------------------
sub check_tcp {
- my( $addr, $port, $data ) = @_;
- my( $iaddr, $paddr, $proto, $line, $ip );
+ my( $addr, $port, $data, $timeout ) = @_;
+ my( $iaddr, $paddr, $proto, $line, $ip, $sock, $err );
if( $addr =~ /^\s*((\d+\.){3}\d+)\s*$/ ) {
$ip = $addr;
} else {
my( @addrs ) = (gethostbyname($addr))[4];
+ if ( ! @addrs ) { return ( 1, "" ); }
my( $a, $b, $c, $d ) = unpack( 'C4', $addrs[0] );
$ip = "$a.$b.$c.$d";
}
- $iaddr = inet_aton( $ip ) || return -1;
- $paddr = sockaddr_in( $port, $iaddr );
- $proto = getprotobyname( 'tcp' );
-
# Set an alarm so that if we can't connect "immediately" it times out.
# Poor man's exception handling in perl...
- $SIG{'ALRM'} = sub { die };
- alarm(10);
-
- eval <<'_EOM_';
- socket( SOCK, PF_INET, SOCK_STREAM, $proto ) || return -2;
- connect( SOCK, $paddr ) || return -3;
- select((select(SOCK), $| = 1)[0]);
- print SOCK "$data";
- recv( SOCK, $line, 256, 0 ); # just grab a chunk from the service.
- close( SOCK ) || return -4;
-_EOM_
-
- alarm(0);
- return $line;
+ $err = 0;
+ $line = 0;
+ {
+ local $SIG{'ALRM'} = sub { die "Socket timed out"; };
+ alarm($timeout);
+
+ eval {
+ $sock = IO::Socket::INET->new( PeerAddr => $ip,
+ PeerPort => $port,
+ Proto => 'tcp',
+ Reuse => 1,
+ );
+ if ( defined $sock ) {
+ print $sock "$data";
+ $sock->recv( $line, 256, 0 ); # just grab a chunk from the service.
+ } else {
+ $err = 2; # Could not connect to service port
+ }
+
+ alarm(0);
+ };
+ };
+
+ if ( $@ =~ /timed out/ ) { $err = 3; }
+
+ return ($err, $line);
}