Nagios SNMP load check plugin improved

Nagios is a powerful monitoring system that enables organizations to identify and resolve IT infrastructure problems before they affect critical business processes.

Nagios SNMP load check plugin improved

Postby lik » Mon Apr 04, 2011 11:05 am

It was quite hard to find ready-to-use SNMP-only Nagios load-average check plugin which meets the following needs:

* works via SNMP protocol (v1, v2, v3)
* supports 4 statuses (ok, error, warning, unknown)
* does not require load thresholds to be passed as parameters to the plugin for each host (uses the values on the host populated via snmpd.conf )

Finally, based on the check_load_ucd plugin with a couple of improvements made with statuses/return codes, the following working plugin appeared:

Code: Select all
perl check_load_ucd13_beta.pl -h

Code: Select all
Usage: snmp_load_warning [-h] [-t timeout] [-v] [-C community] [-p port] [-s 1|2|3] -H hostname 

SNMP version 3 specific: [-u username] [-o authpass] [-r authprot] [-O privpass] [-R privprot]

   Check Load Average via UCD SNMP MIB
   e.g: used on linux in net-snmp agent.

-t (--timeout)      Timeout in seconds (default=15)
-H (--hostname)     Host to monitor
-s (--snmpvers)     SNMP Version [1|2|3] (default=2)
-C (--community)    SNMP Community (default=public)
-p (--port)         SNMP Port (default=161)
-h (--help)         Help
-v (--verbose)      Print some useful information

SNMP version 3 specific arguments:
-u (--username)     Security Name
-o (--authpassword) Authentication password
-r (--authprotocol) Authentication protocol [md5|sha]
-O (--privpassword) Privacy password
-R (--privprotocol) Privacy protocol [des|aes|3des]


Source code of the plugin can be found below:
Code: Select all
#! /usr/bin/perl -w

# Check Load Average via SNMP.
# Plugin uses UCD SNMP MIB (1.3.6.1.4.1.2021).
# Used in net-snmp packages on linux.
#
# This program comes with ABSOLUTELY NO WARRANTY
# Based on the check_load_ucd (v1.3) plugin
# Modified by Evgeniy G and Evgeniy C
# v0.2

############################################################################


use POSIX;
use strict;
use Getopt::Long;

use lib ".";
use lib "/usr/lib/nagios/plugins";
use lib "/usr/lib64/nagios/plugins";
use lib "/usr/local/nagios/libexec";

use utils qw(%ERRORS);

use Net::SNMP qw(oid_lex_sort oid_base_match);

my ($opt_help,$opt_verbose);
my ($opt_timeout);
my ($opt_hostname,$opt_community,$opt_port,$opt_snmpvers);
my ($opt_username,$opt_authpasswd,$opt_authproto);
my ($opt_privpasswd,$opt_privproto);
my ($PROGNAME,$REVISION);
my ($state,$msg);

use constant DEFAULT_TIMEOUT            =>15;
use constant DEFAULT_PORT               =>161;
use constant DEFAULT_COMMUNITY          =>"public";
use constant DEFAULT_SNMPVERS           =>"2";
use constant DEFAULT_PRIVPROTO          =>"DES";
use constant DEFAULT_AUTHPROTO          =>"MD5";

#  UCD SNMP MIB
my $laTable                             ="1.3.6.1.4.1.2021.10";
my  $laEntry                            ="1.3.6.1.4.1.2021.10.1";
my   $laIndex_tabular                   ="1.3.6.1.4.1.2021.10.1.1";
my   $laNames_tabular                   ="1.3.6.1.4.1.2021.10.1.2";
my   $laLoad_tabular                    ="1.3.6.1.4.1.2021.10.1.3";
my   $laConfig_tabular                  ="1.3.6.1.4.1.2021.10.1.4";
my   $laLoadInt_tabular                 ="1.3.6.1.4.1.2021.10.1.5";
my   $laLoadFloat_tabular               ="1.3.6.1.4.1.2021.10.1.6";
my   $laErrorFlag_tabular               ="1.3.6.1.4.1.2021.10.1.100";
my   $laErrorMsg_tabular                ="1.3.6.1.4.1.2021.10.1.101";


$ENV{'PATH'}='';
$ENV{'BASH_ENV'}='';
$ENV{'ENV'}='';
$PROGNAME = "snmp_load_warning";
$REVISION = "0.1";

