summaryrefslogtreecommitdiffstats
path: root/lib/Smokeping
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Smokeping')
-rw-r--r--lib/Smokeping/RRDtools.pm73
-rw-r--r--lib/Smokeping/matchers/Avgratio.pm2
-rw-r--r--lib/Smokeping/probes/AnotherDNS.pm18
-rw-r--r--lib/Smokeping/probes/CiscoRTTMonEchoICMP.pm41
-rw-r--r--lib/Smokeping/probes/Curl.pm56
-rw-r--r--lib/Smokeping/probes/base.pm51
-rw-r--r--lib/Smokeping/probes/passwordchecker.pm2
7 files changed, 185 insertions, 58 deletions
diff --git a/lib/Smokeping/RRDtools.pm b/lib/Smokeping/RRDtools.pm
index 7260cca..2b7ad2b 100644
--- a/lib/Smokeping/RRDtools.pm
+++ b/lib/Smokeping/RRDtools.pm
@@ -4,7 +4,7 @@ package Smokeping::RRDtools;
Smokeping::RRDtools - Tools for RRD file handling
-=head1 SYNOPSYS
+=head1 SYNOPSIS
use Smokeping::RRDtools;
use RRDs;
@@ -22,12 +22,15 @@ Smokeping::RRDtools - Tools for RRD file handling
my $comparison = Smokeping::RRDtools::compare($file, \@create);
print "Create arguments didn't match: $comparison\n" if $comparison;
+ Smokeping::RRDtools::tuneds($file, \@create);
+
=head1 DESCRIPTION
-This module offers two functions, C<info2create> and C<compare>.
-The first can be used to recreate the arguments that an RRD file
-was created with. The second checks if an RRD file was created
-with the given arguments.
+This module offers three functions, C<info2create>, C<compare> and
+C<tuneds>. The first can be used to recreate the arguments that an RRD file
+was created with. The second checks if an RRD file was created with the
+given arguments. The thirds tunes the DS parameters according to the
+supplied create string.
The function C<info2create> must be called with one argument:
the path to the interesting RRD file. It will return an array
@@ -35,14 +38,17 @@ reference of the argument list that can be fed to C<RRDs::create>.
Note that this list will never contain the C<start> parameter,
but it B<will> contain the C<step> parameter.
-The function C<compare> must be called with two arguments: the path
-to the interesting RRD file, and a reference to an argument list that
-could be fed to C<RRDs::create>. The function will then simply compare
-the result of C<info2create> with this argument list. It will return
-C<undef> if the arguments matched, and a string indicating the difference
-if a discrepancy was found. Note that if there is a C<start> parameter in
-the argument list, C<compare> disregards it. If C<step> isn't specified,
-C<compare> will use the C<rrdtool> default of 300 seconds.
+The function C<compare> must be called with two arguments: the path to the
+interesting RRD file, and a reference to an argument list that could be fed
+to C<RRDs::create>. The function will then simply compare the result of
+C<info2create> with this argument list. It will return C<undef> if the
+arguments matched, and a string indicating the difference if a discrepancy
+was found. Note that if there is a C<start> parameter in the argument list,
+C<compare> disregards it. If C<step> isn't specified, C<compare> will use
+the C<rrdtool> default of 300 seconds. C<compare> ignores non-matching DS
+parameters since C<tuneds> will fix them.
+
+C<tuneds> talks on stderr about the parameters it fixes.
=head1 NOTES
@@ -57,6 +63,10 @@ Probably.
Copyright (c) 2005 by Niko Tyni.
+=head1 AUTHOR
+
+Niko Tyni <ntyni@iki.fi>
+
=head1 LICENSE
This program is free software; you can redistribute it
@@ -89,11 +99,13 @@ use RRDs;
sub info2create {
my $file = shift;
my @create;
+ my $buggy_perl_version = 1 if $^V and $^V eq v5.8.0;
my $info = RRDs::info($file);
my $error = RRDs::error;
die("RRDs::info $file: ERROR: $error") if $error;
die("$file: unknown RRD version: $info->{rrd_version}")
- unless $info->{rrd_version} eq '0001';
+ unless $info->{rrd_version} eq '0001'
+ or $info->{rrd_version} eq '0003';
my $cf = $info->{"rra[0].cf"};
die("$file: no RRAs found?")
unless defined $cf;
@@ -107,7 +119,8 @@ sub info2create {
my @s = ("DS", $ds);
for (qw(type minimal_heartbeat min max)) {
die("$file: missing $_ for DS $ds?")
- unless exists $info->{"ds[$ds].$_"};
+ unless exists $info->{"ds[$ds].$_"}
+ or $buggy_perl_version;
my $val = $info->{"ds[$ds].$_"};
push @s, defined $val ? $val : "U";
}
@@ -117,7 +130,8 @@ sub info2create {
my @s = ("RRA", $info->{"rra[$i].cf"});
for (qw(xff pdp_per_row rows)) {
die("$file: missing $_ for RRA $i")
- unless exists $info->{"rra[$i].$_"};
+ unless exists $info->{"rra[$i].$_"}
+ or $buggy_perl_version;
push @s, $info->{"rra[$i].$_"};
}
push @create, join(":", @s);
@@ -160,10 +174,37 @@ sub compare {
while (my $arg = shift @create) {
my $arg2 = shift @create2;
+ my @ds = split /:/, $arg;
+ my @ds2 = split /:/, $arg2;
+ next if $ds[0] eq 'DS' and $ds[0] eq $ds2[0] and $ds[1] eq $ds2[1] and $ds[2] eq $ds2[2];
return "Different arguments: $file has $arg2, create string has $arg"
unless $arg eq $arg2;
}
return undef;
}
+sub tuneds {
+ my $file = shift;
+ my $create = shift;
+ my @create2 = sort grep /^DS/, @{info2create($file)};
+ my @create = sort grep /^DS/, @$create;
+ while (@create){
+ my @ds = split /:/, shift @create;
+ my @ds2 = split /:/, shift @create2;
+ next unless $ds[1] eq $ds2[1] and $ds[2] eq $ds[2];
+ if ($ds[3] ne $ds2[3]){
+ warn "## Updating $file DS:$ds[1] heartbeat $ds2[3] -> $ds[3]\n";
+ RRDs::tune $file,"--hearbeat","$ds[1]:$ds[3]" unless $ds[3] eq $ds2[3];
+ }
+ if ($ds[4] ne $ds2[4]){
+ warn "## Updating $file DS:$ds[1] minimum $ds2[4] -> $ds[4]\n";
+ RRDs::tune $file,"--minimum","$ds[1]:$ds[4]" unless $ds[4] eq $ds2[4];
+ }
+ if ($ds[5] ne $ds2[5]){
+ warn "## Updating $file DS:$ds[1] maximum $ds2[5] -> $ds[5]\n";
+ RRDs::tune $file,"--maximum","$ds[1]:$ds[5]" unless $ds[5] eq $ds2[5];
+ }
+ }
+}
+
1;
diff --git a/lib/Smokeping/matchers/Avgratio.pm b/lib/Smokeping/matchers/Avgratio.pm
index 8679fe9..e97fcf0 100644
--- a/lib/Smokeping/matchers/Avgratio.pm
+++ b/lib/Smokeping/matchers/Avgratio.pm
@@ -5,7 +5,7 @@ package Smokeping::matchers::Avgratio;
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 measurement.
diff --git a/lib/Smokeping/probes/AnotherDNS.pm b/lib/Smokeping/probes/AnotherDNS.pm
index 65a1bd4..d4f0397 100644
--- a/lib/Smokeping/probes/AnotherDNS.pm
+++ b/lib/Smokeping/probes/AnotherDNS.pm
@@ -69,6 +69,7 @@ sub pingone ($) {
my $recordtype = $target->{vars}{recordtype};
my $timeout = $target->{vars}{timeout};
my $port = $target->{vars}{port};
+ my $require_noerror = $target->{vars}{require_noerror};
$lookuphost = $target->{addr} unless defined $lookuphost;
my $packet = Net::DNS::Packet->new( $lookuphost, $recordtype )->data;
@@ -93,9 +94,20 @@ sub pingone ($) {
my $t1 = [gettimeofday];
$elapsed = tv_interval( $t0, $t1 );
if ( defined $ready ) {
- push @times, $elapsed;
my $buf = '';
$ready->recv( $buf, &Net::DNS::PACKETSZ );
+ my ($recvPacket, $err) = Net::DNS::Packet->new(\$buf);
+ if (defined $recvPacket) {
+ if (not $require_noerror) {
+ push @times, $elapsed;
+ } else {
+ # Check the Response Code for the NOERROR.
+ my $recvHeader = $recvPacket->header();
+ if ($recvHeader->rcode() eq "NOERROR") {
+ push @times, $elapsed;
+ }
+ }
+ }
}
}
@times =
@@ -127,6 +139,10 @@ DOC
_default => .5,
_re => '(\d*\.)?\d+',
},
+ require_noerror => {
+ _doc => 'Only Count Answers with Response Status NOERROR.',
+ _default => 0,
+ },
recordtype => {
_doc => 'Record type to look up.',
_default => 'A',
diff --git a/lib/Smokeping/probes/CiscoRTTMonEchoICMP.pm b/lib/Smokeping/probes/CiscoRTTMonEchoICMP.pm
index f763fde..c542ed1 100644
--- a/lib/Smokeping/probes/CiscoRTTMonEchoICMP.pm
+++ b/lib/Smokeping/probes/CiscoRTTMonEchoICMP.pm
@@ -92,8 +92,7 @@ sub new($$$)
sub ProbeDesc($){
my $self = shift;
- my $bytes = $self->{properties}{packetsize};
- return "CiscoRTTMonEchoICMP ($bytes Bytes)";
+ return "CiscoRTTMonEchoICMP";
}
sub pingone ($$) {
@@ -102,7 +101,7 @@ sub pingone ($$) {
my $pings = $self->pings($target) || 20;
my $tos = $target->{vars}{tos};
- my $bytes = $target->{properties}{packetsize};
+ my $bytes = $target->{vars}{packetsize};
# use the proces ID as as row number to make this poll distinct on the router;
my $row=$$;
@@ -260,27 +259,6 @@ sub DestroyData ($$) {
&snmpset($host, "rttMonCtrlAdminStatus.$row", 'integer', 6);
}
-sub probevars {
- my $class = shift;
- return $class->_makevars($class->SUPER::probevars, {
- packetsize => {
- _doc => <<DOC,
-The packetsize parameter lets you configure the packetsize for the pings
-sent. The minimum is 8, the maximum 16392. Use the same number as with
-fping, if you want the same packet sizes being used on the network.
-DOC
- _default => 56,
- _re => '\d+',
- _sub => sub {
- my $val = shift;
- return "ERROR: packetsize must be between 8 and 16392"
- unless $val >= 8 and $val <= 16392;
- return undef;
- },
- },
- });
-}
-
sub targetvars {
my $class = shift;
return $class->_makevars($class->SUPER::targetvars, {
@@ -315,6 +293,21 @@ corresponds to a DSCP value 40 and a Precedence value of 5. The RTTMon
MIB versions before IOS 12.0(3)T didn't support this parameter.
DOC
},
+ packetsize => {
+ _doc => <<DOC,
+The packetsize parameter lets you configure the packetsize for the pings
+sent. The minimum is 8, the maximum 16392. Use the same number as with
+fping, if you want the same packet sizes being used on the network.
+DOC
+ _default => 56,
+ _re => '\d+',
+ _sub => sub {
+ my $val = shift;
+ return "ERROR: packetsize must be between 8 and 16392"
+ unless $val >= 8 and $val <= 16392;
+ return undef;
+ },
+ },
});
}
diff --git a/lib/Smokeping/probes/Curl.pm b/lib/Smokeping/probes/Curl.pm
index 56dd338..af5be29 100644
--- a/lib/Smokeping/probes/Curl.pm
+++ b/lib/Smokeping/probes/Curl.pm
@@ -102,6 +102,48 @@ host to be probed.
DOC
_example => "http://%host%/",
},
+ insecure_ssl => {
+ _doc => <<DOC,
+The "-k" curl(1) option. Accept SSL connections that don't have a secure
+certificate chain to a trusted CA. Note that if you are going to monitor
+https targets, you'll probably have to either enable this option or specify
+the CA path to curl through extraargs below. For more info, see the
+curl(1) manual page.
+DOC
+ _example => 1,
+ },
+ extrare=> {
+ _doc => <<DOC,
+The regexp used to split the extraargs string into an argument list,
+in the "/regexp/" notation. This contains just the space character
+(" ") by default, but if you need to specify any arguments containing spaces,
+you can set this variable to a different value.
+DOC
+ _default => "/ /",
+ _example => "/ /",
+ _sub => sub {
+ my $val = shift;
+ return "extrare should be specified in the /regexp/ notation"
+ unless $val =~ m,^/.*/$,;
+ return undef;
+ },
+ },
+ extraargs => {
+ _doc => <<DOC,
+Any extra arguments you might want to hand to curl(1). The arguments
+should be separated by the regexp specified in "extrare", which
+contains just the space character (" ") by default.
+
+Note that curl will be called with the resulting list of arguments
+without any shell expansion. If you need to specify any arguments
+containing spaces, you should set "extrare" to something else.
+
+As a complicated example, to explicitly set the "Host:" header in Curl
+requests, you need to set "extrare" to something else, eg. "/;/",
+and then specify C<extraargs = --header;Host: www.example.com>.
+DOC
+ _example => "-6 --head --user user:password",
+ },
});
}
@@ -178,9 +220,22 @@ sub proto_args {
my @args = ("-o", "/dev/null", "-w", "Time: %{time_total} DNS time: %{time_namelookup}\\n");
my $ssl2 = $target->{vars}{ssl2};
push (@args, "-2") if defined($ssl2);
+ my $insecure_ssl = $target->{vars}{insecure_ssl};
+ push (@args, '-k') if defined $insecure_ssl;
+
return(@args);
}
+sub extra_args {
+ my $self = shift;
+ my $target = shift;
+ my $args = $target->{vars}{extraargs};
+ return () unless defined $args;
+ my $re = $target->{vars}{extrare};
+ ($re =~ m,^/(.*)/$,) and $re = qr{$1};
+ return split($re, $args);
+}
+
sub make_commandline {
my $self = shift;
my $target = shift;
@@ -191,6 +246,7 @@ sub make_commandline {
my $host = $target->{addr};
$url =~ s/%host%/$host/g;
push @args, $self->proto_args($target);
+ push @args, $self->extra_args($target);
return ($self->{properties}{binary}, @args, $url);
}
diff --git a/lib/Smokeping/probes/base.pm b/lib/Smokeping/probes/base.pm
index 8cc4def..c0525b6 100644
--- a/lib/Smokeping/probes/base.pm
+++ b/lib/Smokeping/probes/base.pm
@@ -42,12 +42,14 @@ sub pod {
my $class = shift;
my $pod = "";
my $podhash = $class->pod_hash;
- $podhash->{synopsys} = $class->pod_synopsys;
+ $podhash->{synopsis} = $class->pod_synopsis;
$podhash->{variables} = $class->pod_variables;
- for my $what (qw(name overview synopsys description variables authors notes bugs see_also)) {
+ for my $what (qw(name overview synopsis description variables authors notes bugs see_also)) {
my $contents = $podhash->{$what};
next if not defined $contents or $contents eq "";
- $pod .= "=head1 " . uc $what . "\n\n";
+ my $headline = uc $what;
+ $headline =~ s/_/ /; # see_also => SEE ALSO
+ $pod .= "=head1 $headline\n\n";
$pod .= $contents;
chomp $pod;
$pod .= "\n\n";
@@ -88,6 +90,23 @@ sub ProbeDesc ($) {
return "Probe which does not overrivd the ProbeDesc methode";
}
+sub target2dynfile ($$) {
+ # the targets are stored in the $self->{targets}
+ # hash as filenames pointing to the RRD files
+ #
+ # now that we use a (optionally) different dir for the
+ # . adr files, we need to derive the .adr filename
+ # from the RRD filename with a simple substitution
+
+ my $self = shift;
+ my $target = shift; # filename with <datadir> embedded
+ my $dyndir = $self->{cfg}{General}{dyndir};
+ return $target unless defined $dyndir; # nothing to do
+ my $datadir = $self->{cfg}{General}{datadir};
+ $target =~ s/^\Q$datadir\E/$dyndir/;
+ return $target;
+}
+
sub rrdupdate_string($$)
{ my $self = shift;
my $tree = shift;
@@ -105,17 +124,18 @@ sub rrdupdate_string($$)
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];
+ my $dynbase = $self->target2dynfile($self->{targets}{$tree});
+ if ( -f $dynbase.".adr" ) {
+ $age = time - (stat($dynbase.".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";
+ if ( -f $dynbase.".adr"
+ and not -f $dynbase.".snmp" ){
+ unlink $dynbase.".adr";
}
} ;
return "${age}:${loss}:${median}:".(join ":", @times);
@@ -129,12 +149,13 @@ sub addresses($)
foreach my $tree (keys %{$self->{targets}}){
my $target = $self->{targets}{$tree};
if ($target =~ m|/|) {
- if ( open D, "<$target.adr" ) {
+ my $dynbase = $self->target2dynfile($target);
+ if ( open D, "<$dynbase.adr" ) {
my $ip;
chomp($ip = <D>);
close D;
- if ( open D, "<$target.snmp" ) {
+ if ( open D, "<$dynbase.snmp" ) {
my $snmp = <D>;
chomp($snmp);
if ($snmp ne Smokeping::snmpget_ident $ip) {
@@ -316,7 +337,7 @@ sub _makevars {
return $to;
}
-sub pod_synopsys {
+sub pod_synopsis {
my $class = shift;
my $classname = ref $class||$class;
$classname =~ s/^Smokeping::probes:://;
@@ -329,8 +350,8 @@ sub pod_synopsys {
+$classname
DOC
- $pod .= $class->_pod_synopsys($probevars);
- my $targetpod = $class->_pod_synopsys($targetvars);
+ $pod .= $class->_pod_synopsis($probevars);
+ my $targetpod = $class->_pod_synopsis($targetvars);
$pod .= "\n # The following variables can be overridden in each target section\n$targetpod"
if defined $targetpod and $targetpod ne "";
$pod .= <<DOC;
@@ -353,8 +374,8 @@ DOC
return $pod;
}
-# synopsys for one hash ref
-sub _pod_synopsys {
+# synopsis for one hash ref
+sub _pod_synopsis {
my $class = shift;
my $vars = shift;
my %mandatory;
diff --git a/lib/Smokeping/probes/passwordchecker.pm b/lib/Smokeping/probes/passwordchecker.pm
index 7633eba..d1cc128 100644
--- a/lib/Smokeping/probes/passwordchecker.pm
+++ b/lib/Smokeping/probes/passwordchecker.pm
@@ -31,7 +31,7 @@ for storing passwords and a method for accessing them.
DOC
description => <<DOC,
-${e}head2 synopsys with more detail
+${e}head2 synopsis with more detail
SmokePing main configuration file: