#!/usr/bin/perl -w
# -*-  perl -*-

=head1 NAME

df - Munin plugin to monitor disk usage

=head1 APPLICABLE SYSTEMS

Every Linux system with df installed.

=head1 CONFIGURATION

The plugin excludes per default the following special, read-only or
dynamically allocating file systems from graphing: 

  none unknown iso9660 squashfs udf romfs ramfs

To change this set the environment variable "exclude" with a list of
space separated fs types.  The environment variables "warning" and
"critical" sets the percentage from which Munin starts to warn about
the disk usage.

This configuration snipplet is an example with the defaults:

  [df]
    env.exclude none unknown iso9660 squashfs udf romfs ramfs debugfs
    env.warning 92
    env.critical 98

Put it in a file in /etc/munin/plugin-conf.d/ and restart the munin-node.

You may specify filesystem specific warning and critical levels:

    env._dev_sda2_warning 98
    env._dev_sda2_critical 99

=head1 USAGE 

Link this plugin to /etc/munin/plugins/ and restart the munin-node.

=head1 MAGIC MARKERS

  #%# family=auto
  #%# capabilities=autoconf

=head1 BUGS

Uses device names instead of mount points to identify mounted
filesystems.

=head1 VERSION

$Id: df.in 3295 2010-01-08 10:07:14Z ssm $

=head1 AUTHOR

Ingvar Hagelund

=head1 LICENSE

GPLv2

=cut

use strict;
use Munin::Plugin;

# For these devices use the mount point, the device is useless
my %usemntpt = ( tmpfs => 1, none => 1, udev => 1 );

my $exclude=$ENV{'exclude'} || 'none unknown iso9660 squashfs udf romfs ramfs debugfs simfs';
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>) {
	chomp;
	next if /\/\//; # Ignore lines containing //? Samba?
	
	# Parse the output
	my ($name,undef,$used,$avail,undef,$mountpt,undef)=split(/\s+/,$_,7);

	$name = $mountpt if defined($usemntpt{$name}) && $usemntpt{$name};

	$name=clean_fieldname($name);

	my $ps = 0;

	$ps = ( $used / ($used+$avail) ) * 100 if $used;

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

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

if ( defined($ARGV[0]) and $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
	my ($name,undef,undef,undef,$ps,$mountpt,undef)=split(/\s+/,$_,7);

	$name = $mountpt if defined($usemntpt{$name}) && $usemntpt{$name};

	$name=clean_fieldname($name);

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

	print_thresholds($name,undef,undef,92,98);
    }
    close DF;
    die "Error executing df. Exit code $?\n" if $?;
    exit 0;
}

print_values();