# checking commandline arguments
my $arg_status = check_args();
if ($arg_status){
  print "ERROR: some arguments wrong\n";
  exit $ERRORS{"UNKNOWN"};
}

# set alarmhandler for timeout handling
$SIG{'ALRM'} = sub {
  print ("ERROR: plugin timed out after $opt_timeout seconds \n");
  exit $ERRORS{"UNKNOWN"};
};

alarm($opt_timeout);

# let's see if the server wants to speak with us
my ($snmp_session,$snmp_error)=open_snmp_session($opt_hostname);
if ( ! defined ($snmp_session)) {
  print "ERROR: Could not open connection: $snmp_error \n";
  exit $ERRORS{'UNKNOWN'};
}

$snmp_session->translate(['-endofmibview'=>0,'-nosuchobject'=>0,'-nosuchinstance'=>0]);

#  get laTable
my $p_laTable=get_table ($laTable);

$snmp_session->close;

if ( $opt_verbose ) {
  print_laTable ();
}

# set default values for program exit

# cyber start here
my $first = $p_laTable->{$laLoad_tabular.".1"};
my $second = $p_laTable->{$laLoad_tabular.".2"};
my $third = $p_laTable->{$laLoad_tabular.".3"};

my $first_flag = $p_laTable->{$laErrorFlag_tabular.".1"};
my $second_flag = $p_laTable->{$laErrorFlag_tabular.".2"};
my $third_flag = $p_laTable->{$laErrorFlag_tabular.".3"};

my $third_level = $p_laTable->{$laConfig_tabular.".3"};

if ($first_flag){
    print "Load average: $first, $second, $third\n";
    exit $ERRORS{'CRITICAL'};
} else {
    if (floor($first) >= $third_level || scalar $second_flag || scalar $third_flag){
        print "Load average: $first, $second, $third\n";
        exit $ERRORS{'WARNING'};
    } else {
        print "LOAD OK: $first, $second, $third\n";
        exit $ERRORS{'OK'};
    }
}
# cyber end here

#--------------------------------------------------------------------------#
# S U B R O U T I N E S                                                    #
#--------------------------------------------------------------------------#

sub open_snmp_session {
  my ($l_host)=@_;

  my ($snmp_session,$snmp_error);

  # open SNMP Session to Server
  if ( $opt_snmpvers eq "3" ) {
    if ( defined ($opt_authpasswd)) {
      if ( defined ($opt_privpasswd)) {
        ($snmp_session,$snmp_error)=Net::SNMP->session(
            -hostname           =>      $l_host,
            -port               =>      $opt_port || 161,
            -timeout            =>      2,
            -retries            =>      2,
            -maxmsgsize         =>      16384,
            -version            =>      $opt_snmpvers,
            -username           =>      $opt_username,
            -authpassword       =>      $opt_authpasswd,
            -authprotocol       =>      $opt_authproto,
            -privpassword       =>      $opt_privpasswd,
            -privprotocol       =>      $opt_privproto,
            );
      } else {
        ($snmp_session,$snmp_error)=Net::SNMP->session(
            -hostname           =>      $l_host,
            -port               =>      $opt_port || 161,
            -timeout            =>      2,
            -retries            =>      2,
            -maxmsgsize         =>      16384,
            -version            =>      $opt_snmpvers,
            -username           =>      $opt_username,
            -authpassword       =>      $opt_authpasswd,
            -authprotocol       =>      $opt_authproto,
            );
      }
    } else {
        ($snmp_session,$snmp_error)=Net::SNMP->session(
            -hostname           =>      $l_host,
            -port               =>      $opt_port || 161,
            -timeout            =>      2,
            -retries            =>      2,
            -maxmsgsize         =>      16384,
            -version            =>      $opt_snmpvers,
            -username           =>      $opt_username,
            );
    }
  } else {
    ($snmp_session,$snmp_error)=Net::SNMP->session(
        -hostname       =>      $l_host,
        -community      =>      $opt_community || 'public',
        -port           =>      $opt_port || 161,
        -timeout        =>      2,
        -retries        =>      2,
        -maxmsgsize     =>      16384,
        -version        =>      $opt_snmpvers,
        );
  }
  return ($snmp_session,$snmp_error);
}

sub  create_msg {
  my ($l_txt,$l_msg)=@_;

  if (! defined $l_txt) {return};

  if (defined $$l_msg) {
    $$l_msg.=", ";
  }
  $$l_msg.=$l_txt;
}

