root / plugins / disk / du-2 @ 6c7ad652
Historique | Voir | Annoter | Télécharger (5,4 ko)
| 1 |
#!/usr/bin/perl |
|---|---|
| 2 |
# vim: set filetype=perl sw=4 tabstop=4 expandtab smartindent: # |
| 3 |
|
| 4 |
=head1 NAME |
| 5 |
|
| 6 |
du - Plugin to monitor multiple directories size |
| 7 |
|
| 8 |
=head1 AUTHOR AND COPYRIGHT |
| 9 |
|
| 10 |
Copyright 2011-2014 Luc Didry <luc AT didry.org> |
| 11 |
|
| 12 |
=head1 HOWTO CONFIGURE AND USE : |
| 13 |
|
| 14 |
=over |
| 15 |
|
| 16 |
=item - /etc/munin/plugins/du |
| 17 |
cp du /etc/munin/plugins/ |
| 18 |
|
| 19 |
=item - /etc/munin/plugin-conf.d/du_ |
| 20 |
|
| 21 |
[du] |
| 22 |
user root |
| 23 |
env.interval 20 # INTERVAL OF DU POLLING IN MINUTES |
| 24 |
env.dirs /home/foo /home/bar # DIRECTORIES TO POLL |
| 25 |
env.suppr /home/ # PLEASE USE \# INSTEAD OF # |
| 26 |
timeout 900 # 15 MINUTES IN SECONDS |
| 27 |
|
| 28 |
=item - restart Munin node |
| 29 |
|
| 30 |
/etc/init.d/munin-node restart |
| 31 |
|
| 32 |
=back |
| 33 |
|
| 34 |
=head1 CREDITS |
| 35 |
|
| 36 |
Based on the 'du_multidirs-v2' initially written in Bash by Christian Kujau <lists@nerdbynature.de> and modified by dano229. |
| 37 |
This script was based on the 'homedirs' plugin, initially written in Perl by Philipp Gruber <pg@flupps.net> |
| 38 |
|
| 39 |
=head1 MAGIC MARKERS |
| 40 |
|
| 41 |
#%# family=auto |
| 42 |
#%# capabilities=autoconf |
| 43 |
|
| 44 |
=head1 LICENSE |
| 45 |
|
| 46 |
This program is free software: you can redistribute it and/or modify |
| 47 |
it under the terms of the GNU General Public License as published by |
| 48 |
the Free Software Foundation, either version 3 of the License, or |
| 49 |
any later version. |
| 50 |
|
| 51 |
This program is distributed in the hope that it will be useful, |
| 52 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 53 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 54 |
GNU General Public License for more details. |
| 55 |
|
| 56 |
You should have received a copy of the GNU General Public License |
| 57 |
along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 58 |
|
| 59 |
=cut |
| 60 |
|
| 61 |
use warnings; |
| 62 |
use strict; |
| 63 |
use Munin::Plugin; |
| 64 |
use POSIX qw(setsid); |
| 65 |
|
| 66 |
my $PLUGIN_NAME = "du"; |
| 67 |
my $CACHEFILE="$Munin::Plugin::pluginstatedir/du.cache"; |
| 68 |
my $TEMPFILE="$Munin::Plugin::pluginstatedir/du.tmp"; |
| 69 |
my $LOCKFILE="$Munin::Plugin::pluginstatedir/du.lock"; |
| 70 |
my $TIMEFILE="$Munin::Plugin::pluginstatedir/du.time"; |
| 71 |
|
| 72 |
##### autoconf |
| 73 |
if( (defined $ARGV[0]) && ($ARGV[0] eq "autoconf") ) {
|
| 74 |
print "no\n"; |
| 75 |
## Done ! |
| 76 |
munin_exit_done(); |
| 77 |
} |
| 78 |
|
| 79 |
## In the parent, it's just a regular munin plugin which reads a file with the infos |
| 80 |
##### config |
| 81 |
if( (defined $ARGV[0]) && ($ARGV[0] eq "config") ) {
|
| 82 |
print "graph_title Directory usage\n"; |
| 83 |
print "graph_args --base 1024 -l 1\n"; |
| 84 |
print "graph_vlabel Bytes\n"; |
| 85 |
print "graph_category disk\n"; |
| 86 |
print "graph_total total\n"; |
| 87 |
print "graph_info This graph shows the size of several directories\n"; |
| 88 |
|
| 89 |
my $foo = 0; |
| 90 |
open (FILE, "<", $CACHEFILE) or munin_exit_fail(); |
| 91 |
while(defined (my $bar = <FILE>)) {
|
| 92 |
if ($bar =~ m/(\d+)\s+(.+)/) {
|
| 93 |
my $dir = $2; |
| 94 |
clean_path(\$dir); |
| 95 |
my $clean_dir = clean_fieldname($dir); |
| 96 |
print "$clean_dir.label $dir\n"; |
| 97 |
if ($foo++) {
|
| 98 |
print "$clean_dir.draw STACK\n"; |
| 99 |
} else {
|
| 100 |
print "$clean_dir.draw AREA\n"; |
| 101 |
} |
| 102 |
} |
| 103 |
} |
| 104 |
close(FILE); |
| 105 |
## Done ! |
| 106 |
munin_exit_done(); |
| 107 |
} |
| 108 |
|
| 109 |
##### fetch |
| 110 |
if (open (FILE, "<", $CACHEFILE)) {
|
| 111 |
while(defined (my $foo = <FILE>)) {
|
| 112 |
if ($foo =~ m/(\d+)\s+(.+)/) {
|
| 113 |
my ($field, $value) = ($2, $1); |
| 114 |
clean_path(\$field); |
| 115 |
print clean_fieldname($field), ".value ", $value, "\n"; |
| 116 |
} |
| 117 |
} |
| 118 |
close(FILE); |
| 119 |
} |
| 120 |
daemonize(); |
| 121 |
|
| 122 |
# |
| 123 |
## |
| 124 |
### PUBLIC FUNCTIONS |
| 125 |
############################################################################### |
| 126 |
## Used to create the fork |
| 127 |
sub daemonize {
|
| 128 |
chdir '/' or die "Can't chdir to /: $!"; |
| 129 |
defined(my $pid = fork) or die "Can't fork: $!"; |
| 130 |
munin_exit_done() if $pid; |
| 131 |
open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; |
| 132 |
open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!"; |
| 133 |
open STDERR, '>&STDOUT' or die "Can't dup stdout: $!"; |
| 134 |
setsid or die "Can't start a new session: $!"; |
| 135 |
## In the child, let's get the du infos if necessary |
| 136 |
if (cache_is_too_old() && du_not_running()) {
|
| 137 |
my $dirs = $ENV{dirs};
|
| 138 |
system("touch $LOCKFILE; du -sb $dirs | sort -n -r > $TEMPFILE; cat $TEMPFILE > $CACHEFILE; rm $LOCKFILE; date +%s > $TIMEFILE;");
|
| 139 |
} |
| 140 |
exit; |
| 141 |
} ## daemonize |
| 142 |
|
| 143 |
## Used to remove the beginning of the paths if wanted |
| 144 |
sub clean_path {
|
| 145 |
my ($path) = @_; |
| 146 |
if (defined $ENV{suppr}) {
|
| 147 |
my $pattern = $ENV{suppr};
|
| 148 |
$$path =~ s#^($pattern)##; |
| 149 |
} |
| 150 |
} ## clean_path |
| 151 |
|
| 152 |
## Do you really need I told you what this functions are going to check ? |
| 153 |
sub cache_is_too_old {
|
| 154 |
return 1 if (! -e $TIMEFILE); |
| 155 |
my ($time) = `cat $TIMEFILE`; |
| 156 |
chomp $time; |
| 157 |
return 1 if ( (time - $time) > ($ENV{interval}*60) );
|
| 158 |
return 0; |
| 159 |
} ## cache_is_too_old |
| 160 |
|
| 161 |
sub du_not_running {
|
| 162 |
if (-e $LOCKFILE) {
|
| 163 |
my ($time) = `cat $TIMEFILE`; |
| 164 |
chomp $time; |
| 165 |
if ( (time - $time) > ($ENV{interval}*60*60) ) {
|
| 166 |
# The cache is really old (60xinterval) => Maybe the lockfile wasn't properly deleted. |
| 167 |
# Let's delete it. |
| 168 |
system("rm $LOCKFILE;");
|
| 169 |
return 1; |
| 170 |
} else {
|
| 171 |
return 0; |
| 172 |
} |
| 173 |
} else {
|
| 174 |
return 1; |
| 175 |
} |
| 176 |
} |
| 177 |
|
| 178 |
sub munin_exit_done {
|
| 179 |
__munin_exit(0); |
| 180 |
} ## sub munin_exit_done |
| 181 |
|
| 182 |
sub munin_exit_fail {
|
| 183 |
__munin_exit(1); |
| 184 |
} ## sub munin_exit_fail |
| 185 |
|
| 186 |
# |
| 187 |
## |
| 188 |
### INTERNALS FUNCTIONS |
| 189 |
############################################################################### |
| 190 |
sub __munin_exit {
|
| 191 |
my $exitcode = shift; |
| 192 |
exit($exitcode) if(defined $exitcode); |
| 193 |
exit(1); |
| 194 |
} ## sub __munin_exit |
