added new DSs to 'fs' graph mainly to include support to collect inode usage

This commit is contained in:
Jordi Sanfeliu 2014-02-28 13:13:53 +01:00
parent 789b84433b
commit f81aed0f0e
1 changed files with 178 additions and 3 deletions

181
lib/fs.pm
View File

@ -29,6 +29,120 @@ use File::Basename;
use Exporter 'import';
our @EXPORT = qw(fs_init fs_update fs_cgi);
#
# Some ideas of this upgrading function have been taken from a script written
# by Joost Cassee and found in the RRDtool Contrib Area:
# <http://oss.oetiker.ch/rrdtool/pub/contrib/>
#
sub upgrade_to_350 {
my $myself = (caller(0))[3];
my $rrd = shift;
my $ds = 0;
my $cdp = 0;
my $end_tim = 0;
my $str = "";
logger("$myself: Adding new 'ino' plus 1 extra DS to '$rrd'.");
logger("$myself: $!") if !(open(IN, "rrdtool dump $rrd |"));
logger("$myself: $!") if !(open(OUT, "| rrdtool restore - $rrd.new"));
while(<IN>) {
$ds = 1 if /<!-- Round Robin Database Dump -->/;
$ds = 0 if /<!-- Round Robin Archives -->/;
$cdp = 1 if /<cdp_prep>/;
$cdp = 0 if /<\/cdp_prep>/;
if($ds) {
if(/<name> fs(\d+)_use(\d+) <\/name>/) {
$str = "fs$1" . "_tim$2";
}
$end_tim = 1 if /<name> $str <\/name>/;
if($end_tim) {
if(/<\/ds>/) {
$str =~ s/tim/ino/;
print OUT $_;
print OUT "\n";
print OUT <<EOF;
<ds>
<name> $str </name>
<type> GAUGE </type>
<minimal_heartbeat> 120 </minimal_heartbeat>
<min> 0.0000000000e+00 </min>
<max> 100 </max>
<!-- PDP Status -->
<last_ds> UNKN </last_ds>
<value> 0.0000000000e+00 </value>
<unknown_sec> 0 </unknown_sec>
</ds>
EOF
$str =~ s/ino/val/;
print OUT "\n";
print OUT <<EOF;
<ds>
<name> $str </name>
<type> GAUGE </type>
<minimal_heartbeat> 120 </minimal_heartbeat>
<min> 0.0000000000e+00 </min>
<max> NaN </max>
<!-- PDP Status -->
<last_ds> UNKN </last_ds>
<value> 0.0000000000e+00 </value>
<unknown_sec> 0 </unknown_sec>
</ds>
EOF
$end_tim = 0;
next;
}
}
}
if($cdp) {
if(/<\/ds>/) {
if(!($cdp % 3)) {
print OUT $_;
print OUT <<EOF;
<ds>
<primary_value> 0.0000000000e+00 </primary_value>
<secondary_value> NaN </secondary_value>
<value> NaN </value>
<unknown_datapoints> 0 </unknown_datapoints>
</ds>
<ds>
<primary_value> 0.0000000000e+00 </primary_value>
<secondary_value> NaN </secondary_value>
<value> NaN </value>
<unknown_datapoints> 0 </unknown_datapoints>
</ds>
EOF
$cdp++;
next;
}
$cdp++;
}
}
if(/<\/row>/) {
my $str = $_;
my $n = 0;
$str =~ s/( <\/v>)/++$n % 3 == 0 ? " $1<v> NaN <\/v><v> NaN <\/v>" : $1/eg;
print OUT $str;
next;
}
print OUT $_;
}
close(IN);
close(OUT);
if(-f "$rrd.new") {
rename($rrd, "$rrd.old");
rename("$rrd.new", $rrd);
} else {
logger("$myself: WARNING: something went wrong upgrading $rrd. You have an unsupported old version.");
}
}
sub fs_init {
my $myself = (caller(0))[3];
my ($package, $config, $debug) = @_;
@ -60,8 +174,22 @@ sub fs_init {
}
}
}
if(scalar(@ds) / 24 != keys(%{$fs->{list}})) {
logger("$myself: Detected size mismatch between <list>...</list> (" . keys(%{$fs->{list}}) . ") and $rrd (" . scalar(@ds) / 24 . "). Resizing it accordingly. All historical data will be lost. Backup file created.");
# convert from 3.4.0- to 3.5.0 (add fs_ino DS)
upgrade_to_350($rrd) if scalar(@ds) == 24;
# recalculate the number of DS
undef(@ds);
$info = RRDs::info($rrd);
for my $key (keys %$info) {
if(index($key, 'ds[') == 0) {
if(index($key, '.type') != -1) {
push(@ds, substr($key, 3, index($key, ']') - 3));
}
}
}
if(scalar(@ds) / 40 != keys(%{$fs->{list}})) {
logger("$myself: Detected size mismatch between <list>...</list> (" . keys(%{$fs->{list}}) . ") and $rrd (" . scalar(@ds) / 40 . "). Resizing it accordingly. All historical data will be lost. Backup file created.");
rename($rrd, "$rrd.bak");
}
if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) {
@ -82,27 +210,43 @@ sub fs_init {
push(@tmp, "DS:fs" . $n . "_use0:GAUGE:120:0:100");
push(@tmp, "DS:fs" . $n . "_ioa0:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_tim0:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_ino0:GAUGE:120:0:100");
push(@tmp, "DS:fs" . $n . "_val0:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_use1:GAUGE:120:0:100");
push(@tmp, "DS:fs" . $n . "_ioa1:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_tim1:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_ino1:GAUGE:120:0:100");
push(@tmp, "DS:fs" . $n . "_val1:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_use2:GAUGE:120:0:100");
push(@tmp, "DS:fs" . $n . "_ioa2:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_tim2:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_ino2:GAUGE:120:0:100");
push(@tmp, "DS:fs" . $n . "_val2:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_use3:GAUGE:120:0:100");
push(@tmp, "DS:fs" . $n . "_ioa3:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_tim3:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_ino3:GAUGE:120:0:100");
push(@tmp, "DS:fs" . $n . "_val3:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_use4:GAUGE:120:0:100");
push(@tmp, "DS:fs" . $n . "_ioa4:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_tim4:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_ino4:GAUGE:120:0:100");
push(@tmp, "DS:fs" . $n . "_val4:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_use5:GAUGE:120:0:100");
push(@tmp, "DS:fs" . $n . "_ioa5:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_tim5:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_ino5:GAUGE:120:0:100");
push(@tmp, "DS:fs" . $n . "_val5:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_use6:GAUGE:120:0:100");
push(@tmp, "DS:fs" . $n . "_ioa6:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_tim6:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_ino6:GAUGE:120:0:100");
push(@tmp, "DS:fs" . $n . "_val6:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_use7:GAUGE:120:0:100");
push(@tmp, "DS:fs" . $n . "_ioa7:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_tim7:GAUGE:120:0:U");
push(@tmp, "DS:fs" . $n . "_ino7:GAUGE:120:0:100");
push(@tmp, "DS:fs" . $n . "_val7:GAUGE:120:0:U");
}
eval {
RRDs::create($rrd,
@ -344,6 +488,7 @@ sub fs_update {
my $use = 0;
my $ioa = 0;
my $tim = 0;
my $ino = 0;
my $used = 0;
my $free = 0;
@ -406,6 +551,36 @@ sub fs_update {
# prevents a division by 0 if device is not responding
$use = ($used * 100) / ($used + $free) unless $used + $free == 0;
eval {
local $SIG{'ALRM'} = sub {
kill 9, $pid;
logger("$myself: Timeout! Process with PID $pid was hung after $config->{timeout} secs. Killed.");
@tmp = (0, 0, 0, 0, 0, 0, 0);
};
alarm($config->{timeout});
if($config->{os} eq "Linux") {
$pid = open(IN, "df -P -i $f |");
} elsif($config->{os} eq "FreeBSD" || $config->{os} eq "OpenBSD") {
$pid = open(IN, "df -i $f |");
}
while(<IN>) {
if(/ $f$/) {
@tmp = split(' ', $_);
last;
}
}
close(IN);
alarm(0);
};
if($config->{os} eq "Linux") {
(undef, undef, $used, $free) = @tmp;
} elsif($config->{os} eq "FreeBSD" || $config->{os} eq "OpenBSD") {
(undef, undef, undef, undef, undef, $used, $free) = @tmp;
}
chomp($used, $free);
# prevents a division by 0 if device is not responding
$ino = ($used * 100) / ($used + $free) unless $used + $free == 0;
# FS alert
if($f eq "/" && lc($fs->{alerts}->{rootfs_enabled}) eq "y") {
if(!$fs->{alerts}->{rootfs_threshold} || $use < $fs->{alerts}->{rootfs_threshold}) {
@ -500,7 +675,7 @@ sub fs_update {
$tim /= 60;
$config->{fs_hist}->{$str} = $val;
$rrdata .= ":$use:$ioa:$tim";
$rrdata .= ":$use:$ioa:$tim:$ino:0";
}
$e++;
}