sub get_table {
  my ($l_oid)=@_;

  my $l_snmp_result=$snmp_session->get_table(
        -baseoid        =>      $l_oid
        );

  if ( ! defined ($l_snmp_result)) {
  #if ($snmp_session->error_status != 0) {
#    print "ERROR %d: get_table: ",$snmp_session->error_status,$snmp_session->error,"\n";
    print "ERROR - ",$snmp_session->error,"\n";
    $snmp_session->close;
    exit $ERRORS{'UNKNOWN'};
  }
  return $l_snmp_result;
}

sub check_args {
  Getopt::Long::Configure('bundling');
  GetOptions
        (
         "v"                    => \$opt_verbose,
         "verbose"              => \$opt_verbose,
         "h|?"                  => \$opt_help,
         "help"                 => \$opt_help,
         "t=i"                  => \$opt_timeout,
         "timeout=i"            => \$opt_timeout,
         "H=s"                  => \$opt_hostname,
         "hostname=s"           => \$opt_hostname,
         "C=s"                  => \$opt_community,
         "community=s"          => \$opt_community,
         "p=i"                  => \$opt_port,
         "port=i"               => \$opt_port,
         "s=s"                  => \$opt_snmpvers,
         "snmpvers=s"           => \$opt_snmpvers,
         "u=s"                  => \$opt_username,
         "username=s"           => \$opt_username,
         "o=s"                  => \$opt_authpasswd,
         "authpass=s"           => \$opt_authpasswd,
         "r=s"                  => \$opt_authproto,
         "authprot=s"           => \$opt_authproto,
         "O=s"                  => \$opt_privpasswd,
         "privpass=s"           => \$opt_privpasswd,
         "R=s"                  => \$opt_privproto,
         "privprot=s"           => \$opt_privproto,
         );

  if ($opt_help) {
    print_help();
    exit $ERRORS{'OK'};
  }

  if ( ! defined($opt_hostname)){
    print "\nERROR: Hostname not defined\n\n";
    print_usage();
    exit $ERRORS{'UNKNOWN'};
  }

  unless (defined $opt_snmpvers) {
    $opt_snmpvers = DEFAULT_SNMPVERS;
  }
  if (($opt_snmpvers ne "1") && ($opt_snmpvers ne "2") && ($opt_snmpvers ne "3")) {
    printf ("\nERROR: SNMP Version %s unknown\n",$opt_snmpvers);
    print_usage();
    exit $ERRORS{'UNKNOWN'};
  }

  unless (defined $opt_timeout) {
    $opt_timeout = DEFAULT_TIMEOUT;
  }

  unless (defined $opt_port) {
    $opt_port = DEFAULT_PORT;
  }

  unless (defined $opt_community) {
    $opt_community = DEFAULT_COMMUNITY;
  }

  if (defined $opt_privpasswd) {
    unless (defined $opt_privproto) {
      $opt_privproto = DEFAULT_PRIVPROTO;
    }
  }

  if (defined $opt_authpasswd) {
    unless (defined $opt_authproto) {
      $opt_authproto = DEFAULT_AUTHPROTO;
    }
  }

  if ($opt_snmpvers eq 3) {
    unless (defined $opt_username) {
      printf ("\nERROR: SNMP Version %s: please define username\n",$opt_snmpvers);
      print_usage();
      exit $ERRORS{'UNKNOWN'};
    }
  }

  return $ERRORS{'OK'};
}

sub print_usage {
  print "Usage: $PROGNAME [-h] [-t timeout] [-v] [-C community] [-p port] [-s 1|2|3] -H hostname  \n\n";
  print "SNMP version 3 specific: [-u username] [-o authpass] [-r authprot] [-O privpass] [-R privprot]\n";
}

