Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

dfmon - Disk Free Monitor

by rob_au (Abbot)
on May 09, 2002 at 12:04 UTC ( [id://165341]=sourcecode: print w/replies, xml ) Need Help??
Category: Utility Scripts
Author/Contact Info rob_au
Description: This little script is a rewrite of a very nasty bash script that for a long time formed a core crontab entry on systems which I administer. This code allows for the alerting of the system administrator via email when the disk space on any of the mounted partitions drops below a set threshold.

The corresponding template file used for the email sent to the system administrator may look similar to the following:

This is an automatically generated message. The following file systems have reached a storage capacity greater than the alert threshold set within the dfmon.perl administrative script. [% FOREACH fs = filesystems %] [% FILTER format('%-10s') %][% fs.mountpoint %][% END -%] [%- FILTER format('%15s') %][% fs.blocks_total %][% END -%] [%- FILTER format('%10s') %][% fs.blocks_used %][% END -%] [%- FILTER format('%10s') %][% fs.blocks_free %][% END -%] [%- FILTER format('%5s%%') %][% fs.percent %][% END -%] [%- END %] --


#!/usr/bin/perl -Tw

use constant EMAIL      =>  '';
use constant SERVER     =>  'localhost';

use constant ALERT      =>  90;
use constant FILESYS    =>  ( '/', '/usr', '/var', '/home' );

use Carp;
use Filesys::Df ();
use Mail::Mailer;
use Template;
use strict;

my @alert = ();
foreach my $fs ( FILESYS ) {
    my $ref = Filesys::Df::df( $fs );
    push @alert, {
        'mountpoint'    =>  $fs,
        'percent'       =>  $ref->{'per'},
        'blocks_free'   =>  $ref->{'bfree'},
        'blocks_used'   =>  $ref->{'used'},
        'blocks_total'  =>  $ref->{'blocks'}
    } if $ref->{'per'} > ALERT;

if (scalar @alert) {
    my $output;
    my $mail = Mail::Mailer->new( 'smtp', Server => SERVER );
        'To'        =>  EMAIL,
        'From'      =>  EMAIL
    my $template = Template->new({ 'ABSOLUTE' => 1 });
        { 'filesystems' => \@alert },
    ) || croak( 'Error in processing mail template - ', $template->err
+or );
    print $mail $output;

exit 0;
Replies are listed 'Best First'.
Re: dfmon - Disk Free Monitor
by neilwatson (Priest) on May 13, 2002 at 15:24 UTC
    This may be a little more flexible for you:

    #!/usr/bin/perl -w use strict; use warnings; #usage: diskspace <number between 0 and 100> my $diskuse = $ARGV[0]; my $recipient = "support\"; #who gets the report my $dfrep = `df -k`; #get partition report my @partitions = split(/\n/,$dfrep); # split report my (@full, @ele, $usage, $x, $i); my $hostname = `hostname`; chomp($hostname); #check syntax unless ($diskuse > 0 || $diskuse < 100) { print "\nUsage: spaceuse <n>\n"; print "Where n is the maximum percentage of space, in use by "; print "any disk partition\n"; } #check for partitions whose percent full is #greater than or equal to the percent entered #by the user. foreach $i (@partitions) { $_ = $i; if (m/(\d{2})%/) {$usage = $1} if ($diskuse <= $usage) { push(@full,$x) } $x++; } #create and mail report if ($#full != 0) { open(MAIL, "|mail -s \"Diskspace Warning\" $recipient"); print MAIL "\nWarning from $hostname\n"; print MAIL "These Partitions are dangerously full:\n\n"; for (@full) { $_++; $_--; #converts scalar to numberic $partitions[$_] =~ s/\s+/\t/g; @ele = split(/\t/, $partitions[$_]); printf MAIL "%13s %11s %11s %11s %4s %13s\n", $ele[0], $ele[1], $ele +[2], $ele[3], $ele[4], $ele[5]; } close(MAIL); }

    Neil Watson

      Thanks for your feedback Neil - A couple of quick comments ...

      • In the reporting loop, the conversion of scalar to numeric can be performed more directly with $_ + 0 instead of the sequential increment and decrement.
      • In a quick test of your code, it didn't appear to correctly validate the parameter passed on the command line - No error messages were returned when using an out of bounds value.
      • In the original snippet of code which I posted, I consciously made use of the Filesys::Df module for the determination of disk space in place of parsing the output of df.

        The reason for this stems from my near paranoid nature about making external system calls - Introducing an external system call places an additional dependency upon the code to run and introduces a point in the system where the code may either fail or be compromised. If you must perform system calls, ensure that the full path to the application is given and that system return codes are checked - Also see my discussion on this here


        Thanks for the tips. The code should work. I have it running on several servers now.

        Neil Watson

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://165341]
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (7)
As of 2024-04-24 03:30 GMT
Find Nodes?
    Voting Booth?

    No recent polls found