use RRDs perl module, keep samples a year
[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
MG
32sub rrdcreate(@) {
33 my $rrdfile = shift;
34 my $start = shift;
35
36 my @cmd = ("${rrdfile}", "--step=${step}");
37
38 if (defined($start)) {
39 push @cmd, "--start=${start}";
40 }
41
42 foreach my $var (@fields) {
43 push @cmd, "DS:${var}:GAUGE:600:" .
44 $vars->{$var}->{'min'} . ":" .
45 $vars->{$var}->{'max'} . " ";
46 }
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
e18c93b3 66if (! -e "${rrdfile}") {
e5da3876
MG
67 print "Creating ${rrdfile}...\n";
68 rrdcreate("${rrdfile}");
69}
70
71my $rrdinfo = RRDs::info("${rrdfile}");
72if (RRDs::error) {
73 print "Error while getting info: " . RRDs::error . "\n";
74 exit 1;
75}
76
77if ($rrdinfo->{'rra[0].rows'} != $keep) {
78 print "Resizing ${rrdfile} from " . $rrdinfo->{'rra[0].rows'} .
79 " to ${keep} samples.\n";
80
81 (my $start, my $ostep, my $names, my $data) =
82 RRDs::fetch("${rrdfile}",
83 "-s " . (time() - ($rrdinfo->{'rra[0].rows'} * $rrdinfo->{'step'})),
84 "AVERAGE");
85
86 if (RRDs::error) {
87 print "Error while fetching data: " . RRDs::error . "\n";
88 exit 1;
e18c93b3 89 }
e18c93b3 90
e5da3876
MG
91 rrdcreate("${rrdfile}.new", (${start}-${ostep}));
92
93 print "Preserving data since " . localtime($start) . "\n";
94
95 my $pos = $start;
96 foreach my $line (@$data) {
97 my $vline = "${pos}";
98
99 foreach my $val (@$line) {
100 $val = 'U' if (!defined($val));
101 $vline .= ":${val}";
102 }
103 RRDs::update("${rrdfile}.new", $vline) or die "Can't insert data\n";
104
105 if (RRDs::error) {
106 print "Error while updating: " . RRDs::error . "\n";
107 exit 1;
108 }
109 $pos += $ostep;
110
111 if ((($pos-$start)/$ostep) == $#$data) {
112 last;
113 }
114 }
115
116 rename("${rrdfile}", "${rrdfile}.old") or die "Can't rename old file: $!\n";
117 rename("${rrdfile}.new", "${rrdfile}") or die "Can't rename new file: $!\n";
118
119 $rrdinfo = RRDs::info("${rrdfile}");
120 if (RRDs::error) {
121 print "Error while getting info: " . RRDs::error . "\n";
122 exit 1;
123 }
124
125 if ($rrdinfo->{'rra[0].rows'} != $keep) {
126 print "Failed!\n";
127 exit 1;
128 }
e18c93b3
MG
129}
130
6aa53fc5
MG
131my $child = fork();
132
133die "fork failed!" if (!defined($child));
134
135exit 0 if ($child != 0);
136
e18c93b3
MG
137while(1) {
138 ($session,$error) = Net::SNMP->session(Hostname => $host,
139 Community => $community);
140
141 die "session error: $error" unless ($session);
142
143 $session->translate(0);
144
145 foreach my $var (@fields) {
146 delete $vars->{$var}->{'value'};
147
148 my $result = $session->get_request($vars->{$var}->{'oid'});
149 next unless (defined $result);
150
151 $vars->{$var}->{'value'} = $result->{$vars->{$var}->{'oid'}};
152 if (defined($vars->{$var}->{'factor'})) {
153 $vars->{$var}->{'value'} *= $vars->{$var}->{'factor'};
154 }
155 }
156
157 $session->close;
158
e5da3876 159 my $vline = "N";
e18c93b3
MG
160 foreach my $var (@fields) {
161 if (!(defined($vars->{$var}->{'value'}))) {
162 $vars->{$var}->{'value'} = 'U';
163 }
e5da3876
MG
164 $vline .= ":" . $vars->{$var}->{'value'};
165 }
166 RRDs::update("${rrdfile}", $vline);
167 if (RRDs::error) {
168 print "Error while updating: " . RRDs::error . "\n";
e18c93b3 169 }
e18c93b3
MG
170
171 open(HTML, ">${outdir}/index.html.new");
172
173 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>';
174 print HTML '<body bgcolor="#ffffff">';
175
176 foreach my $var (@fields) {
e5da3876
MG
177 my @graphdef = ("-t", $vars->{$var}->{'name'}, "DEF:${var}=${rrdfile}:${var}:AVERAGE", "LINE1:${var}#FF0000");
178 (my $averages, my $width, my $height) =
179 RRDs::graph("${outdir}/${var}.png.new",
180 "-w", "720", @graphdef);
181
182 if (RRDs::error) {
183 print "Error while graphing: " . RRDs::error . "\n";
184 } else {
185 rename("${outdir}/${var}.png.new", "${outdir}/${var}.png");
186 }
187
188 print HTML "<a href=\"${var}.html\"><img src=\"${var}.png\" width=\"${width}\" height=\"${height}\" border=\"0\"></a>";
189
190 open (HTML2, ">${outdir}/${var}.html.new");
191 print HTML2 "<html><head><title>" . $vars->{$var}->{'name'} . "</title></head>";
192 print HTML2 '<body bgcolor="#ffffff">';
193
194 ($averages, $width, $height) =
195 RRDs::graph("${outdir}/${var}.long.png.new",
196 "-w", "1008", @graphdef);
197
198 if (RRDs::error) {
199 print "Error while graphing: " . RRDs::error . "\n";
200 } else {
201 rename("${outdir}/${var}.long.png.new", "${outdir}/${var}.long.png");
202 }
203
204 print HTML2 "<img src=\"${var}.long.png\" width=\"${width}\" height=\"${height}\"><br>";
205
206 ($averages, $width, $height) =
207 RRDs::graph("${outdir}/${var}.week.png.new",
208 "-w", "1008", "-e", "now", "-s", "end-1w", @graphdef);
209
210 if (RRDs::error) {
211 print "Error while graphing: " . RRDs::error . "\n";
212 } else {
213 rename("${outdir}/${var}.week.png.new", "${outdir}/${var}.week.png");
214 }
215
216 print HTML2 "<img src=\"${var}.week.png\" width=\"${width}\" height=\"${height}\"><br>";
217
218 ($averages, $width, $height) =
219 RRDs::graph("${outdir}/${var}.year.png.new",
220 "-w", "1008", "-e", "now", "-s", "end-1y", @graphdef);
221
222 if (RRDs::error) {
223 print "Error while graphing: " . RRDs::error . "\n";
224 } else {
225 rename("${outdir}/${var}.year.png.new", "${outdir}/${var}.year.png");
226 }
e18c93b3 227
e5da3876 228 print HTML2 "<img src=\"${var}.year.png\" width=\"${width}\" height=\"${height}\"><br>";
e18c93b3 229
e5da3876
MG
230 print HTML2 "</body></html>\n";
231 close(HTML2);
232 rename("${outdir}/${var}.html.new", "${outdir}/${var}.html");
e18c93b3
MG
233 }
234
235 print HTML "</body></html>\n";
236 print HTML "<br>Generated on: " . localtime(time());
863e62dc 237 print HTML ' by <a href="http://git.zerfleddert.de/cgi-bin/gitweb.cgi/upsgraph">upsgraph</a>.';
e18c93b3
MG
238
239 close(HTML);
240
241 rename("${outdir}/index.html.new", "${outdir}/index.html");
242
243 sleep(${step}/2);
244}
Impressum, Datenschutz