From 2d8297b72b98005b7220c1ab47e9eeeb68711ac6 Mon Sep 17 00:00:00 2001 From: Niko Tyni Date: Sun, 20 Feb 2005 21:40:58 +0000 Subject: * check at startup that existing RRD files conform to the config specifications -- niko - new Smokeping::RRDtools module - note in CHANGES and smokeping_upgrade --- lib/Smokeping.pm | 10 ++- lib/Smokeping/RRDtools.pm | 169 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 lib/Smokeping/RRDtools.pm (limited to 'lib') diff --git a/lib/Smokeping.pm b/lib/Smokeping.pm index 65ac92b..82113a3 100644 --- a/lib/Smokeping.pm +++ b/lib/Smokeping.pm @@ -16,6 +16,7 @@ setlogsock('unix') if grep /^ $^O $/xo, ("linux", "openbsd", "freebsd", "netbsd"); use File::Basename; use Smokeping::Examples; +use Smokeping::RRDtools; # globale persistent variables for speedy use vars qw($cfg $probes $VERSION $havegetaddrinfo $cgimode); @@ -359,8 +360,7 @@ sub init_target_tree ($$$$) { } my $pings = $probeobj->_pings($tree); - if (not -f $name.".rrd"){ - my @create = + my @create = ($name.".rrd", "--step",$step, "DS:uptime:GAUGE:".(2*$step).":0:U", "DS:loss:GAUGE:".(2*$step).":0:".$pings, @@ -369,10 +369,16 @@ sub init_target_tree ($$$$) { (map { "DS:ping${_}:GAUGE:".(2*$step).":0:180" } 1..$pings), (map { "RRA:".(join ":", @{$_}) } @{$cfg->{Database}{_table}} )); + if (not -f $name.".rrd"){ do_debuglog("Calling RRDs::create(@create)"); RRDs::create(@create); my $ERROR = RRDs::error(); do_log "RRDs::create ERROR: $ERROR\n" if $ERROR; + } else { + shift @create; # remove the filename + my $comparison = Smokeping::RRDtools::compare($name.".rrd", \@create); + die("Error: RRD parameter mismatch ('$comparison'). You must delete $name.rrd or fix the configuration parameters.\n") + if $comparison; } } } diff --git a/lib/Smokeping/RRDtools.pm b/lib/Smokeping/RRDtools.pm new file mode 100644 index 0000000..7260cca --- /dev/null +++ b/lib/Smokeping/RRDtools.pm @@ -0,0 +1,169 @@ +package Smokeping::RRDtools; + +=head1 NAME + +Smokeping::RRDtools - Tools for RRD file handling + +=head1 SYNOPSYS + + use Smokeping::RRDtools; + use RRDs; + + my $file = '/path/to/file.rrd'; + + # get the create arguments that $file was created with + my $create = Smokeping::RRDtools::info2create($file); + + # use them to create a new file + RRDs::create('/path/to/file2.rrd', @$create); + + # or compare them against another create list + my @create = ('--step', 60, 'DS:ds0:GAUGE:120:0:U', 'RRA:AVERAGE:0.5:1:1008'); + my $comparison = Smokeping::RRDtools::compare($file, \@create); + print "Create arguments didn't match: $comparison\n" if $comparison; + +=head1 DESCRIPTION + +This module offers two functions, C and C. +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 function C must be called with one argument: +the path to the interesting RRD file. It will return an array +reference of the argument list that can be fed to C. +Note that this list will never contain the C parameter, +but it B contain the C parameter. + +The function C 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. The function will then simply compare +the result of C with this argument list. It will return +C if the arguments matched, and a string indicating the difference +if a discrepancy was found. Note that if there is a C parameter in +the argument list, C disregards it. If C isn't specified, +C will use the C default of 300 seconds. + +=head1 NOTES + +This module is not particularly specific to Smokeping, it is just +distributed with it. + +=head1 BUGS + +Probably. + +=head1 COPYRIGHT + +Copyright (c) 2005 by Niko Tyni. + +=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 SEE ALSO + +RRDs(3) + +=cut + +use strict; +use RRDs; + +# take an RRD file and make a create list out of it +sub info2create { + my $file = shift; + my @create; + 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'; + my $cf = $info->{"rra[0].cf"}; + die("$file: no RRAs found?") + unless defined $cf; + my @fetch = RRDs::fetch($file, $cf); + $error = RRDs::error; + die("RRDs::fetch $file $cf: ERROR: $error") if $error; + my @ds = @{$fetch[2]}; + + push @create, '--step', $info->{step}; + for my $ds (@ds) { + my @s = ("DS", $ds); + for (qw(type minimal_heartbeat min max)) { + die("$file: missing $_ for DS $ds?") + unless exists $info->{"ds[$ds].$_"}; + my $val = $info->{"ds[$ds].$_"}; + push @s, defined $val ? $val : "U"; + } + push @create, join(":", @s); + } + for (my $i=0; exists $info->{"rra[$i].cf"}; $i++) { + 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].$_"}; + push @s, $info->{"rra[$i].$_"}; + } + push @create, join(":", @s); + } + return \@create; +} + +sub compare { + my $file = shift; + my $create = shift; + my @create2 = @{info2create($file)}; + my @create = @$create; # copy because we change it + # we don't compare the '--start' param + if ($create[0] eq '--start') { + shift @create; + shift @create; + } + # special check for the optional 'step' parameter + die("Internal error: didn't get the step parameter from info2create?") + unless ("--step" eq shift @create2); + my $step = shift @create2; + my $step2; + if ($create[0] eq '--step') { + shift @create; + $step2 = shift @create; + } else { + $step2 = 300; # default value + } + return "Wrong value of step: $file has $step, create string has $step2" + unless $step == $step2; + + my $dscount = grep /^DS/, @create; + my $dscount2 = grep /^DS/, @create2; + return "Different number of data sources: $file has $dscount2, create string has $dscount" + unless $dscount == $dscount2; + my $rracount = grep /^RRA/, @create; + my $rracount2 = grep /^RRA/, @create2; + return "Different number of RRAs: $file has $rracount2, create string has $rracount" + unless $rracount == $rracount2; + + while (my $arg = shift @create) { + my $arg2 = shift @create2; + return "Different arguments: $file has $arg2, create string has $arg" + unless $arg eq $arg2; + } + return undef; +} + +1; -- cgit v1.2.3-24-g4f1b