incarnadine has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I'm looking to write something that will check all the various local and NFS mounted filesystems, and send an email to the user specified on the command line if the usage is over 70%, with another email (or perhaps just a different message) if it's over 90%. Before I get into it, should I even be trying to write this in Perl? Would the Bourne shell be better, or is there some clever Perl way to do this? I looked around, and didn't see any Perl snippets, modules, or scripts that do this, which led me to think it Perl might not be the way to go this time; checking filesystem usage seems like something useful and generic enough that if it were particularly easy to do in Perl, someone already would have. Any thoughts welcome.

Replies are listed 'Best First'.
Re: Checking filesystems?
by graff (Chancellor) on Feb 14, 2003 at 06:55 UTC
    Using Perl for this would certainly be better/easier than using a shell script. You have the choice of using perl modules (as suggested in the earlier reply) or using back-tick runs of handy shell utilities to collect information and take appropriate actions (I often do both).

    If you're working on a diverse network (i.e. running on different hosts that might have different flavors of unix, or at least different versions of the "standard" df utility), then you really want to use Filesys::DiskFree, so you won't need to worry about figuring out how to parse different formats of df output. (And then there's "Mail::Send" to make the mailing part easier too.)

    I've never been a whiz at shell scripts, but they tend to look awfully clumsy and difficult when it comes to doing anything really computational. Here's an example of a script to do what you specified (tested on linux and solaris):

    use strict; use Mail::Send; use Filesys::DiskFree; # This will check all mounted volumes, both local and NFS, # and send separate email reports listing the ones over # 90% full and the ones over 70% full. my $fs = new Filesys::DiskFree; $fs->df(); my @vols = sort $fs->disks(); my ( $yellowFlag, $redFlag ); for my $vol ( @vols ) { my $dev = $fs->device( $vol ); next unless ( $fs->total( $dev ); # some solaris vols may be 0 my $pct_used = $fs->used( $dev ) / $fs->total( $dev ); $yellowFlag .= "$vol ($dev) is over 70% full\n" if ( $pct_used > 0.7 ); $redFlag .= "$vol ($dev) is over 90% full\n" if ( $pct_used > 0.9 ); } if ( $yellowFlag or $redFlag ) { my $msg = new Mail::Send; if ( $yellowFlag ) { $msg->to( 'bureaucrat@my.org' ); $msg->subject( 'Time to buy more disk!' ); my $fh = $msg->open; print $fh $yellowFlag; $fh->close; } if ( $redFlag ) { $msg->to( 'sysadmin@my.org' ); $msg->subject( 'Time to rattle some cages!' ); my $fh = $msg->open; print $fh $redFlag; $fh->close; } }
    update: fixed the logic for appending lines to the two different reports.
Re: Checking filesystems?
by data64 (Chaplain) on Feb 14, 2003 at 05:21 UTC

    You might want to try Filesys::DiskFree

    Besides even if you had to run "df" or whatever to retrieve the Filesystem information, parsing it is probably going to be easier with perl.


    Just a tongue-tied, twisted, earth-bound misfit. -- Pink Floyd

Re: Checking filesystems?
by Abigail-II (Bishop) on Feb 14, 2003 at 13:08 UTC
    Perl would be overkill.
    #!/usr/bin/sh if df -k | grep '\([7-9][0-9]|[0-9][0-9][0-9]\)%' > /dev/null then mailx -s "File system(s) full. Clean up your mess." user@foo. +tla <<'--' Yada yada yada - The angry sysadmin. -- fi

    This assumes you don't have mount points or volumes that are named "file_at_89%' though. ;-)

    Abigail

Re: Checking filesystems? - link
by Tomte (Priest) on Feb 14, 2003 at 09:00 UTC

    As a kind of shameless advertisement I suggest a look at script-security / custom nagios-check ;-).
    The script presented there uses a slighly altered version of Filesys::DiskFree (that calls df with an absolute path).

    regards,
    tomte