2 # author: Al Tobey <albert.tobey@priority-health.com>
3 # what: monitor diskspace using the host-resources mib
4 # license: GPL - http://www.fsf.org/licenses/gpl.txt
10 use lib
qw( /opt/nagios/libexec );
11 use utils
qw(%ERRORS $TIMEOUT &print_revision &support &usage);
14 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 );
16 $PROGNAME = "snmp_disk_monitor.pl";
19 $opt_community = 'public';
30 my( $opt_crit, $opt_warn ) = ();
31 Getopt::Long::Configure( 'bundling' );
33 'V' => \$opt_version, 'version' => \$opt_version,
34 'v' => \$opt_verbose, 'verbose' => \$opt_verbose,
35 'h' => \$opt_help, 'help' => \$opt_help,
36 's' => \$opt_stats, 'statistics' => \$opt_stats,
37 'H:s' => \$opt_host, 'hostname:s' => \$opt_host,
38 'p:i' => \$opt_port, 'port:i' => \$opt_port,
39 'C:s' => \$opt_community, 'community:s' => \$opt_community,
40 'c:i' => \$opt_crit, 'critical:i' => \$opt_crit,
41 'w:i' => \$opt_warn, 'warning:i' => \$opt_warn,
42 't:i' => \$TIMEOUT, 'timeout:i' => \$TIMEOUT,
43 'm:s' => \$opt_mountpoint, 'mountpoint:s'=> \$opt_mountpoint
45 if ( defined($opt_version) ) { local_print_revision(); }
46 if ( defined($opt_verbose) ) { $SNMP::debugging = 1; }
47 if ( !defined($opt_host) || defined($opt_help) || !defined($opt_mountpoint) ) {
49 exit $ERRORS{UNKNOWN};
51 $opt_mountpoint = [ split(/,/, $opt_mountpoint) ];
54 sub local_print_revision {
55 print_revision( $PROGNAME, '$Revision: 82 $ ' )
59 print "Usage: $PROGNAME -H <host> -C <snmp_community> [-s] [-w <low>,<high>] [-c <low>,<high>] [-t <timeout>] -m <mountpoint>\n";
63 local_print_revision();
64 print "Copyright (c) 2002 Al Tobey <albert.tobey\@priority-health.com>\n\n",
65 "SNMP Disk Monitor plugin for Nagios\n\n";
69 print extra debugging information
71 print this help message
73 name or IP address of host to check
74 -C, --community=COMMUNITY NAME
75 community name for the host's SNMP agent
76 -m, --mountpoint=MOUNTPOINT
77 a mountpoint, or a comma delimited list of mountpoints
79 percent of disk used to generate WARNING state (Default: 99)
80 -c, --critical=INTEGER
81 percent of disk used to generate CRITICAL state (Default: 100)
83 output statistics in Nagios format
88 return if ( !defined($opt_verbose) );
92 sub check_for_errors
{
93 if ( $snmp_session->{ErrorNum
} ) {
94 print "UNKNOWN - error retrieving SNMP data: $snmp_session->{ErrorStr}\n";
95 exit $ERRORS{UNKNOWN
};
99 # =========================================================================== #
101 # =========================================================================== #
104 alarm( $TIMEOUT ); # make sure we don't hang Nagios
106 $snmp_session = new SNMP
::Session
(
107 DestHost
=> $opt_host,
108 Community
=> $opt_community,
109 RemotePort
=> $opt_port,
113 # retrieve the data from the remote host
114 my( $mps, $alloc, $size, $used ) = $snmp_session->bulkwalk( 0, 4, [['hrStorageDescr'],['hrStorageAllocationUnits'],['hrStorageSize'],['hrStorageUsed']] );
117 alarm( 0 ); # all done with the network connection
119 # move all the data into a nice, convenient hash for processing
120 foreach my $mp ( @
$mps ) { $mounts{$mp->iid}->{mountpoint
} = $mp->val; }
121 foreach my $a ( @
$alloc ) { $mounts{$a->iid}->{alloc_units
} = $a->val; }
122 foreach my $si ( @
$size ) {
123 if ( exists($mounts{$si->iid}->{alloc_units
}) ) {
124 $mounts{$si->iid}->{size
} = $si->val * $mounts{$si->iid}->{alloc_units
};
127 $mounts{$si->iid}->{size
} = $si->val;
130 foreach my $us ( @
$used ) {
131 if ( exists($mounts{$us->iid}->{alloc_units
}) ) {
132 $mounts{$us->iid}->{used
} = $us->val * $mounts{$us->iid}->{alloc_units
};
135 $mounts{$us->iid}->{used
} = $us->val;
139 # now find the mountpoint or mountpoints that were actually requested and push onto an array for output
141 foreach my $mp ( @
$opt_mountpoint ) {
142 my $found = scalar(@matches); # count all matches
143 foreach my $key ( keys(%mounts) ) {
144 if ( $mounts{$key}->{mountpoint
} eq $mp ) {
146 # find the percentate - eval to avoid divide by zero errors
147 eval { $mounts{$key}->{percent_used
} = $mounts{$key}->{used
} / $mounts{$key}->{size
} };
148 $mounts{$key}->{percent_used
} =~ s/^0\.([0-9]{1,2})([0-9]?).*/\1/; # truncate
149 if ( $2 >= 5 ) { $mounts{$key}->{percent_used
}++ }; # round the number number
151 verbose
"mountpoint $mp has ", $mounts{$key}->{percent_used
}, "% used, ",
152 $mounts{$key}->{size
}, " bytes and ",$mounts{$key}->{used
}, " used\n";
154 push( @matches, $mounts{$key} );
157 if ( scalar(@matches) == $found ) {
158 print "UNKNOWN - could not locate mountpoint $mp on host\n";
159 exit $ERRORS{UNKNOWN
};
163 # now run through and check the thresholds
164 foreach my $mp ( @matches ) {
165 if ( $mp->{percent_used
} >= $opt_warning ) {
167 if ( $mp->{percent_used
} >= $opt_critical ) { $exit = 'CRITICAL'; }
169 $message .= $mp->{percent_used
}.'% used on '.$mp->{mountpoint
}.', ';
171 $message =~ s/,\s*$//;
173 # append statistics if requested
174 if ( defined($opt_stats) ) {
176 foreach my $mp ( @matches ) {
177 push( @tmp, join(',',$mp->{mountpoint
},$mp->{size
},$mp->{used
}) );
179 $message .= '|'.join( ':', @tmp );
182 print "Disk $exit - $message\n";