I had a need for a Filesystem Monitoring Perl Script. I have a filesystem that is mounted on a SAN and I suspect that the SAN is becomming unreachable momentarily every once in a while. It can cause issues with an application I support on the system, that relies heavily on this filesystem being available in a cluster.
Every log I examine shows nothing yet the behavior shows otherwise. I decided to write a little Filesystem Monitoring Perl Script that will run from cron every 60 seconds and alert me to any issues that crop up reading or writing to a filesystem.
The Script is basic. It does three things. First it attempts to open a file and write to it, next it attempts to read from that file, and third it will alert me via email if any steps in this process fail. Make sure you edit the variables to your needs.
Filesystem Monitoring Perl Script
Here is the code for mountMonitor.pl:
#!/usr/bin/perl
use strict;
use warnings;
use POSIX;
use Sys::Hostname;
use Storable qw( store retrieve );
use Mail::Mailer;
## Variables
my $mountPoint = "/MountPointToMonitor";
my $testFile = "$mountPoint/fsmonitor.test";
my $alertDir = "/tmp";
my ($writeOk, $readOk) = (0, 0);
my $Alerts = eval { retrieve("$alertDir/fs.alerts"); };
my $hostname = hostname();
## Main Program
&write();
&read();
&clean();
unless ($writeOk) { pdebugLocal("Could not Write to SAN!", 1, 'SAN Subsystem', 1) }
unless ($readOk) { pdebugLocal("Could not Read from SAN!", 1, 'SAN Subsystem', 1) }
if ($writeOk && $readOk){
foreach my $alert (keys %$Alerts){
## Clear old alerts
delete($Alerts->{$alert});}
print "SAN: Read Write Checkout GOODn"; }
store($Alerts, "$alertDir/fs.alerts");
exit 0;
## Subs
sub write {
open WFILE, '>', $testFile or warn "Cannot Open File for Writing";
print WFILE "Testing Write to SAN";
$writeOk = 1;
close WFILE;
}
sub read {
if (-e $testFile) {
open RFILE, '<', $testFile or warn "Cannot Open File for Reading";
my $count = grep /SAN/,
if ($count == '1') {
$readOk = 1;
} else {
$readOk = 0;
}
close RFILE;
}
}
sub clean {
qx |rm $testFile|;
}
sub pdebugLocal {
my $msg = shift;
my $severity = shift;
my $string = shift;
my $status = shift;
print "SAN: FAIL - $msg:$stringn";
sendMail("$msg : $string");
$Alerts->{$$} = { 'msg' => $msg,
'severity' => $severity,
'string' => $string,
'status' => 1,
};
store($Alerts, "$alertDir/fs.alerts");
exit 0;
}
sub sendMail {
my $code = shift;
my $sendAlias = '"SAN Monitor"
my $mailHead;
$mailHead->{'From'} = $sendAlias;
$mailHead->{'To'} = '[email protected]';
$mailHead->{'Bcc'} = '[email protected]';
$mailHead->{'Subject'} = "SAN Monitor Failure! [$hostname]";
my $mail = Mail::Mailer->new('sendmail');
$mail->open($mailHead);
print $mail "n/* Result of SAN Failure /*nn";
print $mail " Component : [SAN]n";
print $mail " Time : [", POSIX::strftime('%y%m%d %H:%M:%S', localtime(time)), "]n";
print $mail " Server : [$hostname]n";
print $mail " ERROR : [SAN is Unavailable!]n";
print $mail "n/* End Result of SAN Failure /*nn";
$mail->close();
}
Next chmod your file to make it executable and run it once to make sure you have everything editied to your needs with no typographical errors.
chmod +x mountMonitor.pl
./mountMonitor.pl
Then to setup cron to run the script every minute:
crontab -e
##ADD THE FOLLOWING LINE
*/1 * * * * /path/to/script/mountMonitor.pl
Thats all there is to it. Enjoy!
Leave a Reply