~ubuntu-branches/debian/lenny/smokeping/lenny

« back to all changes in this revision

Viewing changes to lib/Smokeping/RRDtools.pm

  • Committer: Bazaar Package Importer
  • Author(s): Niko Tyni
  • Date: 2006-10-26 21:45:56 UTC
  • mfrom: (1.2.2 upstream) (2.1.5 edgy)
  • Revision ID: james.westby@ubuntu.com-20061026214556-5jnpiesx4vdijmu6
* debian/patches/15_clean_makefile.dpatch:
  + remove unneeded and potentially unsecure include paths.
* debian/patches: selected patches from the upstream SVN repository
  + 40_password.dpatch: skip reading the password file when running as a CGI.
  + 50_ldap.dpatch: Make the 'scope' option in the LDAP probe actually work.
  + 60_fping.dpatch:
    * Support the '-S' (set source address, see #198486) fping option.
    * Don't try to execute fping when running as a CGI.
  + 70_syslog.dpatch: Don't die silently if syslogd is unavailable.
    (Closes: #395056)
* Remove all the autogenerated documentation at clean time, to properly
  undo the effects of the 'build' target.
* Install example configuration files for documentation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package Smokeping::RRDtools;
 
2
 
 
3
=head1 NAME
 
4
 
 
5
Smokeping::RRDtools - Tools for RRD file handling
 
6
 
 
7
=head1 SYNOPSIS
 
8
 
 
9
 use Smokeping::RRDtools;
 
10
 use RRDs;
 
11
 
 
12
 my $file = '/path/to/file.rrd';
 
13
 
 
14
 # get the create arguments that $file was created with
 
15
 my $create = Smokeping::RRDtools::info2create($file);
 
16
 
 
17
 # use them to create a new file
 
18
 RRDs::create('/path/to/file2.rrd', @$create);
 
19
 
 
20
 # or compare them against another create list
 
21
 my @create = ('--step', 60, 'DS:ds0:GAUGE:120:0:U', 'RRA:AVERAGE:0.5:1:1008');
 
22
 my ($fatal, $comparison) = Smokeping::RRDtools::compare($file, \@create);
 
23
 print "Fatal: " if $fatal;
 
24
 print "Create arguments didn't match: $comparison\n" if $comparison;
 
25
 
 
26
 Smokeping::RRDtools::tuneds($file, \@create);
 
27
 
 
28
=head1 DESCRIPTION
 
29
 
 
30
This module offers three functions, C<info2create>, C<compare> and
 
31
C<tuneds>. The first can be used to recreate the arguments that an RRD file
 
32
was created with. The second checks if an RRD file was created with the
 
33
given arguments. The thirds tunes the DS parameters according to the
 
34
supplied create string.
 
35
 
 
36
The function C<info2create> must be called with one argument:
 
37
the path to the interesting RRD file. It will return an array
 
38
reference of the argument list that can be fed to C<RRDs::create>.
 
39
Note that this list will never contain the C<start> parameter,
 
40
but it B<will> contain the C<step> parameter.
 
41
 
 
42
The function C<compare> must be called with two arguments: the path to the
 
43
interesting RRD file, and a reference to an argument list that could be fed
 
44
to C<RRDs::create>. The function will then simply compare the result of
 
45
C<info2create> with this argument list. It will return an array of two values:
 
46
C<(fatal, text)> where  C<fatal> is 1 if it found a fatal difference, and 0 if not.
 
47
The C<text> will contain an error message if C<fatal == 1> and a possible warning 
 
48
message if C<fatal == 0>. If C<fatal == 0> and C<text> is C<undef>, all the
 
49
arguments matched.
 
50
 
 
51
Note that if there is a C<start> parameter in the argument list,
 
52
C<compare> disregards it. If C<step> isn't specified, C<compare> will use
 
53
the C<rrdtool> default of 300 seconds. C<compare> ignores non-matching DS
 
54
parameters since C<tuneds> will fix them.
 
55
 
 
56
C<tuneds> talks on stderr about the parameters it fixes.
 
57
 
 
58
=head1 NOTES
 
59
 
 
60
This module is not particularly specific to Smokeping, it is just
 
61
distributed with it.
 
62
 
 
63
=head1 BUGS
 
64
 
 
65
Probably.
 
66
 
 
67
=head1 COPYRIGHT
 
68
 
 
69
Copyright (c) 2005 by Niko Tyni.
 
70
 
 
71
=head1 AUTHOR
 
72
 
 
73
Niko Tyni <ntyni@iki.fi>
 
74
 
 
75
=head1 LICENSE
 
76
 
 
77
This program is free software; you can redistribute it
 
78
and/or modify it under the terms of the GNU General Public
 
79
License as published by the Free Software Foundation; either
 
80
version 2 of the License, or (at your option) any later
 
81
version.
 
82
 
 
83
This program is distributed in the hope that it will be
 
84
useful, but WITHOUT ANY WARRANTY; without even the implied
 
85
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 
86
PURPOSE.  See the GNU General Public License for more
 
87
details.
 
88
 
 
89
You should have received a copy of the GNU General Public
 
90
License along with this program; if not, write to the Free
 
91
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
 
92
02139, USA.
 
93
 
 
94
=head1 SEE ALSO
 
95
 
 
96
RRDs(3)
 
97
 
 
98
=cut
 
99
 
 
100
use strict;
 
101
use RRDs;
 
102
 
 
103
# take an RRD file and make a create list out of it
 
104
sub info2create {
 
105
        my $file = shift;
 
106
        my @create;
 
107
 
 
108
        # check for Perl version 5.8.0, it's buggy
 
109
        # no more v-strings 
 
110
        my $buggy_perl_version = 1 if abs($] - 5.008000) < .0000005;
 
111
 
 
112
        my $info = RRDs::info($file);
 
113
        my $error = RRDs::error;
 
114
        die("RRDs::info $file: ERROR: $error") if $error;
 
115
        die("$file: unknown RRD version: $info->{rrd_version}")
 
116
                unless $info->{rrd_version} eq '0001'
 
117
                or     $info->{rrd_version} eq '0003';
 
118
        my $cf = $info->{"rra[0].cf"};
 
119
        die("$file: no RRAs found?") 
 
120
                unless defined $cf;
 
121
        my @fetch = RRDs::fetch($file, $cf);
 
122
        $error = RRDs::error;
 
123
        die("RRDs::fetch $file $cf: ERROR: $error") if $error;
 
124
        my @ds = @{$fetch[2]};
 
125
 
 
126
        push @create, '--step', $info->{step};
 
127
        for my $ds (@ds) {
 
128
                my @s = ("DS", $ds);
 
129
                for (qw(type minimal_heartbeat min max)) {
 
130
                        die("$file: missing $_ for DS $ds?")
 
131
                                unless exists $info->{"ds[$ds].$_"}
 
132
                or $buggy_perl_version;
 
133
                        my $val = $info->{"ds[$ds].$_"};
 
134
                        push @s, defined $val ? $val : "U";
 
135
                }
 
136
                push @create, join(":", @s);
 
137
        }
 
138
        for (my $i=0; exists $info->{"rra[$i].cf"}; $i++) {
 
139
                my @s = ("RRA", $info->{"rra[$i].cf"});
 
140
                for (qw(xff pdp_per_row rows)) {
 
141
                        die("$file: missing $_ for RRA $i")
 
142
                                unless exists $info->{"rra[$i].$_"}
 
143
                or $buggy_perl_version;
 
144
                        push @s, $info->{"rra[$i].$_"};
 
145
                }
 
146
                push @create, join(":", @s);
 
147
        }
 
148
        return \@create;
 
149
}
 
150
 
 
151
sub compare {
 
152
        my $file = shift;
 
153
        my $create = shift;
 
154
        my @create2 = @{info2create($file)};
 
155
        my @create = @$create; # copy because we change it
 
156
        # we don't compare the '--start' param
 
157
        if ($create[0] eq '--start') {
 
158
                shift @create;
 
159
                shift @create;
 
160
        }
 
161
        # special check for the optional 'step' parameter
 
162
        die("Internal error: didn't get the step parameter from info2create?")
 
163
                unless ("--step" eq shift @create2);
 
164
        my $step = shift @create2;
 
165
        my $step2;
 
166
        if ($create[0] eq '--step') {
 
167
                shift @create;
 
168
                $step2 = shift @create;
 
169
        } else {
 
170
                $step2 = 300; # default value
 
171
        }
 
172
        return (1, "Wrong value of step: $file has $step, create string has $step2")
 
173
                unless $step == $step2;
 
174
        
 
175
        my $dscount = grep /^DS/, @create;
 
176
        my $dscount2 = grep /^DS/, @create2;
 
177
        return (1, "Different number of data sources: $file has $dscount2, create string has $dscount")
 
178
                unless $dscount == $dscount2;
 
179
        my $rracount = grep /^RRA/, @create;
 
180
        my $rracount2 = grep /^RRA/, @create2;
 
181
        return (1, "Different number of RRAs: $file has $rracount2, create string has $rracount")
 
182
                unless $rracount == $rracount2;
 
183
 
 
184
        my $warning;
 
185
        while (my $arg = shift @create) {
 
186
                my $arg2 = shift @create2;
 
187
                my @ds = split /:/, $arg;
 
188
                my @ds2 = split /:/, $arg2;
 
189
                next if $ds[0] eq 'DS' and $ds[0] eq $ds2[0] and $ds[1] eq $ds2[1] and $ds[2] eq $ds2[2];
 
190
                if ($arg ne $arg2) {
 
191
                        if ($ds[0] eq 'RRA' and $ds[0] eq $ds2[0] and $ds[1] eq $ds2[1]) {
 
192
                                # non-fatal: CF is the same, but xff/steps/rows differ
 
193
                                $warning .= "Different RRA parameters: $file has $arg2, create string has $arg";
 
194
                        } else {
 
195
                                return (1, "Different arguments: $file has $arg2, create string has $arg");
 
196
                        }
 
197
                }
 
198
        }
 
199
        return (0, $warning);
 
200
}
 
201
 
 
202
sub tuneds {
 
203
        my $file = shift;
 
204
        my $create = shift;
 
205
        my @create2 = sort grep /^DS/, @{info2create($file)};
 
206
        my @create = sort grep /^DS/,  @$create;
 
207
        while (@create){
 
208
               my @ds = split /:/, shift @create;
 
209
               my @ds2 = split /:/, shift @create2;
 
210
               next unless $ds[1] eq $ds2[1] and $ds[2] eq $ds[2];
 
211
               if ($ds[3] ne $ds2[3]){
 
212
                        warn "## Updating $file DS:$ds[1] heartbeat $ds2[3] -> $ds[3]\n";
 
213
                        RRDs::tune $file,"--hearbeat","$ds[1]:$ds[3]" unless $ds[3] eq $ds2[3];
 
214
               }
 
215
               if ($ds[4] ne $ds2[4]){
 
216
                        warn "## Updating $file DS:$ds[1] minimum $ds2[4] -> $ds[4]\n";
 
217
                        RRDs::tune $file,"--minimum","$ds[1]:$ds[4]" unless $ds[4] eq $ds2[4];
 
218
               }
 
219
               if ($ds[5] ne $ds2[5]){
 
220
                        warn "## Updating $file DS:$ds[1] maximum $ds2[5] -> $ds[5]\n";
 
221
                        RRDs::tune $file,"--maximum","$ds[1]:$ds[5]" unless $ds[5] eq $ds2[5];
 
222
               }
 
223
        }
 
224
}       
 
225
                                        
 
226
1;