[Nagiosplug-devel] network management plugins
Guy Van Den Bergh
guy.vandenbergh at belnet.be
Wed Sep 4 10:48:06 CEST 2002
Hi guys,
I've written a few plugins useful for network management. They all
written in perl, and using snmp for talking to the routers. They are in
attachment:
check_xinterface: an 'extended' plugin for monitoring router interfaces
via snmp. It only uses standard mibs for maximum vendor independence.
check_cisco_env: for monitoring environment of cisco routers
(temperature, power supply, ...)
check_juniper_env: about the same for juniper routers.
They perform well in a production environment, but I've had some memory
leaks when using the embedded perl interpreter. So I've switched off the
interpreter :)
Take a look at it and maybe they are useful for the main plugin
distribution.
Off course any comments are welcome...
Best regards,
--
Guy Van Den Bergh
BELNET -- Network Engineer
Wetenschapsstraat 4
B-1000 Brussel
Tel. +32 2 790.33.33
Fax. +32 2 790.33.34
-------------- next part --------------
#!/usr/bin/perl -wT
#
# check_xinterface - nagios plugin
#
# largely based upon check_ifoperstatus.pl plugin by Christoph Kron
#
#
#
#
# Copyright (C) 2002 Guy Van Den Bergh
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
# Report bugs to: guy at belnet.be
#
# design of the plugin:
# check admin status: if down, then warning; exit
# check operational status: if down, then critical; exit
# check last change, if within 'tolerance' (-l or --last-change option),
# then warning
# get performance data: bits in/out, etc... (implementation to be scheduled later)
# performance data could be checked against older values (bw drops e.g.)
use strict;
use Net::SNMP;
use Getopt::Long;
&Getopt::Long::config('auto_abbrev');
my $status;
my $TIMEOUT = 60;
my %ERRORS = ('UNKNOWN' , '-1',
'OK' , '0',
'WARNING', '1',
'CRITICAL', '2');
my %ciscoEnvMonState = ('1','normal(1)',
'2','warning(2)',
'3','critical(3)',
'4','shutdown(4)',
'5','notPresent(5)',
'6','notFunctioning(6)');
my $state = "UNKNOWN";
my $answer = "";
my $snmpkey = 1;
my $community = "public";
my $port = 161;
my $t_oid;
my @snmpoids;
my %error_oids;
my $snmpCiscoVoltageStatus;
my $snmpCiscoTemperatureStatus;
my $snmpCiscoFanStatus;
my $snmpCiscoSupplyStatus;
my $hostname;
my $session;
my $error;
my $response;
my $value;
my $oid;
my @voltage_errors;
my @temperature_errors;
my @fan_errors;
my @supply_errors;
sub usage {
printf "\nMissing arguments!\n";
printf "\n";
printf "Perl Check Cisco Environment plugin for Nagios\n";
printf "checks status of temperature, fans, ...\n";
printf "usage: \n";
printf "check_cisco_env -c <READCOMMUNITY> -p <PORT> <HOSTNAME>";
printf "\nCopyright (C) 2002 Guy Van Den Bergh\n";
printf "check_cisco_env comes with ABSOLUTELY NO WARRANTY\n";
printf "This programm is licensed under the terms of the ";
printf "GNU General Public License\n(check source code for details)\n";
printf "\n\n";
exit $ERRORS{"UNKNOWN"};
}
# Just in case of problems, let's not hang Nagios
$SIG{'ALRM'} = sub {
print ("ERROR: No snmp response from $hostname (alarm)\n");
exit $ERRORS{"UNKNOWN"};
};
alarm($TIMEOUT);
$status = GetOptions("community=s",\$community,
"port=i",\$port);
if ($status == 0)
{
&usage;
}
#shift;
$hostname = shift || &usage;
($session, $error) = Net::SNMP->session(
-hostname => $hostname,
-community => $community,
-port => $port
);
if (!defined($session)) {
$state='UNKNOWN';
$answer=$error;
print ("$state: $answer");
exit $ERRORS{$state};
}
$snmpCiscoVoltageStatus = '.1.3.6.1.4.1.9.9.13.1.2.1.7';
$snmpCiscoTemperatureStatus = '.1.3.6.1.4.1.9.9.13.1.3.1.6';
$snmpCiscoFanStatus = '.1.3.6.1.4.1.9.9.13.1.4.1.3';
$snmpCiscoSupplyStatus = '.1.3.6.1.4.1.9.9.13.1.5.1.3';
push(@snmpoids,$snmpCiscoVoltageStatus);
push(@snmpoids,$snmpCiscoTemperatureStatus);
push(@snmpoids,$snmpCiscoFanStatus);
push(@snmpoids,$snmpCiscoSupplyStatus);
#
# These four oids all have the same syntax,
# which makes it easy for scripting all four oids at the same time!
#
$answer = "No data returned (Environment MIB not supported)";
# This will be overwritten when there IS data returned!
TABLE:
foreach $t_oid (@snmpoids) {
#
# Now get all relevant oids, and set the plugin output status accordingly.
#
if (!defined($response = $session->get_table($t_oid))) {
$error_oids{$t_oid} = $session->error;
next TABLE;
}
while ( ($oid, $value) = each %$response ) {
if ($value == 1 || $value == 5 || $value == 6) {
# normal, notPresent or notFunctioning
$state = 'OK' if $state =~ /UNKNOWN/;
$answer = "All environment variables normal." if $state eq 'OK';
} elsif ($value == 2) {
# warning
$error_oids{$oid} = $ciscoEnvMonState{$value};
$state = 'WARNING' unless $state =~ /CRITICAL/;
} elsif ($value == 3 || $value == 4) {
# critical or shutdown
$error_oids{$oid} = $ciscoEnvMonState{$value};
$state = 'CRITICAL'
}
}
}
$session->close;
## Here is the place for introducing artificial errors (for debugging).
#
# Now parse all erroneous responses:
#
unless ($state eq 'OK' or $state eq 'UNKNOWN') {
while ( ($oid, $value) = each %error_oids ) {
$value =~ s/\(\d\)//;
if ($oid =~ /$snmpCiscoVoltageStatus\./) {
$oid =~ s/$snmpCiscoVoltageStatus\.//;
push(@voltage_errors, "$value (instance $oid)");
} elsif($oid =~ /$snmpCiscoTemperatureStatus\./) {
$oid =~ s/$snmpCiscoTemperatureStatus\.//;
push(@temperature_errors, "$value (instance $oid)");
} elsif ($oid =~ /$snmpCiscoFanStatus\./) {
$oid =~ s/$snmpCiscoFanStatus\.//;
push(@fan_errors, "$value (fan $oid)");
} elsif ($oid =~ /$snmpCiscoSupplyStatus\./) {
$oid =~ s/$snmpCiscoSupplyStatus\.//;
push(@supply_errors, "$value (PS $oid)");
}
}
#
# And now the final formatting of the output:
#
my $voltage_errors_s = join ";", @voltage_errors if defined $voltage_errors[0];
my $temperature_errors_s = join ";", @temperature_errors if defined $temperature_errors[0];
my $fan_errors_s = join ";", @fan_errors if defined $fan_errors[0];
my $supply_errors_s = join ";", @supply_errors if defined $supply_errors[0];
$answer = "Problems with:<BR>";
$answer .= "Voltage: " . $voltage_errors_s . "<BR>" if defined $voltage_errors_s;
$answer .= "Temperature: " . $temperature_errors_s . "<BR>" if defined $temperature_errors_s;
$answer .= "Fans: " . $fan_errors_s . "<BR>" if defined $fan_errors_s;
$answer .= "Power Supply: " . $supply_errors_s ."<BR>" if defined $supply_errors_s;
}
print ("$answer\n");
exit $ERRORS{$state};
-------------- next part --------------
#!/usr/bin/perl -wT
#
# check_juniper_env - nagios plugin
#
# largely based upon check_ifoperstatus.pl plugin by Christoph Kron
#
#
#
#
# Copyright (C) 2002 Guy Van Den Bergh
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
# Report bugs to: guy at belnet.be
#
# design of the plugin:
# check admin status: if down, then warning; exit
# check operational status: if down, then critical; exit
# check last change, if within 'tolerance' (-l or --last-change option),
# then warning
# get performance data: bits in/out, etc... (implementation to be scheduled later)
# performance data could be checked against older values (bw drops e.g.)
use strict;
use Net::SNMP;
use Getopt::Long;
&Getopt::Long::config('auto_abbrev');
my $status;
my $TIMEOUT = 15;
my %ERRORS = ('UNKNOWN' , '-1',
'OK' , '0',
'WARNING', '1',
'CRITICAL', '2');
my %jnxOperatingState = ('1','unknown(1)',
'2','running(2)',
'3','ready(3)',
'4','reset(4)',
'5','runningAtFullSpeed(5)',
'6','down(6)',
'7','standby(7)');
my $state = "UNKNOWN";
my $answer = "";
my $snmpkey = 1;
my $community = "public";
my $port = 161;
my $t_oid;
my %error_oids;
my $snmpJnxOperatingDescr;
my $snmpJnxOperatingState;
my $snmpJnxOperatingTemp;
my $snmpJnxOperatingCPU;
my $hostname;
my $session;
my $error;
my $response;
my $temp_w;
my $temp_c;
my $cpu_w;
my $cpu_c;
my $value;
my $descr;
my $oid;
my @state_errors;
my @temp_errors;
my @cpu_errors;
sub usage {
printf "\nMissing arguments!\n";
printf "\n";
printf "Perl Check Juniper Environment plugin for Nagios\n";
printf "checks status of temperature, fans, ...\n";
printf "usage: \n";
printf "check_juniper_env --community <READCOMMUNITY> --port <PORT> --temp <warn-temp:critical-temp> --load <warn-cpu:critical-cpu> <HOSTNAME>";
printf "\nCopyright (C) 2002 Guy Van Den Bergh\n";
printf "check_juniper_env comes with ABSOLUTELY NO WARRANTY\n";
printf "This programm is licensed under the terms of the ";
printf "GNU General Public License\n(check source code for details)\n";
printf "\n\n";
exit $ERRORS{"UNKNOWN"};
}
# Just in case of problems, let's not hang Nagios
$SIG{'ALRM'} = sub {
print ("ERROR: No snmp response from $hostname (alarm)\n");
exit $ERRORS{"UNKNOWN"};
};
alarm($TIMEOUT);
$status = GetOptions("community=s",\$community,
"port=i",\$port,
"temp=s",\$temp_w,
"load=s",\$cpu_w);
if ($status == 0)
{
&usage;
}
if ($temp_w =~ /\d+:\d+/ and $cpu_w =~ /\d+:\d+/) {
($temp_w, $temp_c) = split /:/, $temp_w;
($cpu_w, $cpu_c) = split /:/, $cpu_w;
if ($temp_w > $temp_c) {
print "Critical temp is below warning level\n\n";
&usage;
} elsif ($cpu_w > $cpu_c) {
print "Critical CPU is below warning level\n\n";
&usage;
}
} else {
&usage;
}
#shift;
$hostname = shift || &usage;
($session, $error) = Net::SNMP->session(
-hostname => $hostname,
-community => $community,
-port => $port
);
if (!defined($session)) {
$state='UNKNOWN';
$answer=$error;
print ("$state: $answer");
exit $ERRORS{$state};
}
$snmpJnxOperatingDescr = '.1.3.6.1.4.1.2636.3.1.13.1.5';
$snmpJnxOperatingState = '.1.3.6.1.4.1.2636.3.1.13.1.6';
$snmpJnxOperatingTemp = '.1.3.6.1.4.1.2636.3.1.13.1.7';
$snmpJnxOperatingCPU = '.1.3.6.1.4.1.2636.3.1.13.1.8';
$answer = "No data returned (Environment MIB not supported)";
# This will be overwritten when there IS data returned!
#
# get all jnxOperatingState values (see %jnxOperatingState).
#
if (!defined($response = $session->get_table($snmpJnxOperatingState))) {
$error_oids{$snmpJnxOperatingState} = $session->error;
}
while ( ($oid, $value) = each %$response ) {
if ($value == 1 || $value == 2 || $value == 3 || $value == 7) {
# unknown, running, ready or standby
$state = 'OK' if $state =~ /UNKNOWN/;
$answer = "All environment variables normal." if $state =~ /UNKNOWN/;
} elsif ($value == 4 || $value == 5) {
# reset or runningAtFullSpeed
$error_oids{$oid} = $jnxOperatingState{$value};
$state = 'WARNING' unless $state =~ /CRITICAL/;
} elsif ($value == 6) {
# down
$error_oids{$oid} = $jnxOperatingState{$value};
$state = 'CRITICAL'
}
}
#
# get all temperature values
#
if (!defined($response = $session->get_table($snmpJnxOperatingTemp))) {
$error_oids{$snmpJnxOperatingTemp} = $session->error;
}
while ( ($oid, $value) = each %$response ) {
if ($value < $temp_w) {
$state = 'OK' if $state =~ /UNKNOWN/;
$answer = "All environment variables normal." if $state =~ /UNKNOWN/;
} elsif ($value < $temp_c) {
$error_oids{$oid} = " $value ?C";
$state = 'WARNING' unless $state =~ /CRITICAL/;
} else {
$error_oids{$oid} = " $value ?C";
$state = 'CRITICAL'
}
}
#
# get all cpu values
#
if (!defined($response = $session->get_table($snmpJnxOperatingCPU))) {
$error_oids{$snmpJnxOperatingCPU} = $session->error;
}
while ( ($oid, $value) = each %$response ) {
if ($value < $cpu_w) {
$state = 'OK' if $state =~ /UNKNOWN/;
$answer = "All environment variables normal." if $state =~ /UNKNOWN/;
} elsif ($value < $cpu_c) {
$error_oids{$oid} = " $value%";
$state = 'WARNING' unless $state =~ /CRITICAL/;
} else {
$error_oids{$oid} = " $value%";
$state = 'CRITICAL'
}
}
## Here is the place for introducing artificial errors (for debugging).
unless ($state eq 'OK' or $state eq 'UNKNOWN') {
while ( ($oid, $value) = each %error_oids ) {
if ($oid =~ /$snmpJnxOperatingState\./) {
$value =~ s/\(\d\)//;
$oid =~ s/$snmpJnxOperatingState\.//;
if ($response = $session->get_request($snmpJnxOperatingDescr.".$oid")) {
$descr = $$response{$snmpJnxOperatingDescr.".$oid"};
} else {
$descr = "instance $oid";
}
push(@state_errors, "$descr is $value");
} elsif ($oid =~ /$snmpJnxOperatingTemp\./) {
$oid =~ s/$snmpJnxOperatingTemp\.//;
if ($response = $session->get_request($snmpJnxOperatingDescr.".$oid")) {
$descr = $$response{$snmpJnxOperatingDescr.".$oid"};
} else {
$descr = "instance $oid";
}
push(@temp_errors, " $descr : $value");
} elsif ($oid =~ /$snmpJnxOperatingCPU\./) {
$oid =~ s/$snmpJnxOperatingCPU\.//;
if ($response = $session->get_request($snmpJnxOperatingDescr.".$oid")) {
$descr = $$response{$snmpJnxOperatingDescr.".$oid"};
} else {
$descr = "instance $oid";
}
push(@cpu_errors, " $descr : $value");
}
}
my $state_errors_s = join ";", @state_errors if defined $state_errors[0];
my $temp_errors_s = join ";", @temp_errors if defined $temp_errors[0];
my $cpu_errors_s = join ";", @cpu_errors if defined $cpu_errors[0];
$answer = "Problems with:<BR>";
$answer .= "State: " . $state_errors_s . "<BR>" if defined $state_errors_s;
$answer .= "Temperature: " . $temp_errors_s . "<BR>" if defined $temp_errors_s;
$answer .= "CPU: " . $cpu_errors_s . "<BR>" if defined $cpu_errors_s;
$session->close;
}
print ("$answer\n");
exit $ERRORS{$state};
-------------- next part --------------
#!/usr/bin/perl -wT
#
# check_xinterface - nagios plugin
#
# largely based upon check_ifoperstatus.pl plugin by Christoph Kron
#
#
#
#
# Copyright (C) 2002 Guy Van Den Bergh
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
# Report bugs to: guy at belnet.be
#
# design of the plugin:
# get index for interface from -i option (format: <ifName>::<ifIndex>)
# check whether ifName matches ifIndex: if not: warning; exit
# check admin status: if down, then warning; exit
# check operational status: if down, then critical; exit
# check last change, if within 'tolerance' (-l or --last-change option),
# then warning
# get performance data: bits in/out, etc... (implementation to be scheduled later)
# performance data could be checked against older values (bw drops e.g.)
use strict;
use Net::SNMP;
use Getopt::Long;
&Getopt::Long::config('auto_abbrev');
my @cmdline = @ARGV;
my $status;
my $TIMEOUT = 15;
my %ERRORS = ('OK' , '0',
'WARNING', '1',
'CRITICAL', '2',
'UNKNOWN', '3');
my %ifOperStatus = ('1','up',
'2','down',
'3','testing',
'4','unknown',
'5','dormant',
'6','notPresent');
my $state = "UNKNOWN";
my $answer = "(No output. Bug?)";
my $ifName;
my $ifIndex;
my $ifDescr;
my $community = "public";
my $port = 161;
my @snmpoids;
my $snmpIfName;
my $snmpIfDescr;
my $snmpIfAlias;
my $snmpIfAdminStatus;
my $snmpIfOperStatus;
my $hostname;
my $session;
my $error;
my $response;
sub usage {
printf "\nMissing arguments!\n";
printf "\n";
printf "Perl eXtended Check Interface plugin for Nagios\n";
printf "checks status of specified interface\n";
printf "When the interface state changed within the last check interval, a WARNING is returned. \n\n";
printf "usage: \n";
printf "check_xinterface -i <ifIndex> -n <ifName> -c <READCOMMUNITY> -p <PORT> <HOSTNAME>\n";
printf "\nCopyright (C) 2002 Guy Van Den Bergh\n";
printf "check_xinterface comes with ABSOLUTELY NO WARRANTY\n";
printf "This programm is licensed under the terms of the ";
printf "GNU General Public License\n(check source code for details)\n";
printf "\n\n";
exit $ERRORS{"UNKNOWN"};
}
# Just in case of problems, let's not hang Nagios
$SIG{'ALRM'} = sub {
print ("ERROR: No snmp response from $hostname (alarm)\n");
exit $ERRORS{"UNKNOWN"};
};
alarm($TIMEOUT);
$status = GetOptions("index=s",\$ifIndex,
"name=s",\$ifName,
"community=s",\$community,
"port:i",\$port);
if ($status == 0)
{
&usage;
}
if (not defined $ifIndex) {
print ("ERROR: No snmp ifIndex supplied (@cmdline)\n");
exit $ERRORS{"UNKNOWN"};
}
if (not defined $ifName) {
print ("ERROR: No snmp ifName supplied (@cmdline)\n");
exit $ERRORS{"UNKNOWN"};
}
$hostname = shift || &usage;
($session, $error) = Net::SNMP->session(
-hostname => $hostname,
-community => $community,
-port => $port
);
if (!defined($session)) {
$state='UNKNOWN';
$answer=$error;
print ("$state: $answer");
exit $ERRORS{$state};
}
$snmpIfAdminStatus = '.1.3.6.1.2.1.2.2.1.7.' . $ifIndex;
$snmpIfOperStatus = '.1.3.6.1.2.1.2.2.1.8.' . $ifIndex;
$snmpIfName = '.1.3.6.1.2.1.31.1.1.1.1.' . $ifIndex;
$snmpIfDescr = '.1.3.6.1.2.1.2.2.1.2.' . $ifIndex;
$snmpIfAlias = '.1.3.6.1.2.1.31.1.1.1.18.' . $ifIndex;
push(@snmpoids,$snmpIfName);
push(@snmpoids,$snmpIfDescr);
push(@snmpoids,$snmpIfAdminStatus);
push(@snmpoids,$snmpIfOperStatus);
if (!defined($response = $session->get_request(@snmpoids))) {
$answer=$session->error;
$session->close;
$state = 'WARNING';
print ("$state: SNMP error: $answer\n");
exit $ERRORS{$state};
}
if ( not ($response->{$snmpIfName} eq $ifName) ) {
$state = 'UNKNOWN';
$answer = "Interface name ($ifName) doesn't match snmp value ($response->{$snmpIfName}) (index $ifIndex)";
} elsif ( not ($response->{$snmpIfAdminStatus} == 1) ) {
$state = 'WARNING';
$answer = "Interface $ifName (index $ifIndex) is administratively down.";
} elsif ( not ($response->{$snmpIfOperStatus} == 1) ) {
$state = 'CRITICAL';
$answer = "Interface $ifName (index $ifIndex) is down.";
} else {
$state = 'OK';
$answer = "Interface $ifName (index $ifIndex) is up.";
}
# Get ifAlias if available.
@snmpoids = ($snmpIfAlias);
$ifDescr = $response->{$snmpIfDescr} if defined $response->{$snmpIfDescr};
if (defined($response = $session->get_request(@snmpoids))
and defined $response->{$snmpIfAlias}
and length ($response->{$snmpIfAlias}) > 0) {
$answer .= "<BR>ifAlias: $response->{$snmpIfAlias}";
} elsif (defined $ifDescr
and length ($ifDescr) > 0) {
$answer .= "<BR>ifDescr: $ifDescr";
}
$session->close;
print ("$state: $answer\n");
exit $ERRORS{$state};
More information about the Devel
mailing list