1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
#!/usr/local/bin/perl
# author: Al Tobey <albert.tobey@priority-health.com>
# what: monitor diskspace using the host-resources mib
# license: GPL - http://www.fsf.org/licenses/gpl.txt
#
# Todo:
use strict;
require 5.6.0;
use lib qw( /opt/nagios/libexec );
use utils qw(%ERRORS $TIMEOUT &print_revision &support &usage);
use SNMP 5.0;
use Getopt::Long;
use vars qw( $exit $message $opt_version $opt_timeout $opt_help $opt_command $opt_host $opt_community $opt_verbose $opt_warning $opt_critical $opt_port $opt_mountpoint $opt_stats $snmp_session $PROGNAME $TIMEOUT %mounts );
$PROGNAME = "snmp_disk_monitor.pl";
$opt_verbose = undef;
$opt_host = undef;
$opt_community = 'public';
$opt_command = undef;
$opt_warning = 99;
$opt_critical = 100;
$opt_port = 161;
$opt_stats = undef;
$message = undef;
$exit = 'OK';
%mounts = ();
sub process_options {
my( $opt_crit, $opt_warn ) = ();
Getopt::Long::Configure( 'bundling' );
GetOptions(
'V' => \$opt_version, 'version' => \$opt_version,
'v' => \$opt_verbose, 'verbose' => \$opt_verbose,
'h' => \$opt_help, 'help' => \$opt_help,
's' => \$opt_stats, 'statistics' => \$opt_stats,
'H:s' => \$opt_host, 'hostname:s' => \$opt_host,
'p:i' => \$opt_port, 'port:i' => \$opt_port,
'C:s' => \$opt_community, 'community:s' => \$opt_community,
'c:i' => \$opt_crit, 'critical:i' => \$opt_crit,
'w:i' => \$opt_warn, 'warning:i' => \$opt_warn,
't:i' => \$TIMEOUT, 'timeout:i' => \$TIMEOUT,
'm:s' => \$opt_mountpoint, 'mountpoint:s'=> \$opt_mountpoint
);
if ( defined($opt_version) ) { local_print_revision(); }
if ( defined($opt_verbose) ) { $SNMP::debugging = 1; }
if ( !defined($opt_host) || defined($opt_help) || !defined($opt_mountpoint) ) {
print_help();
exit $ERRORS{UNKNOWN};
}
$opt_mountpoint = [ split(/,/, $opt_mountpoint) ];
}
sub local_print_revision {
print_revision( $PROGNAME, '$Revision: 1.1 $ ' )
}
sub print_usage {
print "Usage: $PROGNAME -H <host> -C <snmp_community> [-s] [-w <low>,<high>] [-c <low>,<high>] [-t <timeout>] -m <mountpoint>\n";
}
sub print_help {
local_print_revision();
print "Copyright (c) 2002 Al Tobey <albert.tobey\@priority-health.com>\n\n",
"SNMP Disk Monitor plugin for Nagios\n\n";
print_usage();
print <<EOT;
-v, --verbose
print extra debugging information
-h, --help
print this help message
-H, --hostname=HOST
name or IP address of host to check
-C, --community=COMMUNITY NAME
community name for the host's SNMP agent
-m, --mountpoint=MOUNTPOINT
a mountpoint, or a comma delimited list of mountpoints
-w, --warning=INTEGER
percent of disk used to generate WARNING state (Default: 99)
-c, --critical=INTEGER
percent of disk used to generate CRITICAL state (Default: 100)
-s, --statistics
output statistics in Nagios format
EOT
}
sub verbose (@) {
return if ( !defined($opt_verbose) );
print @_;
}
sub check_for_errors {
if ( $snmp_session->{ErrorNum} ) {
print "UNKNOWN - error retrieving SNMP data: $snmp_session->{ErrorStr}\n";
exit $ERRORS{UNKNOWN};
}
}
# =========================================================================== #
# =====> MAIN
# =========================================================================== #
process_options();
alarm( $TIMEOUT ); # make sure we don't hang Nagios
$snmp_session = new SNMP::Session(
DestHost => $opt_host,
Community => $opt_community,
RemotePort => $opt_port,
Version => '2c'
);
# retrieve the data from the remote host
my( $mps, $alloc, $size, $used ) = $snmp_session->bulkwalk( 0, 4, [['hrStorageDescr'],['hrStorageAllocationUnits'],['hrStorageSize'],['hrStorageUsed']] );
check_for_errors();
alarm( 0 ); # all done with the network connection
# move all the data into a nice, convenient hash for processing
foreach my $mp ( @$mps ) { $mounts{$mp->iid}->{mountpoint} = $mp->val; }
foreach my $a ( @$alloc ) { $mounts{$a->iid}->{alloc_units} = $a->val; }
foreach my $si ( @$size ) {
if ( exists($mounts{$si->iid}->{alloc_units}) ) {
$mounts{$si->iid}->{size} = $si->val * $mounts{$si->iid}->{alloc_units};
}
else {
$mounts{$si->iid}->{size} = $si->val;
}
}
foreach my $us ( @$used ) {
if ( exists($mounts{$us->iid}->{alloc_units}) ) {
$mounts{$us->iid}->{used} = $us->val * $mounts{$us->iid}->{alloc_units};
}
else {
$mounts{$us->iid}->{used} = $us->val;
}
}
# now find the mountpoint or mountpoints that were actually requested and push onto an array for output
my @matches = ();
foreach my $mp ( @$opt_mountpoint ) {
my $found = scalar(@matches); # count all matches
foreach my $key ( keys(%mounts) ) {
if ( $mounts{$key}->{mountpoint} eq $mp ) {
# find the percentate - eval to avoid divide by zero errors
eval { $mounts{$key}->{percent_used} = $mounts{$key}->{used} / $mounts{$key}->{size} };
$mounts{$key}->{percent_used} =~ s/^0\.([0-9]{1,2})([0-9]?).*/\1/; # truncate
if ( $2 >= 5 ) { $mounts{$key}->{percent_used}++ }; # round the number number
verbose "mountpoint $mp has ", $mounts{$key}->{percent_used}, "% used, ",
$mounts{$key}->{size}, " bytes and ",$mounts{$key}->{used}, " used\n";
push( @matches, $mounts{$key} );
}
}
if ( scalar(@matches) == $found ) {
print "UNKNOWN - could not locate mountpoint $mp on host\n";
exit $ERRORS{UNKNOWN};
}
}
# now run through and check the thresholds
foreach my $mp ( @matches ) {
if ( $mp->{percent_used} >= $opt_warning ) {
$exit = 'WARNING';
if ( $mp->{percent_used} >= $opt_critical ) { $exit = 'CRITICAL'; }
}
$message .= $mp->{percent_used}.'% used on '.$mp->{mountpoint}.', ';
}
$message =~ s/,\s*$//;
# append statistics if requested
if ( defined($opt_stats) ) {
my @tmp = ();
foreach my $mp ( @matches ) {
push( @tmp, join(',',$mp->{mountpoint},$mp->{size},$mp->{used}) );
}
$message .= '|'.join( ':', @tmp );
}
print "Disk $exit - $message\n";
exit $ERRORS{$exit};
|