Due to lack of central configuration management I am avoiding any Perl modules which would need to be installed on each of a great many servers. Result is more code than would normally be required in order to format HTML and send email as well as make system calls which are less desirable.
#!/usr/bin/perl
use strict;
use warnings;
use Sys::Hostname;
use POSIX qw(uname);
my (%fsSize, %fsFree, %fsPct, %overrides);
my ($thresh, $fh);
my $repFile = "/tmp/chkDiskResults.txt";
my $send = 0;
my $hostname = hostname();
my @uname = uname();
# Determine the OS and set the 'df' command appropriately
my $df;
if ($uname[0] =~ 'AIX') {
$df = "df -tg";
} elsif ($uname[0] =~ 'Linux') {
$df = "df -h";
}
# Check for an override file loading it if it exists and running
# simple checks to ensure the values are valid.
my $overrideFile = "/etc/override";
if (-e $overrideFile) {
open($fh, '<', $overrideFile) or die "Unable to open file: $overrideFile\n $!";
while (my $line = <$fh>) {
my @split = split /\s+/, $line;
unless (!$split[1] || $split[1] !~ /^[0-9]+$/) {
$overrides{$split[0]} = $split[1];
}
}
close($fh);
}
# Execute the system 'df' command ignoring anything that isn't a
# real filesystem
# $cols[1] => Total space in GB
# $cols[3] => Free space in GB
# $cols[4] => Percent used column
# $cols[5] => Mounted on column
foreach my $line (qx[$df |grep -E -v "(Filesystem|proc|tmpfs)"]) {
my @cols = split /\s+/, $line;
chop($cols[1]);
chomp($cols[3]);
chop($cols[4]);
# set threshold based on disk size; A 1TB disk doesn't need
# to alert when 100GB are available
if ($cols[1] >= 800) {
$thresh = 98;
} elsif ($cols[1] < 800 && $cols[1] >= 400) {
$thresh = 96;
} elsif ($cols[1] < 400 && $cols[1] >= 200) {
$thresh = 94;
} elsif ($cols[1] < 200 && $cols[1] >= 100) {
$thresh = 92;
} else {
$thresh = 90;
}
$fsSize{$cols[5]} = $cols[1];# . "G";
$fsFree{$cols[5]} = $cols[3];# . "G";
$fsPct{$cols[5]} = $cols[4];
}
# Do the needful; override the thresholds if necessary; write
# offending filesystems to /tmp/chkDiskResults.txt as HTML
# since Outlook mangles text formatting
open($fh, '>', $repFile) or die "Unable to open file: $repFile\n $!";
print $fh <<"EOF";
<html>
<body>
<h1>Disk usage report for $hostname</h1>
<table width="500">
<tr>
<th align="left">Filesystem</th>
<th>Size</th>
<th>Free</th>
<th>Percent Used</th>
</tr>
EOF
foreach my $key (keys %fsPct) {
my $origThresh = $thresh;
if (exists $overrides{$key}) {
$thresh = $overrides{$key};
}
if ($fsPct{$key} >= $thresh) {
$send = 1;
print $fh " <tr>\n";
print $fh <<"EOF";
<td>$key</td>
<td align="center">$fsSize{$key}G</td>
<td align="center">$fsFree{$key}G</td>
<td align="center">$fsPct{$key}%</td>
EOF
print $fh " </tr>\n";
}
$thresh = $origThresh;
}
# Close out the HTML
print $fh <<"EOF";
</table>
</body>
</html>
EOF
close($fh);
# Send the report; send email directly through sendmail avoiding
# any additional modules
if ($send) {
my ($message_body, $subject, $from, $to, $cc);
open($fh, '<', $repFile) or die "Cannot open $repFile:\n $!";
{
local $/;
$message_body = <$fh>;
}
$subject = "Just a test";
$from = "root\@$hostname";
$to = 'email@address';
#$cc = 'email@address';
#Cc: $cc
open(MAIL, "|/usr/sbin/sendmail -oi -t");
print MAIL << "EOF";
Content-Type: text/html
Subject: $subject
To: $to
From: $from
$message_body
\n\n
EOF
close(MAIL);
unlink $repFile;
} else {
exit;
}
The script is executed via SSH:
# ssh server "perl" < script.pl
EDIT 1
I can say that I've already found one issue: I receive an email even if there are no file systems that are at or above the threshold. The list is empty with just the headers being sent.
EDIT 2
Added code that sends the email if a file system is found which exceeds its threshold otherwise exits the script.
EDIT 3
Eliminated two system calls by using built-in Sys::Hostname
and POSIX
modules; Removed the $os
variable and replaced it with direct use of $uname[0]
established with POSIX::uname()
df
. Anddf -P
might give consistent results across various unix flavors. \$\endgroup\$/etc/override
a standard system file? I tried google it but I could not find any documentation. What is the format of this file? \$\endgroup\$