sub print_help {
  print_usage();
  print "\n";
  print "   Check Load Average via UCD SNMP MIB\n";
  print "   e.g: used on linux in net-snmp agent.\n\n";
  print "-t (--timeout)      Timeout in seconds (default=",DEFAULT_TIMEOUT,")\n";
  print "-H (--hostname)     Host to monitor\n";
  print "-s (--snmpvers)     SNMP Version [1|2|3] (default=",DEFAULT_SNMPVERS,")\n";
  print "-C (--community)    SNMP Community (default=",DEFAULT_COMMUNITY,")\n";
  print "-p (--port)         SNMP Port (default=",DEFAULT_PORT,")\n";
  print "-h (--help)         Help\n";
  print "-v (--verbose)      Print some useful information\n";
  print "\nSNMP version 3 specific arguments:\n";
  print "-u (--username)     Security Name\n";
  print "-o (--authpassword) Authentication password\n";
  print "-r (--authprotocol) Authentication protocol [md5|sha]\n";
  print "-O (--privpassword) Privacy password\n";
  print "-R (--privprotocol) Privacy protocol [des|aes|3des]\n";
  print "\n";
}

sub print_laTable {
  printtable  ("UCD Load Average Table");
  print       ("======================\n");
  foreach my $l_key (oid_lex_sort(keys(%$p_laTable))){
    if (!(oid_base_match($laIndex_tabular,$l_key))) {
      next;
    }
    my $l_val=$p_laTable->{$l_key};
    printtabular("Names",      $p_laTable->{$laNames_tabular.".".$l_val});
    printtabular("Load",         $p_laTable->{$laLoad_tabular.".".$l_val});
    printtabular("Config",        $p_laTable->{$laConfig_tabular.".".$l_val});
    printtabular("Load Int",    $p_laTable->{$laLoadInt_tabular.".".$l_val});
    printtabular("Load Float",     $p_laTable->{$laLoadFloat_tabular.".".$l_val});
    printtabular("Error Flag",     $p_laTable->{$laErrorFlag_tabular.".".$l_val});
    printtabular("Error Message",  $p_laTable->{$laErrorMsg_tabular.".".$l_val});
    print ("\n");
  }
}

sub printhead {
  my ($l_head)=@_;

  printf ("\n%-40s\n",$l_head);
}

sub printtable {
  my ($l_head)=@_;

  printf ("%-40s\n",$l_head);
}

sub printscalar {
  my ($l_arg,$l_oid)=@_;

  printf ("%-35s: %-30s\n",$l_arg,$l_oid);
}

sub printtabular {
  my ($l_arg,$l_oid)=@_;
#! /usr/bin/perl -w

# Check Load Average via SNMP.
# Plugin uses UCD SNMP MIB (1.3.6.1.4.1.2021).
# Used in net-snmp packages on linux.
#
# This program comes with ABSOLUTELY NO WARRANTY
# Based on the check_load_ucd (v1.3) plugin
# Modified by Evgeniy G and Evgeniy C
# v0.2

############################################################################


use POSIX;
use strict;
use Getopt::Long;

use lib ".";
use lib "/usr/lib/nagios/plugins";
use lib "/usr/lib64/nagios/plugins";
use lib "/usr/local/nagios/libexec";

use utils qw(%ERRORS);

use Net::SNMP qw(oid_lex_sort oid_base_match);

my ($opt_help,$opt_verbose);
my ($opt_timeout);
my ($opt_hostname,$opt_community,$opt_port,$opt_snmpvers);
my ($opt_username,$opt_authpasswd,$opt_authproto);
my ($opt_privpasswd,$opt_privproto);
my ($PROGNAME,$REVISION);
my ($state,$msg);

use constant DEFAULT_TIMEOUT            =>15;
use constant DEFAULT_PORT               =>161;
use constant DEFAULT_COMMUNITY          =>"public";
use constant DEFAULT_SNMPVERS           =>"2";
use constant DEFAULT_PRIVPROTO          =>"DES";
use constant DEFAULT_AUTHPROTO          =>"MD5";

#  UCD SNMP MIB
my $laTable                             ="1.3.6.1.4.1.2021.10";
my  $laEntry                            ="1.3.6.1.4.1.2021.10.1";
my   $laIndex_tabular                   ="1.3.6.1.4.1.2021.10.1.1";
my   $laNames_tabular                   ="1.3.6.1.4.1.2021.10.1.2";
my   $laLoad_tabular                    ="1.3.6.1.4.1.2021.10.1.3";
my   $laConfig_tabular                  ="1.3.6.1.4.1.2021.10.1.4";
my   $laLoadInt_tabular                 ="1.3.6.1.4.1.2021.10.1.5";
lik
Founder
Founder
 
Posts: 497
Joined: Wed Dec 15, 2010 3:21 am

Return to Monitoring

 


  • Related topics
    Replies
    Views
    Last post
cron