#!/usr/bin/perl -w ############################## check_snmp_storage ############## # Version : 2.1.0 # Date : Jun 1 2007 # Author : Patrick Proy ( patrick at proy.org) # Help : http://nagios.manubulon.com # License : GPL - http://www.fsf.org/licenses/gpl.txt # TODO : # Contribs : Dimo Velev, Makina Corpus, A. Greiner-B\ufffdr ################################################################# # # help : ./check_snmp_storage -h use strict; use Net::SNMP; use Getopt::Long; # Icinga specific my %ERRORS = ('OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3, 'DEPENDENT' => 4); # SNMP Datas my $hrStorageTable_storage_table = '1.3.6.1.2.1.25.2.3.1'; my $hrStorageTable_storagetype_table = '1.3.6.1.2.1.25.2.3.1.2'; my $hrStorageTable_index_table = '1.3.6.1.2.1.25.2.3.1.1'; my $hrStorageTable_descr_table = '1.3.6.1.2.1.25.2.3.1.3'; my $hrStorageTable_size_table = '1.3.6.1.2.1.25.2.3.1.5.'; my $hrStorageTable_used_table = '1.3.6.1.2.1.25.2.3.1.6.'; my $hrStorageTable_alloc_units = '1.3.6.1.2.1.25.2.3.1.4.'; my $dskTable_storage_table = '1.3.6.1.4.1.2021.9.1'; my $dskTable_index_table = '1.3.6.1.4.1.2021.9.1.1'; my $dskTable_descr_table = '1.3.6.1.4.1.2021.9.1.2'; my $dskTable_size_table = '1.3.6.1.4.1.2021.9.1.6.'; my $dskTable_avail_table = '1.3.6.1.4.1.2021.9.1.7.'; my $dskTable_used_table = '1.3.6.1.4.1.2021.9.1.8.'; my $hrFSTable_fstable = '1.3.6.1.2.1.25.3.8'; #Storage types definition - from /usr/share/snmp/mibs/HOST-RESOURCES-TYPES.txt my %hrStorage; $hrStorage{"Other"} = '1.3.6.1.2.1.25.2.1.1'; $hrStorage{"1.3.6.1.2.1.25.2.1.1"} = 'Other'; $hrStorage{"Ram"} = '1.3.6.1.2.1.25.2.1.2'; $hrStorage{"1.3.6.1.2.1.25.2.1.2"} = 'Ram'; $hrStorage{"VirtualMemory"} = '1.3.6.1.2.1.25.2.1.3'; $hrStorage{"1.3.6.1.2.1.25.2.1.3"} = 'VirtualMemory'; $hrStorage{"FixedDisk"} = '1.3.6.1.2.1.25.2.1.4'; $hrStorage{"1.3.6.1.2.1.25.2.1.4"} = 'FixedDisk'; $hrStorage{"RemovableDisk"} = '1.3.6.1.2.1.25.2.1.5'; $hrStorage{"1.3.6.1.2.1.25.2.1.5"} = 'RemovableDisk'; $hrStorage{"FloppyDisk"} = '1.3.6.1.2.1.25.2.1.6'; $hrStorage{"1.3.6.1.2.1.25.2.1.6"} = 'FloppyDisk'; $hrStorage{"CompactDisk"} = '1.3.6.1.2.1.25.2.1.7'; $hrStorage{"1.3.6.1.2.1.25.2.1.7"} = 'CompactDisk'; $hrStorage{"RamDisk"} = '1.3.6.1.2.1.25.2.1.8'; $hrStorage{"1.3.6.1.2.1.25.2.1.8"} = 'RamDisk'; $hrStorage{"FlashMemory"} = '1.3.6.1.2.1.25.2.1.9'; $hrStorage{"1.3.6.1.2.1.25.2.1.9"} = 'FlashMemory'; $hrStorage{"NetworkDisk"} = '1.3.6.1.2.1.25.2.1.10'; $hrStorage{"1.3.6.1.2.1.25.2.1.10"} = 'NetworkDisk'; # Host Resources File System definitions my %hrFSTable = ( "hrFSIndex" => "1.3.6.1.2.1.25.3.8.1.1", "1.3.6.1.2.1.25.3.8.1.1" => "hrFSIndex", "hrFSMountPoint" => "1.3.6.1.2.1.25.3.8.1.2", "1.3.6.1.2.1.25.3.8.1.2" => "hrFSMountPoint", "hrFSRemoteMountPoint" => "1.3.6.1.2.1.25.3.8.1.3", "1.3.6.1.2.1.25.3.8.1.3" => "hrFSRemoteMountPoint", "hrFSType" => "1.3.6.1.2.1.25.3.8.1.4", "1.3.6.1.2.1.25.3.8.1.4" => "hrFSType", "hrFSAccess" => "1.3.6.1.2.1.25.3.8.1.5", "1.3.6.1.2.1.25.3.8.1.5" => "hrFSAccess", "hrFSBootable" => "1.3.6.1.2.1.25.3.8.1.6", "1.3.6.1.2.1.25.3.8.1.6" => "hrFSBootable", "hrFSStorageIndex" => "1.3.6.1.2.1.25.3.8.1.7", "1.3.6.1.2.1.25.3.8.1.7" => "hrFSStorageIndex", "hrFSLastFullBackupDate" => "1.3.6.1.2.1.25.3.8.1.8", "1.3.6.1.2.1.25.3.8.1.8" => "hrFSLastFullBackupDate", "hrFSLastPartialBackupDate" => "1.3.6.1.2.1.25.3.8.1.9", "1.3.6.1.2.1.25.3.8.1.9" => "hrFSLastPartialBackupDate", ); # Globals my $Name = 'check_snmp_storage'; my $VERSION = "2.1.0"; my $o_host = undef; # hostname my $o_community = undef; # community my $o_port = 161; # port my $o_domain = 'udp/ipv4'; # Default to UDP over IPv4 my $o_version2 = undef; #use snmp v2c my $o_descr = undef; # description filter my $o_storagetype = undef; # parse storage type also my $o_writable = undef; # Check if FS is writable my $o_warn = undef; # warning limit my $o_crit = undef; # critical limit my $o_help = undef; # wan't some help ? my $o_type = undef; # pl, pu, mbl, mbu my @o_typeok = ("pu", "pl", "bu", "bl"); # valid values for o_type my $o_verb = undef; # verbose mode my $o_version = undef; # print version my $o_noreg = undef; # Do not use Regexp for name my $o_sum = undef; # add all storage before testing my $o_index = undef; # Parse index instead of description my $o_negate = undef; # Negate the regexp if set my $o_okifempty = undef; # Consider OK if no disks found my $o_timeout = 5; # Default 5s Timeout my $o_perf = undef; # Output performance data my $o_short = undef; # Short output parameters my @o_shortL = undef; # output type,where,cut my $o_reserve = 0; # % reserved blocks (A. Greiner-B\ufffdr patch) my $o_giga = undef; # output and levels in gigabytes instead of megabytes my $o_dsktable = undef; # use dskTable instead of default hrStorageTable # SNMPv3 specific my $o_login = undef; # Login for snmpv3 my $o_passwd = undef; # Pass for snmpv3 my $v3protocols = undef; # V3 protocol list. my $o_authproto = 'md5'; # Auth protocol my $o_privproto = 'des'; # Priv protocol my $o_privpass = undef; # priv password my $UOM_float = 4; # decimal places # SNMP Message size parameter (Makina Corpus contrib) my $o_octetlength = undef; # functions sub p_version { print "$Name version : $VERSION\n"; } sub print_usage { print "Usage: $Name [-v] -H -C [-2] | (-l login -x passwd [-X pass -L ,]) [-p ] [-P ] [-u] -m [-q storagetype] -w -c [-t ] [-T pl|pu|bl|bu ] [-r -s -i -G] [-e] [-O] [-W] [-S 0|1[,1,]] [-o ] [-R <% reserved>]\n"; } sub round ($$) { sprintf "%.$_[1]f", $_[0]; } sub is_pattern_valid { # Test for things like "" or "+5-i" my $pat = shift; if (!defined($pat)) { $pat = " "; } # Just to get rid of compilation time warnings return eval { "" =~ /$pat/; 1 } || 0; } # Get the alarm signal (just in case snmp timout screws up) $SIG{'ALRM'} = sub { # print ("ERROR: General time-out (Alarm signal)\n"); # exit $ERRORS{"UNKNOWN"}; print("Waiting for info\n"); exit $ERRORS{"OK"}; }; sub isnnum { # Return true if arg is not a number my $num = shift; if ($num =~ /^-?(\d+\.?\d*)|(^\.\d+)$/) { return 0; } return 1; } sub help { print "\nSNMP Disk Monitor for Icinga/Nagios/Naemon/Shinken, Version ", $VERSION, "\n"; print "(c)2004-2007 Patrick Proy\n\n"; print_usage(); print < warn and critical if %used > crit -v, --verbose print extra debugging information (and lists all storages) -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 (implies SNMP v1) -2, --v2c Use snmp v2c -l, --login=LOGIN ; -x, --passwd=PASSWD Login and auth password for snmpv3 authentication If no priv password exists, implies AuthNoPriv -X, --privpass=PASSWD Priv password for snmpv3 (AuthPriv protocol) -L, --protocols=, : Authentication protocol (md5|sha : default md5) : Priv protocole (des|aes : default des) -x, --passwd=PASSWD Password for snmpv3 authentication -p, --port=PORT SNMP port (Default 161) -P, --protocol=PROTOCOL Network protocol to be used ['udp/ipv4'] : UDP over IPv4 'udp/ipv6' : UDP over IPv6 'tcp/ipv4' : TCP over IPv4 'tcp/ipv6' : TCP over IPv6 -u, --dsktable use dskTable instead of default hrStorageTable; cannot be used with -q -m, --name=NAME Name in description OID (can be mounpoints '/home' or 'Swap Space'...) This is treated as a regexp : -m /var will match /var , /var/log, /opt/var ... Test it before, because there are known bugs (ex : trailling /) No trailing slash for mountpoints ! -q, --storagetype=[Other|Ram|VirtualMemory|FixedDisk|RemovableDisk|FloppyDisk CompactDisk|RamDisk|FlashMemory|NetworkDisk] Also check the storage type in addition of the name It is possible to use regular expressions ( "FixedDisk|FloppyDisk" ) -r, --noregexp Do not use regexp to match NAME in description OID -s, --sum Add all storages that match NAME (used space and total space) THEN make the tests. -W, --writable Check if disk is not Writeable -i, --index Parse index table instead of description table to select storage -e, --exclude Select all storages except the one(s) selected by -m No action on storage type selection -O, --okifempty Consider OK instead of UNKNOWN if no storage found with given criteria -T, --type=TYPE pl : calculate percent left pu : calculate percent used (Default) bl : calculate MegaBytes left bu : calculate MegaBytes used -w, --warn=INTEGER percent / MB of disk used to generate WARNING state you can add the % sign -c, --critical=INTEGER percent / MB of disk used to generate CRITICAL state you can add the % sign -R, --reserved=INTEGER % reserved blocks for superuser For ext2/3 filesystems, it is 5% by default -G, --gigabyte output, warning & critical levels in gigabytes -f, --perfparse, --perfdata Performance data output -S, --short=[,,] : Make the output shorter : 0 : only print the global result except the disk in warning or critical ex: "< 80% : OK" 1 : Don't print all info for every disk ex : "/ : 66 %used (< 80) : OK" : (optional) if = 1, put the OK/WARN/CRIT at the beginning : take the first caracters or last if n<0 -o, --octetlength=INTEGER max-size of the SNMP message, usefull in case of Too Long responses. Be carefull with network filters. Range 484 - 65535, default are usually 1472,1452,1460 or 1440. -t, --timeout=INTEGER timeout for SNMP in seconds (Default: 5) -V, --version prints version number Note : with T=pu or T=bu : OK < warn < crit with T=pl ot T=bl : crit < warn < OK If multiple storage are selected, the worse condition will be returned i.e if one disk is critical, the return is critical example : Browse storage list :