You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Princeton/pu/libexec/check_disk_pu.pl

280 lines
5.6 KiB
Perl

#!/usr/bin/perl
use Getopt::Std;
$CFG_FILE = "/usr/local/nagios/etc/check_disk.cfg";
$CFG_FILE_LOCAL = "/usr/local/nagios/etc/check_disk_local.cfg";
$DFLT_WARN = 90;
$DFLT_CRIT = 95;
$DFLT_CLASS = "system";
$CURR_WARN = $DFLT_WARN;
$CURR_CRIT = $DFLT_CRIT;
$CURR_CLASS = $DFLT_CLASS;
$sys_type = `uname`;
chomp($sys_type);
%FSTypes = (
ext2 => 1,
ext3 => 1,
ext4 => 1,
ufs => 1,
vxfs => 1,
zfs => 1,
xfs => 1
);
# -p enable perf stats
# -d enable debugging output
# -c <crit> set default critical threshold
# -w <warn> set default warning threshold
# -f <config-file>
# -C <class>
# -t <type[,type...]> add additional file system types
getopts("pdc:w:f:C:t:");
$CURR_WARN = $opt_w if $opt_w ne '';
$CURR_CRIT = $opt_c if $opt_c ne '';
$opt_C = $CURR_CLASS if $opt_C eq '';
# get the types
if ($opt_t ne '') {
@types = split(/,/, $opt_t);
for $t (@types) {
print "add type $t\n" if $opt_d;
$FSTypes{$t} = 1;
}
}
# get the list of file systems
&read_mounts;
# read the config file; if it's not there we take the defaults, except
# that if we specify a config file on the command line, we return UNKNOWN
# if the file isn't there
if ($opt_f ne '') {
open (CFG_FILE, $opt_f) or unknown("Can't open config file: $opt_f");
&read_config;
}
else {
(open(CFG_FILE, $CFG_FILE_LOCAL) or open(CFG_FILE, $CFG_FILE)) and &read_config;
}
if ($opt_d) {
for $fs (sort keys %Class) {
print "fs $fs class $Class{$fs} warn $Warn{$fs} crit $Crit{$fs}\n";
}
}
# if there are any file systems that are mounted but not mentioned in the config file,
# give them default class and thresholds
for $fs (keys %Type) {
print "testing $fs: ", defined($Interesting{$fs}) ? "" : "not ", "interested\n" if $opt_d;
if (! defined($Interesting{$fs})) {
$Class{$fs} = $DFLT_CLASS;
$Warn{$fs} = $DFLT_WARN;
$Crit{$fs} = $DFLT_CRIT;
}
}
if ($sys_type eq "Linux") {
$cmd = "/bin/df -kP";
}
elsif ($sys_type eq "SunOS") {
$cmd = "/usr/bin/df -k";
}
else {
unknown("I don't grok system type $sys_type");
}
$fscount = 0;
for $fs (sort keys %Class) {
## unknown("Non-existant FS ($fs) in config file, line $Line{$fs}") if $Type{$fs} eq '';
push(@FSList, $fs);
}
for $fs (@FSList) {
next if $Ignore{$fs};
next if $Class{$fs} ne $opt_C;
$cmd = $cmd . " " . $fs;
$fscount++;
}
if ($fscount == 0) {
unknown("no file systems in class \'$opt_C\'");
}
print "$cmd\n" if $opt_d;
$code = 0;
open(DF, "$cmd|") or unknown("Unable to exec df command");
$junk = <DF>; # column headers
while (<DF>) {
chop;
($dev, $tot, $used, $free, $cap, $fs) = split;
$p = int(($tot - $free) * 100 / $tot);
print "$fs: $used/$tot $p\n" if $opt_d;
$perf .= " $fs=$p\%";
if ($p > $Crit{$fs}) {
$crit_result .= " $fs: $p\% (C)";
$code = 2;
}
elsif ($p > $Warn{$fs}) {
$warn_result .= " $fs: $p\% (W)";
$code = 1 if $code != 2;
}
else {
$result .= " $fs: $p\% (OK)";
}
}
print "perf $perf\n" if $opt_d;
@CODE = ("OK", "WARNING", "CRITICAL", "UNKNOWN");
print "DISK $CODE[$code]: class '$opt_C':$crit_result$warn_result$result";
print "|$perf" if $opt_p;
print "\n";
exit $code;
sub read_mounts
{
open(MNTTAB, "/etc/mtab") or open(MNTTAB, "/etc/mnttab") or unknown("Can't open file system mount table");
while (<MNTTAB>) {
chop;
@mnt = split;
next if $FSTypes{$mnt[2]} != 1;
$fs = $mnt[1];
print "read from mtab: $_\n" if $opt_d;
# push(@FSList, $fs);
$Type{$fs} = $mnt[2];
# $Class{$fs} = $DFLT_CLASS;
# $Warn{$fs} = $DFLT_WARN;
# $Crit{$fs} = $DFLT_CRIT;
}
}
sub read_config
{
my ($tmp_class, $tmp_warn, $tmp_crit);
$line_num = 0;
while (<CFG_FILE>) {
$line_num++;
chop;
s/^[ ]*//;
next if /^#/;
next if $_ eq '';
if (/^ignore\s/) {
($junk, $fs) = split;
$Ignore{$fs} = 1;
}
elsif (/^crit\s/) {
($junk, $crit) = split;
$CURR_CRIT = $crit;
}
elsif (/^warn\s/) {
($junk, $warn) = split;
$CURR_WARN = $warn;
}
elsif (/^class\s/) {
($junk, $class) = split;
$CURR_CLASS = $class;
}
elsif (/^fs\s/) {
($junk, @a) = split;
$fs = $a[0];
@fslist = &match($fs);
foreach $fs (@fslist) {
$tmp_class = $CURR_CLASS;
$tmp_warn = $CURR_WARN;
$tmp_crit = $CURR_CRIT;
@aa = @a;
shift @aa;
foreach $arg (@aa) {
if ($arg =~ /^class=/) { $tmp_class = substr($arg, 6); }
elsif ($arg =~ /^warn=/) { $tmp_warn = substr($arg, 5); }
elsif ($arg =~ /^crit=/) { $tmp_crit = substr($arg, 5); }
else { unknown("Syntax error in config file, line $line_num"); }
}
# mark the file system as being of overall interest
$Interesting{$fs} = 1;
# Only set these values if the class of the file system is the one that
# we are looking to check. This allows us to put a file system in
# multiple classes (in cases where more than on group wants to know
# about a F.S.) and not have one definition overwritten by another one.
print "about to test $fs now $Class{$fs} tmp $tmp_class dflt $CURR_CLASS opt $opt_C\n" if $opt_d;
next if $tmp_class ne $opt_C;
print "setting $fs to class $tmp_class\n" if $opt_d;
$Class{$fs} = $tmp_class;
$Warn{$fs} = $tmp_warn;
$Crit{$fs} = $tmp_crit;
$Line{$fs} = $line_num;
}
}
else { # syntax error
unknown("Syntax error in config file, line $line_num");
}
}
close(CFG_FILE);
}
sub match
{
my ($fs) = @_;
my @glist = glob($fs);
my @rlist = ();
print "Match glob list is " . join(' ', @glist) . "\n" if $opt_d;
foreach $fs (@glist) {
push @rlist, $fs if $Type{$fs} ne '';
}
print "Match return list is " . join(' ', @rlist) . "\n" if $opt_d;
return @rlist;
}
sub unknown
{
my ($reason) = @_;
print "UNKNOWN: $reason\n";
exit 3;
}