diff options
author | Niko Tyni <ntyni@iki.fi> | 2005-02-13 20:23:04 +0100 |
---|---|---|
committer | Niko Tyni <ntyni@iki.fi> | 2005-02-13 20:23:04 +0100 |
commit | 6d76521656e91daa160bc8019828f1b68d7aa5dc (patch) | |
tree | aaa27615a0702942fa1606d9a5c89f0a3547467c /lib/Smokeping/matchers | |
parent | 6dba1afbe4b475a7d34f5ef867b7b37291cd1484 (diff) | |
download | smokeping-6d76521656e91daa160bc8019828f1b68d7aa5dc.tar.gz smokeping-6d76521656e91daa160bc8019828f1b68d7aa5dc.tar.xz |
Moved probes, matchers and ciscoRttMonMIB modules to lib/Smokeping.
Diffstat (limited to 'lib/Smokeping/matchers')
-rw-r--r-- | lib/Smokeping/matchers/avgratio.pm | 148 | ||||
-rw-r--r-- | lib/Smokeping/matchers/base.pm | 127 | ||||
-rw-r--r-- | lib/Smokeping/matchers/median.pm | 80 |
3 files changed, 355 insertions, 0 deletions
diff --git a/lib/Smokeping/matchers/avgratio.pm b/lib/Smokeping/matchers/avgratio.pm new file mode 100644 index 0000000..fab0164 --- /dev/null +++ b/lib/Smokeping/matchers/avgratio.pm @@ -0,0 +1,148 @@ +package Smokeping::matchers::avgratio; + +=head1 NAME + +Smokeping::matchers::avgratio - detect changes in average median latency + +=head1 OVERVIEW + +The avgratio matcher establishes a historic average median latency over +several measurement rounds. It compares this average, against a second +average latency value again build over several rounds of measurment. + +=head1 DESCRIPTION + +Call the matcher with the following sequence: + + type = matcher + pattern = avgratio(historic=>a,current=>b,comparator=>o,percentage=>p) + +=over + +=item historic + +The number of median values to use for building the 'historic' average. + +=item current + +The number of median values to use for building the 'current' average. + +=item comparator + +Which comparison operator should be used to compare current/historic with percentage. + +=item percentage + +Right hand side of the comparison. + +=back + + old <--- historic ---><--- current ---> now + +=head1 EXAMPLE + +Take build the average median latency over 10 samples, use this to divid the +current average latency built over 2 samples and check if it is bigger than +150%. + + avgratio(historic=>10,current=>2,comparator=>'>',percentage=>150); + + avg(current)/avg(historic) > 150/100 + +This means the matcher will activate when the current latency average if +more than 1.5 times the historic latency average established over the last +10 rounds of measurement. + +=head1 COPYRIGHT + +Copyright (c) 2004 by OETIKER+PARTNER AG. All rights reserved. + +=head1 SPONSORSHIP + +The development of this matcher has been sponsored by Virtela Communications www.virtela.net. + +=head1 LICENSE + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +=head1 AUTHOR + +Tobias Oetiker <tobi@oetiker.ch> + +=cut + +use vars qw($VERSION); + + +$VERSION = 1.0; + +use strict; +use base qw(Smokeping::matchers::base); +use Carp; + +sub new(@) +{ + my $class = shift; + my $rules = { + historic=>'\d+', + current=>'\d+', + comparator=>'(<|>|<=|>=|==)', + percentage=>'\d+(\.\d+)?' }; + + my $self = $class->SUPER::new($rules,@_); + $self->{param}{sub} = eval "sub {\$_[0] ".$self->{param}{comparator}." \$_[1]}"; + croak "compiling comparator $self->{param}{comparator}: $@" if $@; + $self->{param}{value} = $self->{param}{percentage}/100; + return $self; +} + +sub Length($) +{ + my $self = shift; + return $self->{param}{historic} + $self->{param}{current}; +} + +sub Desc ($) { + croak "Detect changes in average median latency"; +} + +sub avg(@){ + my $sum=0; + my $cnt=0; + for (@_){ + next unless defined $_; + $sum += $_; + $cnt ++; + } + return $sum/$cnt if $cnt; + return undef; +} + +sub Test($$) +{ my $self = shift; + my $data = shift; # @{$data->{rtt}} and @{$data->{loss}} + my $len = $self->Length; + my $rlen = scalar @{$data->{rtt}}; + return undef + if $rlen < $len + or (defined $data->{rtt}[-$len] and $data->{rtt}[-$len] eq 'S'); + my $ac = $self->{param}{historic}; + my $bc = $self->{param}{current}; + my $cc = $ac +$bc; + my $ha = avg(@{$data->{rtt}}[-$cc..-$bc-1]); + my $ca = avg(@{$data->{rtt}}[-$bc..-1]); + return undef unless $ha and $ca; + return &{$self->{param}{sub}}($ca/$ha,$self->{param}{value}); +} diff --git a/lib/Smokeping/matchers/base.pm b/lib/Smokeping/matchers/base.pm new file mode 100644 index 0000000..cd69871 --- /dev/null +++ b/lib/Smokeping/matchers/base.pm @@ -0,0 +1,127 @@ +package Smokeping::matchers::base; + +=head1 NAME + +Smokeping::matchers::base - Base Class for implementing SmokePing Matchers + +=head1 OVERVIEW + +This is the base class for writing SmokePing matchers. Every matcher must +inherit from the base class and provide it's own methods for the 'buisness' +logic. + +=head1 DESCRIPTION + +Every matcher must provide the following methods: + +=cut + +use vars qw($VERSION); +use Carp; + +$VERSION = 1.0; + +use strict; + +=head2 new + +The new method expects hash elements as an argument +eg new({x=>'\d+',y=>'\d+'},x=>1,y=>2). The first part is +a syntax rule for the arguments it should expect and the second part +are the arguments itself. The first part will be supplied +by the child class as it calls the partent method. + +=cut + +sub new(@) +{ + my $this = shift; + my $class = ref($this) || $this; + my $rules = shift; + my $self = { param => { @_ } }; + foreach my $key (keys %{$self->{param}}){ + my $regex = $rules->{$key}; + croak "key '$key' is not known byt this matcher" unless defined $rules->{$key}; + croak "key '$key' contains invalid data: '$self->{param}{$key}'" unless $self->{param}{$key} =~ m/^$regex$/; + } + bless $self, $class; + return $self; +} + +=head2 Length + +The Length method returns the number of values the +matcher will expect from SmokePing. This method must +be overridden by the children of the base class. + +=cut + +sub Length($) +{ + my $self = shift; + croak "SequenceLength must be overridden by the subclass"; +} + +=head2 Desc + +Simply return the description of the function. This method must +be overwritten by a children of the base class. + +=cut + + +sub Desc ($) { + croak "MatcherDesc must be overridden by the subclass"; +} + +=head2 Test + +Run the matcher and return true or false. The Test method is called +with a hash of two arrays giving it access to both rtt and loss values + + my $data=shift; + my @rtt = @{$data->{rtt}}; + my @loss = @{$data->{loss}}; + +The arrays are ordered from old to new. + + @rdd[old..new] + +There may be more than the expected number of elements in this array. Address them with +$x[-1] to $x[-max]. + + +=cut + +sub Test($$) +{ my $self = shift; + my $data = shift; # @{$data->{rtt}} and @{$data->{loss}} + croak "Match must be overridden by the subclass"; + +} + +=head1 COPYRIGHT + +Copyright (c) 2004 by OETIKER+PARTNER AG. All rights reserved. + +=head1 LICENSE + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +=head1 AUTHOR + +Tobias Oetiker <tobi@oetiker.ch> + +=cut diff --git a/lib/Smokeping/matchers/median.pm b/lib/Smokeping/matchers/median.pm new file mode 100644 index 0000000..e8d43cf --- /dev/null +++ b/lib/Smokeping/matchers/median.pm @@ -0,0 +1,80 @@ +package Smokeping::matchers::median; + +=head1 NAME + +Smokeping::matchers::median - Find persistant change in latency + +=head1 OVERVIEW + +The idea behind this matcher is to find sustained changes in latency. + +The median matcher takes a number of past median latencies. It splits the latencies into +two groups (old and new) and again finds the median for each groups. If the +difference between the two medians is bigger than a certain value, it will +give a match. + +=head1 DESCRIPTION + +Call the matcher with the following sequence: + + type = matcher + pattern = median(old=>x,new=>y,diff=>z) + +This will create a matcher which consumes x+y latency-datapoints, builds the +two medians and the matches if the difference between the median latency is +larger than z seconds. + +=head1 COPYRIGHT + +Copyright (c) 2004 by OETIKER+PARTNER AG. All rights reserved. + +=head1 LICENSE + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +=head1 AUTHOR + +Tobias Oetiker <tobi@oetiker.ch> + +=cut + +use strict; +use base qw(Smokeping::matchers::base); +use vars qw($VERSION); +$VERSION = 1.0; +use Carp; + +# how many values does the matcher need to do it's magic +sub Length($) +{ + my $self = shift; + return $self->{param}{old} + $self->{param}{new}; +} + +sub Desc ($) { + croak "Finde changes in median latency"; +} + +sub Test($$) +{ my $self = shift; + my $data = shift; # @{$data->{rtt}} and @{$data->{loss}} + my $ac = $self->{param}{old}; + my $bc = $self->{param}{new}; + my $cc = $ac +$bc; + my $oldm = (sort {$a <=> $b} @{$data->{rtt}}[-$cc..-$bc-1])[int($a/2)]; + $ac++; + my $newm = (sort {$a <=> $b} @{$data->{rtt}}[-$bc..-1])[int($bc/2)]; + return abs($oldm-$newm) > $self->{param}{diff}; +} |