check_snmp_disk_monitor.pl 6.2 KB

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