1
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2025-07-22 22:25:23 +00:00
Munin-Contrib/plugins/disk/du-2
Mikkel Kirkgaard Nielsen 21c28638e3
Generate cache file if missing
Don't exit with error if cache file is missing, instead refrain from sending values and daemonize() in an attempt to generate one.
Invocation using 'config' before generation is successful will fail, as mentioned in #914, but configuration will get picked up as soon as it is present.
2018-10-04 19:53:31 +02:00

194 lines
5.4 KiB
Perl
Executable file

#!/usr/bin/perl
# vim: set filetype=perl sw=4 tabstop=4 expandtab smartindent: #
=head1 NAME
du - Plugin to monitor multiple directories size
=head1 AUTHOR AND COPYRIGHT
Copyright 2011-2014 Luc Didry <luc AT didry.org>
=head1 HOWTO CONFIGURE AND USE :
=over
=item - /etc/munin/plugins/du
cp du /etc/munin/plugins/
=item - /etc/munin/plugin-conf.d/du_
[du]
user root
env.interval 20 # INTERVAL OF DU POLLING IN MINUTES
env.dirs /home/foo /home/bar # DIRECTORIES TO POLL
env.suppr /home/ # PLEASE USE \# INSTEAD OF #
timeout 900 # 15 MINUTES IN SECONDS
=item - restart Munin node
/etc/init.d/munin-node restart
=back
=head1 CREDITS
Based on the 'du_multidirs-v2' initially written in Bash by Christian Kujau <lists@nerdbynature.de> and modified by dano229.
This script was based on the 'homedirs' plugin, initially written in Perl by Philipp Gruber <pg@flupps.net>
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf
=head1 LICENSE
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
=cut
use warnings;
use strict;
use Munin::Plugin;
use POSIX qw(setsid);
my $PLUGIN_NAME = "du";
my $CACHEFILE="$Munin::Plugin::pluginstatedir/du.cache";
my $TEMPFILE="$Munin::Plugin::pluginstatedir/du.tmp";
my $LOCKFILE="$Munin::Plugin::pluginstatedir/du.lock";
my $TIMEFILE="$Munin::Plugin::pluginstatedir/du.time";
##### autoconf
if( (defined $ARGV[0]) && ($ARGV[0] eq "autoconf") ) {
print "no\n";
## Done !
munin_exit_done();
}
## In the parent, it's just a regular munin plugin which reads a file with the infos
##### config
if( (defined $ARGV[0]) && ($ARGV[0] eq "config") ) {
print "graph_title Directory usage\n";
print "graph_args --base 1024 -l 1\n";
print "graph_vlabel Bytes\n";
print "graph_category disk\n";
print "graph_total total\n";
print "graph_info This graph shows the size of several directories\n";
my $foo = 0;
open (FILE, "<", $CACHEFILE) or munin_exit_fail();
while(defined (my $bar = <FILE>)) {
if ($bar =~ m/(\d+)\s+(.+)/) {
my $dir = $2;
clean_path(\$dir);
my $clean_dir = clean_fieldname($dir);
print "$clean_dir.label $dir\n";
if ($foo++) {
print "$clean_dir.draw STACK\n";
} else {
print "$clean_dir.draw AREA\n";
}
}
}
close(FILE);
## Done !
munin_exit_done();
}
##### fetch
if (open (FILE, "<", $CACHEFILE)) {
while(defined (my $foo = <FILE>)) {
if ($foo =~ m/(\d+)\s+(.+)/) {
my ($field, $value) = ($2, $1);
clean_path(\$field);
print clean_fieldname($field), ".value ", $value, "\n";
}
}
close(FILE);
}
daemonize();
#
##
### PUBLIC FONCTIONS
###############################################################################
## Used to create the fork
sub daemonize {
chdir '/' or die "Can't chdir to /: $!";
defined(my $pid = fork) or die "Can't fork: $!";
munin_exit_done() if $pid;
open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!";
open STDERR, '>&STDOUT' or die "Can't dup stdout: $!";
setsid or die "Can't start a new session: $!";
## In the child, let's get the du infos if necessary
if (cache_is_too_old() && du_not_running()) {
my $dirs = $ENV{dirs};
system("touch $LOCKFILE; du -sb $dirs | sort -n -r > $TEMPFILE; cat $TEMPFILE > $CACHEFILE; rm $LOCKFILE; date +%s > $TIMEFILE;");
}
exit;
} ## daemonize
## Used to remove the beginning of the paths if wanted
sub clean_path {
my ($path) = @_;
if (defined $ENV{suppr}) {
my $pattern = $ENV{suppr};
$$path =~ s#^($pattern)##;
}
} ## clean_path
## Do you really need I told you what this functions are going to check ?
sub cache_is_too_old {
return 1 if (! -e $TIMEFILE);
my ($time) = `cat $TIMEFILE`;
chomp $time;
return 1 if ( (time - $time) > ($ENV{interval}*60) );
return 0;
} ## cache_is_too_old
sub du_not_running {
if (-e $LOCKFILE) {
my ($time) = `cat $TIMEFILE`;
chomp $time;
if ( (time - $time) > ($ENV{interval}*60*60) ) {
# The cache is really old (60xinterval) => Maybe the lockfile wasn't properly deleted.
# Let's delete it.
system("rm $LOCKFILE;");
return 1;
} else {
return 0;
}
} else {
return 1;
}
}
sub munin_exit_done {
__munin_exit(0);
} ## sub munin_exit_done
sub munin_exit_fail {
__munin_exit(1);
} ## sub munin_exit_fail
#
##
### INTERNALS FONCTIONS
###############################################################################
sub __munin_exit {
my $exitcode = shift;
exit($exitcode) if(defined $exitcode);
exit(1);
} ## sub __munin_exit