hotsanic |
Subversion Repositories: |
Compare with Previous - Blame - Download
package HotSaNICmod::OSdep;
use RRDs;
sub version {
($VERSION = '$Revision: 1.11 $') =~ s/.*(\d+\.\d+).*/$1/;
return "default.pm $VERSION";
}
sub sample {
my %args=@_;
$mtime=(stat("rrd"))[9];
$now=time;
# if ((($mtime+$interval) > $now) && ($mtime+5 < $now)) { dupe_control("stop",$ARGS{"MODNAME"},""); }
if (($mtime+$args{INTERVAL}) <= $now) {
utime $now,$now,"rrd";
$processes=0;
sub wait_for_child {
my $pid = wait;
return 0 if $pid < 0;
$processes--;
if ($processes<0) {$processes=0;}
}
my @HOSTS=();
foreach (keys(%args)) {
if (index($_,"HOST:") >=0 ) {
(undef,$host)=split /:/;
push @HOSTS,$host;
}
}
foreach $host (@HOSTS) {
wait_for_child() if $processes >= $args{PARALLEL};
$processes++;
$return=fork;
# child process
if ($return == 0) {
if (defined($args{DEBUGLEVEL}) && $args{DEBUGLEVEL}>100) { print " > $host\n"; }
if ($args{SYSPING} == 0) { ($min,$avg,$max)=ping($host,250,250,10,$args{PROTOCOL}); }
else { ($min,$avg,$max)=sysping($host,250,250,10); }
if ( ! -e "rrd/$host.rrd" ) { system("./makerrd","$host","U") }
RRDs::update "rrd/$host.rrd",time.":".$min.":".$avg.":".$max;
if ($ERROR = RRDs::error) { print time," ",$MODNAME,": unable to update `$host.rrd': $ERROR"; }
# if ($args{DEBUGLEVEL}>101) { printf " < %-15s (%3.2f/%3.2f/%3.2f)\n",$host,$min,$avg,$max; }
exit 0;
}
}
}
while($processes) { wait_for_child(); }
}
#### Usage:
#### ping ("host or IP",timeout (ms), wait (ms), count, protocol);
####
#### Return:
#### min/avg/max (ms)
sub ping {
my $TIMING="";
eval { require Time::HiRes; };
if ($@) { print "Time::HiRes not found!\n"; }
else { $TIMING="Time::HiRes"; require Time::HiRes; }
if ($TIMING eq "") {
eval { require 'sys/syscall.ph'; };
if ($@) { print "syscall.ph not found!\n"; }
else { $TIMING="syscall"; require 'sys/syscall.ph'; }
}
if ($TIMING eq "") {
print "No suitable timing method found!\nPlease consider to install the Time::HiRes module from CPAN.\nYou can get it at http://www.cpan.org/\n";
return (0,0,0);
}
use Net::Ping;
my $HOST=shift || "127.0.0.1";
my $TIMEOUT=shift || 50;
my $WAIT=shift || 1000;
my $COUNT=shift || 10;
my $PROTOCOL=shift || "icmp";
if ($TIMEOUT<50) { $TIMEOUT=50; }
$TIMEOUT/=1000;
$WAIT/=1000;
if ($COUNT<5) { $COUNT=5; }
$min=10000000; $max=0; $add=0;
$p = Net::Ping->new($PROTOCOL);
$TIMEVAL_T = "LL";
$done = $start = pack($TIMEVAL_T, ());
$replies=0;
# $first_reply=$p->ping($HOST, $TIMEOUT);
for ($i=0; $i < $COUNT ; $i++) {
if ($TIMING eq "syscall") { syscall(&SYS_gettimeofday, $start, 0) != -1 or dupe_control("die",$MODNAME,": gettimeofday: $!"); }
if ($TIMING eq "Time::HiRes") { $start=Time::HiRes::time(); }
$reply=$p->ping($HOST, $TIMEOUT);
if ($TIMING eq "syscall") {
syscall(&SYS_gettimeofday, $done, 0) != -1 or dupe_control("die",$MODNAME,": gettimeofday: $!");
@start = unpack($TIMEVAL_T, $start);
@done = unpack($TIMEVAL_T, $done);
$time=($done[0]-$start[0])*1000 + ($done[1]-$start[1])/1000;
}
if ($TIMING eq "Time::HiRes") {
$done=Time::HiRes::time();
$time=$done-$start;
}
if ( $reply ) {
push @timearr,$time;
$replies++;
$add+=$time;
}
select (undef, undef,undef,$WAIT);
}
$p->close();
$avg=$add/$replies if $replies>0;
$replies=0;$add=0;
foreach (@timearr) {
if ($_ < 3*$avg) {
$add+=$_;
$replies++;
$min=$_ if $_<$min;
$max=$_ if $_>$max;
}
}
if ($replies eq 0) { $replies++; $min=0; $max=0; $add=0; }
$avg=$add/$replies;
return($min,$avg,$max);
}
sub sysping {
my($HOST,$TIMEOUT,$WAIT,$COUNT)=@_;
$TIMEOUT/=1000;
$WAIT/=1000;
my $command="ping $HOST -c $COUNT -w 1 -i 0.2";
my $line = "";
open FILE,"$command |" || print time," ",$MODNAME,": unable to run `$command': $!\n";
while (<FILE>) { $line=$_; }
close FILE;
# for testing purposes...
#
# $line="round-trip min/avg/max = 0.4/0.4/0.4 ms";
# $line="round-trip min/avg/max/mdev = 0.285/0.304/0.324/0.026 ms";
# $line="rtt min/avg/max/mdev = 0.160/0.194/0.238/0.035 ms";
my $factor=1000;
chomp $line;
if ( (index($line,"round-trip") >=0) || (index($line,"rtt") >=0) ) {
(undef,$times)=split /= */,$line;
($min,$avg,$max)=split /[\/ ]/,$times;
if ($times =~ /us/) { $factor=1000000; }
}
else { ($min,$avg,$max)=(0,0,0); }
return($min/$factor,$avg/$factor,$max/$factor);
}
1;