#!/usr/bin/perl -w
+#Due to memory leak in Debian squeeze (Bug #545519)
+my $use_rrds = 0;
+my $rrd_result = 0;
+
if ((@ARGV != 1) && (@ARGV != 2)) {
print STDERR "Syntax: ${0} configfile [uid]\n";
exit(1);
use Net::SNMP;
use IO::Socket::INET;
use RRDs;
+use File::Copy;
use Data::Dumper;
$UPSGRAPH::outdir = "";
my $keep = $UPSGRAPH::keep;
my $hosts = $UPSGRAPH::hosts;
+sub rrd_update(@) {
+ my @args = @_;
+
+ if ($use_rrds == 1) {
+ RRDs::update(@args);
+ $rrd_result = RRDs::error;
+ } else {
+ $rrd_result = system("rrdtool", "update", @args);
+ }
+}
+
+sub rrd_graph(@) {
+ my @args = @_;
+ my @rrd_out = ();
+
+ if ($use_rrds == 1) {
+ @rrd_out = RRDs::graph(@args);
+ $rrd_result = RRDs::error;
+ } else {
+ my $rrd_stdout;
+
+ open(RRDFD, '-|', 'rrdtool', 'graph', @args);
+ while(<RRDFD>) {
+ chomp;
+ $rrd_stdout = $_;
+ }
+ close(RRDFD);
+ $rrd_result = $?;
+ if ($rrd_result == 0) {
+ push @rrd_out, 0;
+ push @rrd_out, split(/x/, $rrd_stdout);
+ }
+ }
+
+ return @rrd_out;
+}
+
sub rrdcreate(@) {
my $newrrd = shift;
my $field = shift;
if (!$session) {
print STDERR "session error: $error";
+ return undef;
}
$session->translate(0);
$value;
}
+sub fetch_tcp_multi(@) {
+ my $address = shift;
+ my $port = shift;
+ my $delimiter = shift;
+ my %values;
+
+ my $sock = IO::Socket::INET->new(PeerAddr => $address,
+ PeerPort => $port,
+ Proto => 'tcp',
+ Timeout => 1);
+
+ return undef if (!$sock);
+
+ while(<$sock>) {
+ chomp;
+ (my $key, my $value) = split(/${delimiter}/, $_);
+ $value=~ s/\s//g;
+ $values{$key} = $value;
+ }
+
+ close($sock);
+
+ %values;
+}
+
if ($> == 0) {
if (@ARGV != 2) {
print STDERR "Running as root, please provide UID as 2th argument!\n";
foreach my $host (@$hosts) {
my $rrdfile = $host->{'rrdfile'};
+ foreach my $var (keys(%{$host->{'vars'}})) {
+ $host->{'vars'}->{$var}->{'min'} = 'U' if (!defined($host->{'vars'}->{$var}->{'min'}));
+ $host->{'vars'}->{$var}->{'max'} = 'U' if (!defined($host->{'vars'}->{$var}->{'max'}));
+ }
+
if (-e "${rrdfile}") {
print "Reading old ${rrdfile} to preserve data...\n";
exit 1;
}
+ if (defined($rrdinfo->{"ds[${field}].min"})) {
+ if ($rrdinfo->{"ds[${field}].min"} ne $host->{'vars'}->{$field}->{'min'}) {
+ RRDs::tune("${rrdfile}.${field}","-i",$field.":".$host->{'vars'}->{$field}->{'min'});
+ }
+ } else {
+ if ($host->{'vars'}->{$field}->{'min'} ne 'U') {
+ RRDs::tune("${rrdfile}.${field}","-i",$field.":".$host->{'vars'}->{$field}->{'min'});
+ }
+ }
+
+ if (RRDs::error) {
+ print "Error while setting min: " . RRDs::error . "\n";
+ exit 1;
+ }
+
+ if (defined($rrdinfo->{"ds[${field}].max"})) {
+ if ($rrdinfo->{"ds[${field}].max"} ne $host->{'vars'}->{$field}->{'max'}) {
+ RRDs::tune("${rrdfile}.${field}","-a",$field.":".$host->{'vars'}->{$field}->{'max'});
+ }
+ } else {
+ if ($host->{'vars'}->{$field}->{'max'} ne 'U') {
+ RRDs::tune("${rrdfile}.${field}","-a",$field.":".$host->{'vars'}->{$field}->{'max'});
+ }
+ }
+
+ if (RRDs::error) {
+ print "Error while setting max: " . RRDs::error . "\n";
+ exit 1;
+ }
+
if ($rrdinfo->{'rra[0].rows'} != $keep) {
print "Resizing ${rrdfile}.${field} from " . $rrdinfo->{'rra[0].rows'} .
" to ${keep} samples.\n";
while(1) {
open(HTML, ">${outdir}/index.html.new");
- 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>';
+ 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>Status</title></head>';
print HTML '<body bgcolor="#ffffff">';
foreach my $host (@$hosts) {
+ print HTML "[<a href=\"#".${host}->{'name'}."\">".${host}->{'name'}."</a>] ";
+ }
+ print HTML "<br>\n";
+
+ foreach my $host (@$hosts) {
+ print HTML "<br>\n";
+ print HTML "<a name=\"".${host}->{'name'}."\"></a>\n";
my $vars = $host->{'vars'};
my $rrdfile = $host->{'rrdfile'};
my $hostname = $host->{'name'};
+ my %multi_values = ();
foreach my $var (@{$host->{'fields'}}) {
delete $vars->{$var}->{'value'};
$result = fetch_snmp($host->{'address'}, $host->{'community'}, $vars->{$var}->{'oid'});
} elsif ($vars->{$var}->{'proto'} eq 'tcp') {
$result = fetch_tcp($host->{'address'}, $vars->{$var}->{'port'});
+ } elsif ($vars->{$var}->{'proto'} eq 'tcp_multi') {
+ if (defined($multi_values{$vars->{$var}->{'multi_id'}})) {
+ $result = $multi_values{$vars->{$var}->{'multi_id'}}
+ } else {
+ my %values = fetch_tcp_multi($host->{'address'}, $vars->{$var}->{'port'}, $vars->{$var}->{'multi_delimiter'});
+ @multi_values{keys %values} = values %values;
+ $result = $multi_values{$vars->{$var}->{'multi_id'}};
+ }
}
next unless (defined $result);
if (!(defined($vars->{$var}->{'value'}))) {
$vars->{$var}->{'value'} = 'U';
}
- RRDs::update("${rrdfile}.${var}", "N:" . $vars->{$var}->{'value'});
+ rrd_update("${rrdfile}.${var}", "N:" . $vars->{$var}->{'value'});
}
- if (RRDs::error) {
- print "Error while updating: " . RRDs::error . "\n";
+ if ($rrd_result) {
+ print "Error while updating: " . $rrd_result . "\n";
}
foreach my $var (@{$host->{'fields'}}) {
- my @graphdef = ("-t", $hostname." - ".$vars->{$var}->{'name'}, "DEF:${var}=${rrdfile}.${var}:${var}:AVERAGE", "LINE1:${var}#FF0000");
+ my @graphdef = ('-P', "--lazy", "-t", $hostname." - ".$vars->{$var}->{'name'}, "DEF:${var}=${rrdfile}.${var}:${var}:AVERAGE", "LINE1:${var}#FF0000");
+
+ push @graphdef, "VDEF:cur=${var},LAST";
+ push @graphdef, 'GPRINT:cur:Current\\: <span foreground="#FF0000">%.2lf</span>\\r';
+
+ my $mtime;
+ $mtime=(stat("${outdir}/${hostname}.${var}.png.work"))[9];
+
(my $averages, my $width, my $height) =
- RRDs::graph("${outdir}/${hostname}.${var}.png.new",
+ rrd_graph("${outdir}/${hostname}.${var}.png.work",
"-w", "720", @graphdef);
- if (RRDs::error) {
- print "Error while graphing: " . RRDs::error . "\n";
+ pop @graphdef;
+ pop @graphdef;
+
+ if ($rrd_result) {
+ print "Error while graphing: " . $rrd_result . "\n";
} else {
- rename("${outdir}/${hostname}.${var}.png.new", "${outdir}/${hostname}.${var}.png");
+ my $newmtime=(stat("${outdir}/${hostname}.${var}.png.work"))[9];
+ if ((!defined($mtime)) || ($newmtime != $mtime)) {
+ copy("${outdir}/${hostname}.${var}.png.work", "${outdir}/${hostname}.${var}.png.new");
+ rename("${outdir}/${hostname}.${var}.png.new", "${outdir}/${hostname}.${var}.png");
+ }
}
- print HTML "<a href=\"${hostname}.${var}.html\"><img src=\"${hostname}.${var}.png\" width=\"${width}\" height=\"${height}\" border=\"0\"></a>";
+ print HTML "<a href=\"${hostname}.${var}.html\"><img src=\"${hostname}.${var}.png\" width=\"${width}\" height=\"${height}\" border=\"0\"></a><br>\n";
open (HTML2, ">${outdir}/${hostname}.${var}.html.new");
- print HTML2 "<html><head><title>" . $vars->{$var}->{'name'} . "</title></head>";
+ print HTML2 '<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>' . $vars->{$var}->{'name'} . '</title></head>';
print HTML2 '<body bgcolor="#ffffff">';
-
push @graphdef, "VDEF:min=${var},MINIMUM";
push @graphdef, "GPRINT:min:Minimum\\: %.2lf";
push @graphdef, "VDEF:cur=${var},LAST";
push @graphdef, "GPRINT:cur:Current\\: %.2lf";
+ $mtime=(stat("${outdir}/${hostname}.${var}.long.png.work"))[9];
($averages, $width, $height) =
- RRDs::graph("${outdir}/${hostname}.${var}.long.png.new",
+ rrd_graph("${outdir}/${hostname}.${var}.long.png.work",
"-w", "1008", @graphdef);
- if (RRDs::error) {
- print "Error while graphing: " . RRDs::error . "\n";
+ if ($rrd_result) {
+ print "Error while graphing: " . $rrd_result . "\n";
} else {
- rename("${outdir}/${hostname}.${var}.long.png.new", "${outdir}/${hostname}.${var}.long.png");
+ my $newmtime=(stat("${outdir}/${hostname}.${var}.long.png.work"))[9];
+ if ((!defined($mtime)) || ($newmtime != $mtime)) {
+ copy("${outdir}/${hostname}.${var}.long.png.work", "${outdir}/${hostname}.${var}.long.png.new");
+ rename("${outdir}/${hostname}.${var}.long.png.new", "${outdir}/${hostname}.${var}.long.png");
+ }
}
print HTML2 "<img src=\"${hostname}.${var}.long.png\" width=\"${width}\" height=\"${height}\"><br>";
+ $mtime=(stat("${outdir}/${hostname}.${var}.week.png.work"))[9];
($averages, $width, $height) =
- RRDs::graph("${outdir}/${hostname}.${var}.week.png.new",
+ rrd_graph("${outdir}/${hostname}.${var}.week.png.work",
"-w", "1008", "-e", "now", "-s", "end-1w", @graphdef);
- if (RRDs::error) {
- print "Error while graphing: " . RRDs::error . "\n";
+ if ($rrd_result) {
+ print "Error while graphing: " . $rrd_result . "\n";
} else {
- rename("${outdir}/${hostname}.${var}.week.png.new", "${outdir}/${hostname}.${var}.week.png");
+ my $newmtime=(stat("${outdir}/${hostname}.${var}.week.png.work"))[9];
+ if ((!defined($mtime)) || ($newmtime != $mtime)) {
+ copy("${outdir}/${hostname}.${var}.week.png.work", "${outdir}/${hostname}.${var}.week.png.new");
+ rename("${outdir}/${hostname}.${var}.week.png.new", "${outdir}/${hostname}.${var}.week.png");
+ }
}
print HTML2 "<img src=\"${hostname}.${var}.week.png\" width=\"${width}\" height=\"${height}\"><br>";
+ $mtime=(stat("${outdir}/${hostname}.${var}.year.png.work"))[9];
($averages, $width, $height) =
- RRDs::graph("${outdir}/${hostname}.${var}.year.png.new",
+ rrd_graph("${outdir}/${hostname}.${var}.year.png.work",
"-w", "1008", "-e", "now", "-s", "end-1y", @graphdef);
- if (RRDs::error) {
- print "Error while graphing: " . RRDs::error . "\n";
+ if ($rrd_result) {
+ print "Error while graphing: " . $rrd_result . "\n";
} else {
- rename("${outdir}/${hostname}.${var}.year.png.new", "${outdir}/${hostname}.${var}.year.png");
+ my $newmtime=(stat("${outdir}/${hostname}.${var}.year.png.work"))[9];
+ if ((!defined($mtime)) || ($newmtime != $mtime)) {
+ copy("${outdir}/${hostname}.${var}.year.png.work", "${outdir}/${hostname}.${var}.year.png.new");
+ rename("${outdir}/${hostname}.${var}.year.png.new", "${outdir}/${hostname}.${var}.year.png");
+ }
}
print HTML2 "<img src=\"${hostname}.${var}.year.png\" width=\"${width}\" height=\"${height}\"><br>";