}
use Net::SNMP;
+use RRDs;
+use Data::Dumper;
$UPSGRAPH::host = "";
$UPSGRAPH::rrdfile = "";
$UPSGRAPH::outdir = "";
$UPSGRAPH::community = "public";
$UPSGRAPH::step = 60;
+$UPSGRAPH::keep = (370*24*60*60)/$UPSGRAPH::step;
@UPSGRAPH::fields = ();
$UPSGRAPH::vars = {};
my $outdir = $UPSGRAPH::outdir;
my $community = $UPSGRAPH::community;
my $step = $UPSGRAPH::step;
+my $keep = $UPSGRAPH::keep;
my @fields = @UPSGRAPH::fields;
my $vars = $UPSGRAPH::vars;
+sub rrdcreate(@) {
+ my $newrrd = shift;
+ my $field = shift;
+ my $start = shift;
+
+ my @cmd = ("${newrrd}", "--step=${step}");
+
+ if (defined($start)) {
+ push @cmd, "--start=${start}";
+ }
+
+ push @cmd, "DS:${field}:GAUGE:600:" .
+ $vars->{$field}->{'min'} . ":" .
+ $vars->{$field}->{'max'} . " ";
+
+ push @cmd, "RRA:AVERAGE:0.5:1:${keep}";
+
+ RRDs::create(@cmd);
+ if (RRDs::error) {
+ print "Error while creating: " . RRDs::error . "\n";
+ exit 1;
+ }
+}
+
if ($> == 0) {
if (@ARGV != 2) {
- print STDERR "Running as root, please provide UID as 4th argument!\n";
+ print STDERR "Running as root, please provide UID as 2th argument!\n";
exit(1);
}
- print "Running as root, switching to ".$ARGV[3]."\n";
+ print "Running as root, switching to ".$ARGV[1]."\n";
$< = $> = $ARGV[1];
}
-if (! -e "${rrdfile}") {
- my $cmd = "rrdtool create \"${rrdfile}\" ";
- foreach my $var (@fields) {
- $cmd .= "DS:${var}:GAUGE:600:" .
- $vars->{$var}->{'min'} . ":" .
- $vars->{$var}->{'max'} . " ";
+if (-e "${rrdfile}") {
+ print "Reading old ${rrdfile} to preserve data...\n";
+
+ my $rrdinfo = RRDs::info("${rrdfile}");
+ if (RRDs::error) {
+ print "Error while getting info: " . RRDs::error . "\n";
+ exit 1;
+ }
+
+ (my $start, my $ostep, my $names, my $data) =
+ RRDs::fetch("${rrdfile}",
+ "-s " . (time() - ($rrdinfo->{'rra[0].rows'} * $rrdinfo->{'step'})),
+ "AVERAGE");
+
+ if (RRDs::error) {
+ print "Error while fetching data: " . RRDs::error . "\n";
+ exit 1;
+ }
+
+ foreach my $field (@$names) {
+ if (! -e "${rrdfile}.${field}") {
+ rrdcreate("${rrdfile}.${field}","${field}",(${start}-${ostep}));
+ }
+ }
+
+ my $pos = $start;
+ foreach my $line (@$data) {
+ foreach my $field (@$names) {
+ my $val = shift (@$line);
+ next if (!defined($val));
+
+ RRDs::update("${rrdfile}.${field}", "${pos}:${val}");
+ if (RRDs::error) {
+ print "Can't insert data: " . RRDs::error . "\n";
+ exit 1;
+ }
+
+ }
+
+ $pos += $ostep;
+
+ if ((($pos-$start)/$ostep) == $#$data) {
+ last;
+ }
}
- $cmd .= "RRA:AVERAGE:0.5:1:10080 --step ${step}";
- print "Creating ${rrdfile}...\n";
- print `${cmd}`;
+ rename("${rrdfile}", "${rrdfile}.old") or die "Can't rename old file: $!\n";
+}
+
+foreach my $field (@fields) {
+ if (! -e "${rrdfile}.${field}") {
+ print "Creating ${rrdfile}.${field}...\n";
+ rrdcreate("${rrdfile}.${field}","${field}");
+ }
+
+ my $rrdinfo = RRDs::info("${rrdfile}.${field}");
+ if (RRDs::error) {
+ print "Error while getting info: " . RRDs::error . "\n";
+ exit 1;
+ }
+
+ if ($rrdinfo->{'rra[0].rows'} != $keep) {
+ print "Resizing ${rrdfile}.${field} from " . $rrdinfo->{'rra[0].rows'} .
+ " to ${keep} samples.\n";
+
+ (my $start, my $ostep, my $names, my $data) =
+ RRDs::fetch("${rrdfile}.${field}",
+ "-s " . (time() - ($rrdinfo->{'rra[0].rows'} * $rrdinfo->{'step'})),
+ "AVERAGE");
+
+ if (RRDs::error) {
+ print "Error while fetching data: " . RRDs::error . "\n";
+ exit 1;
+ }
+
+ rrdcreate("${rrdfile}.${field}.new", "${field}", (${start}-${ostep}));
+
+ print "Preserving data since " . localtime($start) . "\n";
+
+ my $pos = $start;
+ foreach my $line (@$data) {
+ my $vline = "${pos}";
+
+ foreach my $val (@$line) {
+ $val = 'U' if (!defined($val));
+ $vline .= ":${val}";
+ }
+ RRDs::update("${rrdfile}.${field}.new", $vline) or die "Can't insert data\n";
+
+ if (RRDs::error) {
+ print "Error while updating: " . RRDs::error . "\n";
+ exit 1;
+ }
+ $pos += $ostep;
+
+ if ((($pos-$start)/$ostep) == $#$data) {
+ last;
+ }
+ }
+
+ rename("${rrdfile}.${field}", "${rrdfile}.${field}.old") or die "Can't rename old file: $!\n";
+ rename("${rrdfile}.${field}.new", "${rrdfile}.${field}") or die "Can't rename new file: $!\n";
+
+ $rrdinfo = RRDs::info("${rrdfile}.${field}");
+ if (RRDs::error) {
+ print "Error while getting info: " . RRDs::error . "\n";
+ exit 1;
+ }
+
+ if ($rrdinfo->{'rra[0].rows'} != $keep) {
+ print "Failed!\n";
+ exit 1;
+ }
+ }
}
my $child = fork();
$session->close;
- my $cmd = "rrdtool update \"${rrdfile}\" \"N";
foreach my $var (@fields) {
if (!(defined($vars->{$var}->{'value'}))) {
$vars->{$var}->{'value'} = 'U';
}
- $cmd .= ":" . $vars->{$var}->{'value'};
+ RRDs::update("${rrdfile}.${var}", "N:" . $vars->{$var}->{'value'});
+ }
+ if (RRDs::error) {
+ print "Error while updating: " . RRDs::error . "\n";
}
- $cmd .= "\"";
- print `${cmd}`;
open(HTML, ">${outdir}/index.html.new");
print HTML '<body bgcolor="#ffffff">';
foreach my $var (@fields) {
- my $graphdef = "-t \"" . $vars->{$var}->{'name'} . "\" \"DEF:${var}=${rrdfile}:${var}:AVERAGE\" \"LINE1:${var}#FF0000\"";
- my $cmd = "rrdtool graph \"${outdir}/${var}.png.new\" -w 720 ${graphdef}";
- my $size = `$cmd`;
- rename("${outdir}/${var}.png.new", "${outdir}/${var}.png");
- (my $width, my $height) = split(/x/,$size);
+ my @graphdef = ("-t", $vars->{$var}->{'name'}, "DEF:${var}=${rrdfile}.${var}:${var}:AVERAGE", "LINE1:${var}#FF0000");
+ (my $averages, my $width, my $height) =
+ RRDs::graph("${outdir}/${var}.png.new",
+ "-w", "720", @graphdef);
+
+ if (RRDs::error) {
+ print "Error while graphing: " . RRDs::error . "\n";
+ } else {
+ rename("${outdir}/${var}.png.new", "${outdir}/${var}.png");
+ }
+
+ print HTML "<a href=\"${var}.html\"><img src=\"${var}.png\" width=\"${width}\" height=\"${height}\" border=\"0\"></a>";
+
+ open (HTML2, ">${outdir}/${var}.html.new");
+ print HTML2 "<html><head><title>" . $vars->{$var}->{'name'} . "</title></head>";
+ print HTML2 '<body bgcolor="#ffffff">';
+
+ ($averages, $width, $height) =
+ RRDs::graph("${outdir}/${var}.long.png.new",
+ "-w", "1008", @graphdef);
+
+ if (RRDs::error) {
+ print "Error while graphing: " . RRDs::error . "\n";
+ } else {
+ rename("${outdir}/${var}.long.png.new", "${outdir}/${var}.long.png");
+ }
+
+ print HTML2 "<img src=\"${var}.long.png\" width=\"${width}\" height=\"${height}\"><br>";
+
+ ($averages, $width, $height) =
+ RRDs::graph("${outdir}/${var}.week.png.new",
+ "-w", "1008", "-e", "now", "-s", "end-1w", @graphdef);
+
+ if (RRDs::error) {
+ print "Error while graphing: " . RRDs::error . "\n";
+ } else {
+ rename("${outdir}/${var}.week.png.new", "${outdir}/${var}.week.png");
+ }
+
+ print HTML2 "<img src=\"${var}.week.png\" width=\"${width}\" height=\"${height}\"><br>";
+
+ ($averages, $width, $height) =
+ RRDs::graph("${outdir}/${var}.year.png.new",
+ "-w", "1008", "-e", "now", "-s", "end-1y", @graphdef);
+
+ if (RRDs::error) {
+ print "Error while graphing: " . RRDs::error . "\n";
+ } else {
+ rename("${outdir}/${var}.year.png.new", "${outdir}/${var}.year.png");
+ }
- my $cmd2 = "rrdtool graph \"${outdir}/${var}.long.png.new\" -w 1008 -e now -s end-1w ${graphdef}";
- my $size2 = `$cmd2`;
- rename("${outdir}/${var}.long.png.new", "${outdir}/${var}.long.png");
+ print HTML2 "<img src=\"${var}.year.png\" width=\"${width}\" height=\"${height}\"><br>";
- print HTML "<a href=\"${var}.long.png\"><img src=\"${var}.png\" width=\"${width}\" height=\"${height}\" border=\"0\"></a>";
+ print HTML2 "</body></html>\n";
+ close(HTML2);
+ rename("${outdir}/${var}.html.new", "${outdir}/${var}.html");
}
print HTML "</body></html>\n";