each graph now has its own rrd file
[upsgraph] / upsgraph.pl
CommitLineData
e18c93b3
MG
1#!/usr/bin/perl -w
2
1c9fb9df
MG
3if ((@ARGV != 1) && (@ARGV != 2)) {
4 print STDERR "Syntax: ${0} configfile [uid]\n";
e18c93b3
MG
5 exit(1);
6}
7
1c9fb9df 8use Net::SNMP;
e5da3876
MG
9use RRDs;
10use Data::Dumper;
e18c93b3 11
1c9fb9df
MG
12$UPSGRAPH::host = "";
13$UPSGRAPH::rrdfile = "";
14$UPSGRAPH::outdir = "";
15$UPSGRAPH::community = "public";
16$UPSGRAPH::step = 60;
e5da3876 17$UPSGRAPH::keep = (370*24*60*60)/$UPSGRAPH::step;
1c9fb9df
MG
18@UPSGRAPH::fields = ();
19$UPSGRAPH::vars = {};
e18c93b3 20
1c9fb9df 21do $ARGV[0] or die "can't read config: $!";
e18c93b3 22
1c9fb9df
MG
23my $host = $UPSGRAPH::host;
24my $rrdfile = $UPSGRAPH::rrdfile;
25my $outdir = $UPSGRAPH::outdir;
26my $community = $UPSGRAPH::community;
27my $step = $UPSGRAPH::step;
e5da3876 28my $keep = $UPSGRAPH::keep;
1c9fb9df
MG
29my @fields = @UPSGRAPH::fields;
30my $vars = $UPSGRAPH::vars;
e18c93b3 31
e5da3876 32sub rrdcreate(@) {
21377f43
MG
33 my $newrrd = shift;
34 my $field = shift;
e5da3876
MG
35 my $start = shift;
36
21377f43 37 my @cmd = ("${newrrd}", "--step=${step}");
e5da3876
MG
38
39 if (defined($start)) {
40 push @cmd, "--start=${start}";
41 }
42
21377f43
MG
43 push @cmd, "DS:${field}:GAUGE:600:" .
44 $vars->{$field}->{'min'} . ":" .
45 $vars->{$field}->{'max'} . " ";
46
e5da3876
MG
47 push @cmd, "RRA:AVERAGE:0.5:1:${keep}";
48
49 RRDs::create(@cmd);
50 if (RRDs::error) {
51 print "Error while creating: " . RRDs::error . "\n";
52 exit 1;
53 }
54}
55
af4abf85 56if ($> == 0) {
1c9fb9df 57 if (@ARGV != 2) {
e5da3876 58 print STDERR "Running as root, please provide UID as 2th argument!\n";
af4abf85
MG
59 exit(1);
60 }
61
c6f0760e 62 print "Running as root, switching to ".$ARGV[1]."\n";
1c9fb9df 63 $< = $> = $ARGV[1];
af4abf85
MG
64}
65
21377f43
MG
66if (-e "${rrdfile}") {
67 print "Reading old ${rrdfile} to preserve data...\n";
e5da3876 68
21377f43
MG
69 my $rrdinfo = RRDs::info("${rrdfile}");
70 if (RRDs::error) {
71 print "Error while getting info: " . RRDs::error . "\n";
72 exit 1;
73 }
e5da3876
MG
74
75 (my $start, my $ostep, my $names, my $data) =
76 RRDs::fetch("${rrdfile}",
21377f43
MG
77 "-s " . (time() - ($rrdinfo->{'rra[0].rows'} * $rrdinfo->{'step'})),
78 "AVERAGE");
e5da3876
MG
79
80 if (RRDs::error) {
81 print "Error while fetching data: " . RRDs::error . "\n";
82 exit 1;
e18c93b3 83 }
e18c93b3 84
21377f43
MG
85 foreach my $field (@$names) {
86 if (! -e "${rrdfile}.${field}") {
87 rrdcreate("${rrdfile}.${field}","${field}",(${start}-${ostep}));
88 }
89 }
e5da3876
MG
90
91 my $pos = $start;
92 foreach my $line (@$data) {
21377f43
MG
93 foreach my $field (@$names) {
94 my $val = shift (@$line);
95 next if (!defined($val));
e5da3876 96
21377f43
MG
97 RRDs::update("${rrdfile}.${field}", "${pos}:${val}");
98 if (RRDs::error) {
99 print "Can't insert data: " . RRDs::error . "\n";
100 exit 1;
101 }
e5da3876 102
e5da3876 103 }
21377f43 104
e5da3876
MG
105 $pos += $ostep;
106
107 if ((($pos-$start)/$ostep) == $#$data) {
108 last;
109 }
110 }
111
112 rename("${rrdfile}", "${rrdfile}.old") or die "Can't rename old file: $!\n";
21377f43 113}
e5da3876 114
21377f43
MG
115foreach my $field (@fields) {
116 if (! -e "${rrdfile}.${field}") {
117 print "Creating ${rrdfile}.${field}...\n";
118 rrdcreate("${rrdfile}.${field}","${field}");
119 }
120
121 my $rrdinfo = RRDs::info("${rrdfile}.${field}");
e5da3876
MG
122 if (RRDs::error) {
123 print "Error while getting info: " . RRDs::error . "\n";
124 exit 1;
125 }
126
127 if ($rrdinfo->{'rra[0].rows'} != $keep) {
21377f43
MG
128 print "Resizing ${rrdfile}.${field} from " . $rrdinfo->{'rra[0].rows'} .
129 " to ${keep} samples.\n";
130
131 (my $start, my $ostep, my $names, my $data) =
132 RRDs::fetch("${rrdfile}.${field}",
133 "-s " . (time() - ($rrdinfo->{'rra[0].rows'} * $rrdinfo->{'step'})),
134 "AVERAGE");
135
136 if (RRDs::error) {
137 print "Error while fetching data: " . RRDs::error . "\n";
138 exit 1;
139 }
140
141 rrdcreate("${rrdfile}.${field}.new", "${field}", (${start}-${ostep}));
142
143 print "Preserving data since " . localtime($start) . "\n";
144
145 my $pos = $start;
146 foreach my $line (@$data) {
147 my $vline = "${pos}";
148
149 foreach my $val (@$line) {
150 $val = 'U' if (!defined($val));
151 $vline .= ":${val}";
152 }
153 RRDs::update("${rrdfile}.${field}.new", $vline) or die "Can't insert data\n";
154
155 if (RRDs::error) {
156 print "Error while updating: " . RRDs::error . "\n";
157 exit 1;
158 }
159 $pos += $ostep;
160
161 if ((($pos-$start)/$ostep) == $#$data) {
162 last;
163 }
164 }
165
166 rename("${rrdfile}.${field}", "${rrdfile}.${field}.old") or die "Can't rename old file: $!\n";
167 rename("${rrdfile}.${field}.new", "${rrdfile}.${field}") or die "Can't rename new file: $!\n";
168
169 $rrdinfo = RRDs::info("${rrdfile}.${field}");
170 if (RRDs::error) {
171 print "Error while getting info: " . RRDs::error . "\n";
172 exit 1;
173 }
174
175 if ($rrdinfo->{'rra[0].rows'} != $keep) {
176 print "Failed!\n";
177 exit 1;
178 }
e5da3876 179 }
e18c93b3
MG
180}
181
6aa53fc5
MG
182my $child = fork();
183
184die "fork failed!" if (!defined($child));
185
186exit 0 if ($child != 0);
187
e18c93b3
MG
188while(1) {
189 ($session,$error) = Net::SNMP->session(Hostname => $host,
190 Community => $community);
191
192 die "session error: $error" unless ($session);
193
194 $session->translate(0);
195
196 foreach my $var (@fields) {
197 delete $vars->{$var}->{'value'};
198
199 my $result = $session->get_request($vars->{$var}->{'oid'});
200 next unless (defined $result);
201
202 $vars->{$var}->{'value'} = $result->{$vars->{$var}->{'oid'}};
203 if (defined($vars->{$var}->{'factor'})) {
204 $vars->{$var}->{'value'} *= $vars->{$var}->{'factor'};
205 }
206 }
207
208 $session->close;
209
e18c93b3
MG
210 foreach my $var (@fields) {
211 if (!(defined($vars->{$var}->{'value'}))) {
212 $vars->{$var}->{'value'} = 'U';
213 }
21377f43 214 RRDs::update("${rrdfile}.${var}", "N:" . $vars->{$var}->{'value'});
e5da3876 215 }
e5da3876
MG
216 if (RRDs::error) {
217 print "Error while updating: " . RRDs::error . "\n";
e18c93b3 218 }
e18c93b3
MG
219
220 open(HTML, ">${outdir}/index.html.new");
221
222 print HTML '<html><head><meta http-equiv="refresh" content="60"/><meta http-equiv="cache-control" content="no-cache"/><meta http-equiv="pragma" content="no-cache"/><meta http_equiv="expires" content="Sat, 26 Jul 1997 05:00:00 GMT"/><title>USV status</title></head>';
223 print HTML '<body bgcolor="#ffffff">';
224
225 foreach my $var (@fields) {
21377f43 226 my @graphdef = ("-t", $vars->{$var}->{'name'}, "DEF:${var}=${rrdfile}.${var}:${var}:AVERAGE", "LINE1:${var}#FF0000");
e5da3876
MG
227 (my $averages, my $width, my $height) =
228 RRDs::graph("${outdir}/${var}.png.new",
229 "-w", "720", @graphdef);
230
231 if (RRDs::error) {
232 print "Error while graphing: " . RRDs::error . "\n";
233 } else {
234 rename("${outdir}/${var}.png.new", "${outdir}/${var}.png");
235 }
236
237 print HTML "<a href=\"${var}.html\"><img src=\"${var}.png\" width=\"${width}\" height=\"${height}\" border=\"0\"></a>";
238
239 open (HTML2, ">${outdir}/${var}.html.new");
240 print HTML2 "<html><head><title>" . $vars->{$var}->{'name'} . "</title></head>";
241 print HTML2 '<body bgcolor="#ffffff">';
242
243 ($averages, $width, $height) =
244 RRDs::graph("${outdir}/${var}.long.png.new",
245 "-w", "1008", @graphdef);
246
247 if (RRDs::error) {
248 print "Error while graphing: " . RRDs::error . "\n";
249 } else {
250 rename("${outdir}/${var}.long.png.new", "${outdir}/${var}.long.png");
251 }
252
253 print HTML2 "<img src=\"${var}.long.png\" width=\"${width}\" height=\"${height}\"><br>";
254
255 ($averages, $width, $height) =
256 RRDs::graph("${outdir}/${var}.week.png.new",
257 "-w", "1008", "-e", "now", "-s", "end-1w", @graphdef);
258
259 if (RRDs::error) {
260 print "Error while graphing: " . RRDs::error . "\n";
261 } else {
262 rename("${outdir}/${var}.week.png.new", "${outdir}/${var}.week.png");
263 }
264
265 print HTML2 "<img src=\"${var}.week.png\" width=\"${width}\" height=\"${height}\"><br>";
266
267 ($averages, $width, $height) =
268 RRDs::graph("${outdir}/${var}.year.png.new",
269 "-w", "1008", "-e", "now", "-s", "end-1y", @graphdef);
270
271 if (RRDs::error) {
272 print "Error while graphing: " . RRDs::error . "\n";
273 } else {
274 rename("${outdir}/${var}.year.png.new", "${outdir}/${var}.year.png");
275 }
e18c93b3 276
e5da3876 277 print HTML2 "<img src=\"${var}.year.png\" width=\"${width}\" height=\"${height}\"><br>";
e18c93b3 278
e5da3876
MG
279 print HTML2 "</body></html>\n";
280 close(HTML2);
281 rename("${outdir}/${var}.html.new", "${outdir}/${var}.html");
e18c93b3
MG
282 }
283
284 print HTML "</body></html>\n";
285 print HTML "<br>Generated on: " . localtime(time());
863e62dc 286 print HTML ' by <a href="http://git.zerfleddert.de/cgi-bin/gitweb.cgi/upsgraph">upsgraph</a>.';
e18c93b3
MG
287
288 close(HTML);
289
290 rename("${outdir}/index.html.new", "${outdir}/index.html");
291
292 sleep(${step}/2);
293}
Impressum, Datenschutz