#!/usr/bin/perl
# -*-  perl -*-
#
# $Id: df.in 1416 2008-01-26 21:56:56Z matthias $
#
# Plugin to monitor disk usage. Rewrite based on original shell-based version
#
# Parameters understood:
#
#       config   (required)
#       autoconf (optional - used by munin-config)
#
# Environment
#       exclude: space separated list if fs types to exclude.  by default a
#                list of special, read-only or dynamically allocating file
#                systems
#       warning: Warning percentage, default 92.
#       critical: Critical percentage, default 98.
#
# $Id: df.in 1416 2008-01-26 21:56:56Z matthias $
#
# Magic markers (optional - used by munin-config and installation
# scripts):
#
#%# family=auto
#%# capabilities=autoconf

use strict;
use Munin::Plugin;

my %mounts;

open (MOUNTS,"/proc/mounts") or die "Could not /proc/mounts for reading.";
while (<MOUNTS>) {
    # Does perl really not have any shorthand for this? I guess it has.
    if ( /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/ ) {
	$mounts{$2}=$3;
    }
}
close MOUNTS;

my $exclude=$ENV{'exclude'} || 'none unknown iso9660 squashfs udf romfs ramfs';
my $warning=$ENV{'warning'} || '92';
my $critical=$ENV{'critical'} || '98';
my $dfopts = "-P -l ".join(' -x ',('',split('\s+',$exclude)));

sub print_values() {

    # Read from df
    open (DF,"df $dfopts |") or die "Could not open pipe from df, $!";
    <DF>; # Skip the header
    while (<DF>) {
	next if /\/\//;
	
	# Parse the output
	if ( /^(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+)/ ) {
	    my $fs=$mounts{$6};
	    my $ps=$5;
	    my $name=clean_fieldname($1);

	    $ps =~ s/\%//;
	    print $name, ".value ", $ps, "\n";
	}
    }
    close DF;
    die "Error executing df. Exit code $?\n" if $?;
}

if ( $ARGV[0] eq "autoconf" ) {
    if (`/usr/bin/perl $0` eq "" ) {
	print "no\n";
	exit 1;
    } else {
	print "yes\n";
	exit 0;
    }
}

if ( $ARGV[0] eq "config" ) {

    # The headers
    print "graph_title Disk usage (in percent)\n";
    print "graph_args --upper-limit 100 -l 0\n";
    print "graph_vlabel %\n";
    print "graph_scale no\n";
    print "graph_category disk\n";

    # Read from df
    open (DF,"df $dfopts |") or die "Unable to open pipe from df: $!";
    <DF>; # Skip the header
    while (<DF>) {
	next if /\/\//;
	
	# Parse the output
	if ( /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/ ) {
	    my $fs=$mounts{$6};
	    my $dir=$6;
	    my $name=clean_fieldname($1);

	    # Create and print labels
	    print $name, ".label ", $dir, "\n";

	    # FIXME: These ought to be tunable
	    print "$name.warning $warning\n";
	    print "$name.critical $critical\n";
	}
    }
    close DF;
    die "Error executing df. Exit code $?\n" if $?;
    exit 0;
}

print_values();
