diff options
author | Tobi Oetiker <tobi@oetiker.ch> | 2005-02-11 21:22:38 +0100 |
---|---|---|
committer | Tobi Oetiker <tobi@oetiker.ch> | 2005-02-11 21:22:38 +0100 |
commit | 3623e33d0ae10eaeca653e00a3796495dbc0f713 (patch) | |
tree | a0835e8015f995402c2b8046255d7d101e7f9a59 /lib/probes/base.pm | |
download | smokeping-3623e33d0ae10eaeca653e00a3796495dbc0f713.tar.gz smokeping-3623e33d0ae10eaeca653e00a3796495dbc0f713.tar.xz |
initial import
Diffstat (limited to 'lib/probes/base.pm')
-rw-r--r-- | lib/probes/base.pm | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/lib/probes/base.pm b/lib/probes/base.pm new file mode 100644 index 0000000..79165f1 --- /dev/null +++ b/lib/probes/base.pm @@ -0,0 +1,217 @@ +package probes::base; + +=head1 NAME + +probes::base - Base Class for implementing SmokePing Probes + +=head1 OVERVIEW + +For the time being, please use the probes::FPing for +inspiration when implementing your own probes. + +=head1 AUTHOR + +Tobias Oetiker <tobi@oetiker.ch> + +=cut + +use vars qw($VERSION); +use Carp; +use lib qw(..); +use Smokeping; + +$VERSION = 1.0; + +use strict; + +sub new($$) +{ + my $this = shift; + my $class = ref($this) || $this; + my $self = { properties => shift, cfg => shift, + name => shift, + targets => {}, rtts => {}, addrlookup => {}}; + bless $self, $class; + return $self; +} + +sub add($$) +{ + my $self = shift; + my $tree = shift; + + $self->{targets}{$tree} = shift; +} + +sub ping($) +{ + croak "this must be overridden by the subclass"; +} + +sub round ($) { + return sprintf "%.0f", $_[0]; +} + +sub ProbeDesc ($) { + return "Probe which does not overrivd the ProbeDesc methode"; +} + +sub rrdupdate_string($$) +{ my $self = shift; + my $tree = shift; +# print "$tree -> ", join ",", @{$self->{rtts}{$tree}};print "\n"; + # skip invalid addresses + my $pings = $self->_pings($tree); + return "U:${pings}:".(join ":", map {"U"} 1..($pings+1)) + unless defined $self->{rtts}{$tree} and @{$self->{rtts}{$tree}} > 0; + my $entries = scalar @{$self->{rtts}{$tree}}; + my @times = @{$self->{rtts}{$tree}}; + my $loss = $pings - $entries; + my $median = $times[int($entries/2)] || 'U'; + # shift the data into the middle of the times array + my $lowerloss = int($loss/2); + my $upperloss = $loss - $lowerloss; + @times = ((map {'U'} 1..$lowerloss),@times, (map {'U'} 1..$upperloss)); + my $age; + if ( -f $self->{targets}{$tree}.".adr" ) { + $age = time - (stat($self->{targets}{$tree}.".adr"))[9]; + } else { + $age = 'U'; + } + if ( $entries == 0 ){ + $age = 'U'; + $loss = 'U'; + if ( -f $self->{targets}{$tree}.".adr" + and not -f $self->{targets}{$tree}.".snmp" ){ + unlink $self->{targets}{$tree}.".adr"; + } + } ; + return "${age}:${loss}:${median}:".(join ":", @times); +} + +sub addresses($) +{ + my $self = shift; + my $addresses = []; + $self->{addrlookup} = {}; + foreach my $tree (keys %{$self->{targets}}){ + my $target = $self->{targets}{$tree}; + if ($target =~ m|/|) { + if ( open D, "<$target.adr" ) { + my $ip; + chomp($ip = <D>); + close D; + + if ( open D, "<$target.snmp" ) { + my $snmp = <D>; + chomp($snmp); + if ($snmp ne Smokeping::snmpget_ident $ip) { + # something fishy snmp properties do not match, skip this address + next; + } + close D; + } + $target = $ip; + } else { + # can't read address file skip + next; + } + } + $self->{addrlookup}{$target} = () + unless defined $self->{addrlookup}{$target}; + push @{$self->{addrlookup}{$target}}, $tree; + push @{$addresses}, $target; + }; + return $addresses; +} + +sub debug { + my $self = shift; + my $newval = shift; + $self->{debug} = $newval if defined $newval; + return $self->{debug}; +} + +sub do_debug { + my $self = shift; + return unless $self->debug; + $self->do_log(@_); +} + +sub do_fatal { + my $self = shift; + $self->do_log("Fatal:", @_); + croak(@_); +} + +sub do_log { + my $self = shift; + Smokeping::do_log("$self->{name}:", @_); +} + +sub report { + my $self = shift; + my $count = $self->target_count; + my $offset = $self->offset_in_seconds; + my $step = $self->step; + $self->do_log("probing $count targets with step $step s and offset $offset s."); +} + +sub step { + my $self = shift; + my $rv = $self->{cfg}{Database}{step}; + unless (defined $self->{cfg}{General}{concurrentprobes} + and $self->{cfg}{General}{concurrentprobes} eq 'no') { + $rv = $self->{properties}{step} if defined $self->{properties}{step}; + } + return $rv; +} + +sub offset { + my $self = shift; + my $rv = $self->{cfg}{General}{offset}; + unless (defined $self->{cfg}{General}{concurrentprobes} + and $self->{cfg}{General}{concurrentprobes} eq 'no') { + $rv = $self->{properties}{offset} if defined $self->{properties}{offset}; + } + return $rv; +} + +sub offset_in_seconds { + # returns the offset in seconds rather than as a percentage + # this is filled in from the initialization in Smokeping::main + my $self = shift; + my $newval = shift; + $self->{offset_in_seconds} = $newval if defined $newval; + return $self->{offset_in_seconds}; +} + +# the "public" method that takes a "target" argument is used by the probes +# the "private" method that takes a "tree" argument is used by Smokeping.pm +# there's no difference between them here, but we have to provide both + +sub pings { + my $self = shift; + my $target = shift; + # $target is not used; basefork.pm overrides this method to provide a target-specific parameter + my $rv = $self->{cfg}{Database}{pings}; + $rv = $self->{properties}{pings} if defined $self->{properties}{pings}; + return $rv; +} + + +sub _pings { + my $self = shift; + my $tree = shift; + # $tree is not used; basefork.pm overrides this method to provide a target-specific parameter + my $rv = $self->{cfg}{Database}{pings}; + $rv = $self->{properties}{pings} if defined $self->{properties}{pings}; + return $rv; +} + +sub target_count { + my $self = shift; + return scalar keys %{$self->{targets}}; +} + +1; |