Skip to content
Snippets Groups Projects
Commit b0c37319 authored by Hahn Axel (hahn)'s avatar Hahn Axel (hahn)
Browse files
parent 8ccb03c0
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/perl
#########################################################
# #
# #
# SNMP Printer Check Plugin for Icinga #
# Version 1.2.3 (October 14, 2020) #
# by Rob McLoughlin #
# E-mail: rmcloughlin@outlook.com #
# #
# #
# Based on: #
# check_snmp_printer (Perl) #
# Version 1.6 (September 08, 2014) #
# ( by Franky Van Liedekerke #
# E-mail: liedekef@telenet.be ) #
# #
# Which was further based on: #
# check_snmp_printer.sh #
# Version 1.5 (January 15, 2010) #
# ( by Jason Leonard #
# E-mail: jason_leonard@yahoo.com ) #
# #
# Version History #
# - Refer to CHANGELOG.md #
# #
# Like the original, this plugin is distributed #
# under the GNU GPL license. You may re-destribute only #
# according to the terms of the GNU GPL. #
# #
#########################################################
#########################################################
# #
# DEPENDS On #
# Net::SNMP perl module #
# Nagios plugins installed and located in lib64 #
# #
#########################################################
use strict;
use lib qw( /usr/lib/nagios/plugins /usr/lib64/nagios/plugins );
use utils qw( %ERRORS $TIMEOUT &print_revision &support &usage );
use Net::SNMP;
use Getopt::Long;
use Data::Dumper;
# globals
use vars qw(
$PROGNAME $VERSION %procs $snmp $errstr $oid
$opt_version $opt_help $opt_timeout $opt_retries $opt_host
$opt_community $opt_snmpver $opt_warning $opt_critical
$opt_messages $opt_model $opt_consum $opt_tray $opt_pagecount
$opt_metric $opt_nofeeder
);
my (@consumables,@status,@trays,@strays,@percentages,@mresults,@message,@measurables);
my ($state,$statuscode,$EXITSTRING);
my ($i,$tcount,$scount,$traynumber,$cnumber,$mnumber,$critcount,$warncount) = 0;
my %STATUS_CODE =
( 'UNKNOWN' => '3', 'OK' => '0', 'WARNING' => '1', 'CRITICAL' => '2' );
# config
$PROGNAME = $0;
$VERSION = '1.2.3';
# init options
$opt_version = undef;
$opt_help = undef;
$opt_timeout = $TIMEOUT;
$opt_retries = 3;
$opt_host = undef;
$opt_community = 'public';
$opt_snmpver = 1;
$opt_warning = 20; # warning percentage: if lower: warning
$opt_critical = 5; # critical percentage: if lower: critical
$opt_messages = undef;
$opt_model = undef;
$opt_consum = undef;
$opt_tray = undef;
$opt_pagecount = undef;
$opt_metric = undef;
# get options
Getopt::Long::Configure('bundling');
GetOptions(
'V|version' => \$opt_version,
'h|help' => \$opt_help,
't|timeout=i' => \$opt_timeout,
'r|retries=i' => \$opt_retries,
'H|host=s' => \$opt_host,
'C|community=s' => \$opt_community,
'v|snmpver=s' => \$opt_snmpver,
'w|warning=i' => \$opt_warning,
'c|critical=i' => \$opt_critical,
'messages' => \$opt_messages,
'model' => \$opt_model,
'consum' => \$opt_consum,
'trays' => \$opt_tray,
'pagecount' => \$opt_pagecount,
'nofeeder' => \$opt_nofeeder,
'metric' => \$opt_metric
) or do {
print_usage();
exit($ERRORS{'UNKNOWN'});
};
if($opt_version) {
print_version();
exit($ERRORS{'UNKNOWN'});
}
if($opt_help) {
print_help();
exit($ERRORS{'UNKNOWN'});
}
if(!$opt_host) {
print "Host option not given\n";
print_usage();
exit($ERRORS{'UNKNOWN'});
}
# only use one of messages|model|consum|tray|pagecount options
my $count=0;
($opt_messages) && ($count++);
($opt_model) && ($count++);
($opt_consum) && ($count++);
(defined($opt_tray)) && ($count++);
($opt_pagecount) && ($count++);
if ($count>1) {
print "Only use one of messages|model|consum|trays|pagecount options\n";
print_help();
exit($ERRORS{'UNKNOWN'});
}
if ($count<1) {
print "Only use one of messages|model|consum|trays|pagecount options\n";
print_help();
exit($ERRORS{'UNKNOWN'});
}
sub print_usage {
my $tab = ' ' x length($PROGNAME);
print <<EOB
Usage:
$PROGNAME -H host
$tab [-C snmp_community] [-v snmp_version] [-t timeout]
$PROGNAME --version
$PROGNAME --help
EOB
}
sub print_version {
print_revision($PROGNAME, $VERSION);
}
sub print_help {
print_version();
print <<EOB;
Check a printer through SNMP.
EOB
print_usage();
print <<EOB;
Required Arguments:
-H, --host=HOST
The name or address of the host running SNMP.
--messages
Print the messages of the printer
--model
Prints the model of the printer
--pagecount
Prints the number of pages printed
--trays
Checks trays for paper status.
--consum
Checks consumables for status.
Optional Arguments:
-C, --community=STRING
The community string of the SNMP agent. Default: public
-v, --snmpver=STRING
The version of snmp to use. 1 and 2 are supported. Default: 1
-w, --warning=INTEGER
The warning limit level to alert on. 0 to disable tray alerting.
-c, --critical=INTEGER
The critical limit level to alert on. 0 to disable tray alerting.
-t, --timeout=INTEGER
Number of seconds to wait for a response.
-r, --retries=INTEGER
Number of retries to try before timing out. Default: 3
--metric
Converts output to metric. Default: imperial
--nofeeder
Disables checking of the manual feeder tray
EOB
}
sub check_model {
my ($pcheck) = @_;
my ($oid,$result);
my $MODEL="Uknown model";
my $SERIAL="";
if ($pcheck == 1 || $pcheck == 2) {
$oid=".1.3.6.1.2.1.25.3.2.1.3.1";
$result=$snmp->get_request(-varbindlist => [$oid]);
($result) && ($MODEL=$result->{$oid});
if ($pcheck == 2) { return lc $MODEL; }
}
if ($pcheck == 1) {
$oid=".1.3.6.1.2.1.43.5.1.1.17.1";
$result=$snmp->get_request(-varbindlist => [$oid]);
($result) && ($SERIAL=$result->{$oid});
$SERIAL =~ s/\"//g;
print "$MODEL, Serial # $SERIAL\n";
}
}
sub check_messages {
my ($mcheck) = @_;
my ($oid,$result,$model);
my $MESSAGES="";
$model = check_model(2);
if ($model =~ m/hp/) {
$oid=".1.3.6.1.4.1.11.2.3.9.1.1.3";
} else {
$oid=".1.3.6.1.2.1.43.16";
}
$result = $snmp->get_entries(-columns => [$oid]);
foreach my $key (keys(%$result)) {
$result->{$key} =~ s/\"//g;
$result->{$key} =~ s/\n/\!/g;
$MESSAGES .= $result->{$key}."\n";
}
chomp $MESSAGES;
if ($MESSAGES eq "") {
$MESSAGES= "(Can't determine messages)";
}
if ($mcheck == 2) { return $MESSAGES; }
my @messages = split('\n',$MESSAGES);
foreach my $message (@messages) {
$message = lc $message;
if ($message =~ m/toner low|wenig toner|cartridge low|niedrig|attention/) {
$state = "WARNING";
}
elsif ($message =~ m/replace toner|toner ersetzen|error|paper is out/) {
$state = "CRITICAL";
} else { $state = "OK"; }
push @{ $status[$mnumber] }, $state;
$mnumber++;
}
print "$MESSAGES\n";
}
sub check_page_count {
my ($oid,$result,$model,$t_oid,$c_oid,$m_oid,
$m_a3_oid,$m_a4_oid,$c_a3_oid,$c_a4_oid,
$m_a3,$m_a4,$c_a3,$c_a4,$MonoPagecount,$ColorPagecount,$TotalPagecount);
my (%ttmpprs,%ctmpprs,%mtmpprs) = ();
$model = check_model(2);
if ($model =~ m/hp/) {
$c_oid='.1.3.6.1.4.1.11.2.3.9.4.2.1.4.1.2.7.0';
$m_oid='.1.3.6.1.4.1.11.2.3.9.4.2.1.4.1.2.6.0';
}
if ($model =~ m/canon/) {
$t_oid='.1.3.6.1.4.1.1602.1.11.1.3.1.4.101';
$c_oid='.1.3.6.1.4.1.1602.1.11.1.3.1.4.105';
$m_oid='.1.3.6.1.4.1.1602.1.11.1.3.1.4.108';
$m_a3_oid='.1.3.6.1.4.1.1602.1.11.1.3.1.4.112';
$m_a4_oid='.1.3.6.1.4.1.1602.1.11.1.3.1.4.113';
$c_a3_oid='.1.3.6.1.4.1.1602.1.11.1.3.1.4.222';
$c_a4_oid='.1.3.6.1.4.1.1602.1.11.1.3.1.4.223';
}
if ($model =~ m/xerox/) {
$c_oid='.1.3.6.1.4.1.253.8.53.13.2.1.6.1.20.33';
$m_oid='.1.3.6.1.4.1.253.8.53.13.2.1.6.1.20.34';
}
if ($model =~ m/lexmark/) {
$c_oid='.1.3.6.1.4.1.641.6.4.2.2.1.7.1.1';
$m_oid='.1.3.6.1.4.1.641.6.4.2.2.1.6.1.1';
}
if ($model =~ m/ricoh/) {
$c_oid='.1.3.6.1.4.1.367.3.2.1.2.19.5.1.9.21';
$m_oid='.1.3.6.1.4.1.367.3.2.1.2.19.5.1.9.22';
}
if ($model =~ m/kyocera|ecosys|taskalfa|4200dn/) {
$t_oid='.1.3.6.1.4.1.1347.42.2.1.1.1.6.1';
$c_oid='.1.3.6.1.4.1.1347.42.2.1.1.1.8.1';
$m_oid='.1.3.6.1.4.1.1347.42.2.1.1.1.7.1';
}
$oid=".1.3.6.1.2.1.43.10.2.1.4.1.1";
if (defined($snmp->get_request(-varbindlist => [$m_a3_oid]))) { $m_a3 = $snmp->get_request(-varbindlist => [$m_a3_oid]) }
if (defined($snmp->get_request(-varbindlist => [$m_a4_oid]))) { $m_a4 = $snmp->get_request(-varbindlist => [$m_a4_oid]) }
if (defined($snmp->get_request(-varbindlist => [$c_a3_oid]))) { $c_a3 = $snmp->get_request(-varbindlist => [$c_a3_oid]) }
if (defined($snmp->get_request(-varbindlist => [$c_a4_oid]))) { $c_a4 = $snmp->get_request(-varbindlist => [$c_a4_oid]) }
if (($m_a3 || $m_a4) > 0) {
$MonoPagecount = $m_a3 + $m_a4;
} elsif ($model =~ m/kyocera|ecosys|taskalfa|4200dn/) {
my $tresult = $snmp->get_entries(-columns => [$t_oid]);
my $cresult = $snmp->get_entries(-columns => [$c_oid]);
my $mresult = $snmp->get_entries(-columns => [$m_oid]);
foreach my $tkey (keys(%$tresult)) {
my($tindex) = ($tkey =~ /($t_oid\.\d+)/);
$tresult->{$tkey} =~ s/[^\w\s]//g;
$ttmpprs{$tindex}{t_count} = $tresult->{$tkey};
}
foreach my $tkey (keys(%ttmpprs)) {
my $t_count=$ttmpprs{$tkey}{t_count};
$TotalPagecount = $TotalPagecount+$t_count;
}
foreach my $ckey (keys(%$cresult)) {
my($cindex) = ($ckey =~ /($c_oid\.\d+)/);
$cresult->{$ckey} =~ s/[^\w\s]//g;
$ctmpprs{$cindex}{c_count} = $cresult->{$ckey};
}
foreach my $ckey (keys(%ctmpprs)) {
my $c_count=$ctmpprs{$ckey}{c_count};
$ColorPagecount = $ColorPagecount+$c_count;
}
foreach my $mkey (keys(%$mresult)) {
my($mindex) = ($mkey =~ /($m_oid\.\d+)/);
$mresult->{$mkey} =~ s/[^\w\s]//g;
$mtmpprs{$mindex}{m_count} = $mresult->{$mkey};
}
foreach my $mkey (keys(%mtmpprs)) {
my $m_count=$mtmpprs{$mkey}{m_count};
$MonoPagecount = $MonoPagecount+$m_count;
}
} else {
$result=$snmp->get_request(-varbindlist => [$m_oid]);
if((not defined($result)) || ($result->{$m_oid} eq 'noSuchInstance')) {
$result=$snmp->get_request(-varbindlist => [$t_oid]);
if((not defined($result)) || ($result->{$m_oid} eq 'noSuchInstance')) {
$result=$snmp->get_request(-varbindlist => [$oid]);
if ($snmp->error() =~ m/genError/) {
$result = retry_snmp($oid,undef,undef,undef,undef,undef,undef,undef);
}
if(not defined($result)) {
print "CRITICAL - snmp error: " . $snmp->error() . "\n";
exit($ERRORS{'CRITICAL'});
} else { $TotalPagecount=$result->{$oid}; }
} else { $TotalPagecount=$result->{$t_oid}; }
} else { $MonoPagecount=$result->{$m_oid}; }
}
if (($c_a3 || $c_a4) > 0) {
$ColorPagecount = $c_a3 + $c_a4;
} else {
$result=$snmp->get_request(-varbindlist => [$c_oid]);
if(not defined($result)) {
} else { $ColorPagecount=$result->{$c_oid}; }
}
if (($TotalPagecount) or (($model =~ m/kyocera|ecosys|taskalfa|4200dn/))) {
$EXITSTRING = "Pagecount is $TotalPagecount";
if ($model =~ m/kyocera|ecosys|taskalfa|4200dn/) {
$EXITSTRING.= " Total, $MonoPagecount Black-and-White";
}
} else { $EXITSTRING = "Pagecount is $MonoPagecount Black-and-White"; }
if ($ColorPagecount > 0) {
$EXITSTRING.= ", $ColorPagecount Color";
}
$EXITSTRING.= "\n";
if (($TotalPagecount) or ($model =~ m/kyocera|ecosys|taskalfa|4200dn/)) {
$EXITSTRING.= "|Total=$TotalPagecount;;;;";
if ($model =~ m/kyocera|ecosys|taskalfa|4200dn/) {
$EXITSTRING.= " Black-and-White=$MonoPagecount;;;;";
}
} else { $EXITSTRING.= "|Black-and-White=$MonoPagecount;;;;"; }
if ($ColorPagecount > 0) {
$EXITSTRING.= " Color=$ColorPagecount;;;;";
}
}
sub get_consumables {
my ($result,$Table,$Names,$CurCap,$MaxCap) = @_;
my %tmpprs = ();
my ($consumable, $curcap_pct);
my ($puncher, $found) = 0;
foreach my $key (keys(%$result)) {
my($base, $index) = ($key =~ /($Table\.\d+\.\d+)\.(\d+)/);
if($base eq $Names ) {
$result->{$key} =~ s/[^\w\s]//g;
$tmpprs{$index}{name} = $result->{$key};
}
if($base eq $CurCap) { $tmpprs{$index}{curcap} = $result->{$key}; }
if($base eq $MaxCap) { $tmpprs{$index}{maxcap} = $result->{$key}; }
}
foreach my $key (keys(%tmpprs)) {
my $name=$tmpprs{$key}{name};
if ($name =~ m/Imaging Unit|Imaging Kit/) { $consumable = $name; }
else { ($consumable = $name) =~ s/(\w+).*/$1/; }
if ($consumable eq "Canon") {
my @split = split(' ',$consumable = $name);
foreach my $cconsumable (@split) {
if ($cconsumable =~ m/Black|Yellow|Magenta|Cyan/) { $consumable = $cconsumable; }
else { next; }
}
}
if ($consumable eq "Image") {
my @split = split(' ',$consumable = $name);
foreach my $iconsumable (@split) {
if ($iconsumable =~ m/Transfer|Fuser/) { $consumable = $iconsumable. " Kit"; }
else { next; }
}
}
if (check_model(2) =~ m/generic 30c-9/) {
my @split = split(' ',$consumable = $name);
foreach my $gconsumable (@split) {
if ($gconsumable =~ m/Toner/) {
($consumable) = $name =~ /\((.*)\)/;
} elsif ($gconsumable =~ m/Image|Fusing/) {
$consumable = $name;
} else {
next;
}
}
}
if (check_model(2) =~ m/ricoh/) {
my @split = split(' ',$consumable = $name);
foreach my $rconsumable (@split) {
if ($rconsumable =~ m/Toner/) {
($consumable) = $name =~ /(?<=Toner )(\w+)/;
} else {
next;
}
}
}
my $curcap=$tmpprs{$key}{curcap};
my $maxcap=$tmpprs{$key}{maxcap};
if ($name =~ m/Drum|Resttoner|Waste Toner|Belt|Developer/) {
next;
}
if ($consumable =~ m/Imaging Unit/) { }
elsif ($consumable =~ m/Black|Yellow|Magenta|Cyan/) { $consumable = $consumable." Toner"; }
elsif ($consumable =~ m/Schwarz|Gelb/) { $consumable = $consumable." Toner"; } # German
# Kyocera reports toner as model number so we need to convert that to something human readable
if ($consumable =~ m/TK/) {
if ($consumable =~ /CS$|C$/) { $consumable = "Cyan Toner"; }
elsif ($consumable =~ /MS$|M$/) { $consumable = "Magenta Toner"; }
elsif ($consumable =~ /YS$|Y$/) { $consumable = "Yellow Toner"; }
elsif ($consumable =~ /KS$|K$/) { $consumable = "Black Toner"; }
else { $consumable = "Black Toner"; }
}
if ($consumable eq 'Magneta') { $consumable = "Magenta Toner"; } # New HP OID has a typo
if ($consumable eq 'Clean') { $consumable = $consumable." Rollers"; }
if ($consumable eq 'Document') { $consumable = $consumable." Feeder Kit"; }
if ($consumable eq 'Maintenance') { $consumable = $consumable." Kit"; }
if ($consumable eq 'Transfer') { $consumable = $consumable." Unit"; }
if ($consumable eq 'Stapler') { }
if ($consumable eq 'Staples') { }
if ($consumable eq 'Saddle') { $consumable = $consumable." Staples"; }
if ($consumable eq 'Puncher') { $puncher = 1; $consumable = $consumable. " Waste"; }
push (@consumables, $consumable);
$found=1;
if ($puncher == 1) {
if ($curcap > 99) {
$state = "CRITICAL";
} elsif ($curcap >= 96) {
$state = "WARNING";
} else {
$state = "OK";
}
push (@measurables, '1');
push (@percentages, $curcap);
} else {
if ($maxcap>0 && $curcap>0) {
$curcap_pct=sprintf("%.2f",$curcap*100/$maxcap);
if ($curcap_pct<=$opt_critical) {
# critical messages come first
$state = "CRITICAL";
} elsif ($curcap_pct<=$opt_warning) {
$state = "WARNING";
} else {
$state = "OK";
}
push (@measurables, '1');
push (@percentages, $curcap_pct);
} elsif ($maxcap == 100 && $curcap == 0) {
$state = "CRITICAL";
push (@measurables, '1');
push (@percentages, 0);
} else {
if (check_model(2) =~ m/brother/) {
my ($bresult,$bstatus,$boid);
if ($consumable =~ m/Black|Schwarz/) {
$boid = ".1.3.6.1.4.1.2435.2.3.9.1.1.2.10.1";
}
if ($consumable =~ m/Cyan/) {
$boid = ".1.3.6.1.4.1.2435.2.3.9.1.1.2.10.2";
}
if ($consumable =~ m/Magenta/) {
$boid = ".1.3.6.1.4.1.2435.2.3.9.1.1.2.10.3";
}
if ($consumable =~ m/Yellow|Gelb/) {
$boid = ".1.3.6.1.4.1.2435.2.3.9.1.1.2.10.4";
}
if (defined($snmp->get_request(-varbindlist => [$boid]))) {
$bstatus = $bresult->{$oid};
if ($bstatus == 0) { $state = "OK"; push (@measurables, 'b0'); $curcap = 100; }
if ($bstatus == 1) { $state = "WARNING"; push (@measurables, 'b1'); $curcap = 10; }
if ($bstatus == 2) { $state = "CRITICAL"; push (@measurables, 'b2'); $curcap = 0; }
if ($bstatus == 3) { $state = "CRITICAL"; push (@measurables, 'b3'); $curcap = 0; }
} else { ($state,$curcap) = nonmeasurable($curcap,$maxcap,$name); }
} else {
$state = nonmeasurable($curcap,$maxcap,$name);
}
push (@percentages, $curcap);
}
}
$puncher = 0;
push @{ $status[$cnumber] }, $state;
$cnumber++;
}
}
sub nonmeasurable {
my ($curcap,$maxcap,$name) = @_;
# Our object is not measurable - it's either FULL or EMPTY (such as a punch dust box)
# Let's report on it's status using appropriate terminology
if (check_model(2) =~ m/brother/) {
if ($curcap == -3) { $state = "OK"; push (@measurables, 'b0'); }
else {
my $smessage = check_messages(2);
my @messages = split('\n',$smessage);
foreach my $message (@messages) {
$message = lc $message;
if ($message =~ m/toner low|wenig toner/) {
$state = "WARNING";
push (@measurables, 'b1');
$curcap = 10;
}
elsif ($message =~ m/replace toner|toner ersetzen/) {
$state = "CRITICAL";
push (@measurables, 'b3');
$curcap = 0;
}
}
}
push (@measurables, '1');
return $state, $curcap;
} elsif ($curcap==-3) {
if ($maxcap>0) { $state = "WARNING"; push (@measurables, 'lt'); }
else { $state = "OK"; (@measurables, 'gt'); }
} elsif ($curcap==-2) {
# The value (-2) means unknown
if ($name =~ m/W2020A|W2021A|W2022A|W2023A/) { # HP Color LaserJet Pro M454dw Toner
$state = "CRITICAL";
push (@measurables, '1');
} else { $state = "WARNING"; push (@measurables, '0'); }
} elsif ($curcap==0) {
# Something is empty!
$state = "CRITICAL";
}
return $state;
}
sub prioritize_results {
my ($metric) = @_;
my ($mcount,$scode);
if ((scalar @consumables) > 0) { $mcount = (scalar @consumables); }
if ((scalar @strays) > 0) { $mcount = (scalar @strays); }
$i = 0;
while ($mcount > 0) {
if ($status[$i][0] eq 'CRITICAL') { $scode = 1; }
if ($status[$i][0] eq 'WARNING') { $scode = 2; }
if ($status[$i][0] eq 'OK') { $scode = 3; }
if ($metric eq "consumables") {
push @{ $mresults[$i] }, $scode, $status[$i][0], $consumables[$i], $message[$i];
}
if ($metric eq "trays") {
push @{ $mresults[$i] }, $scode, $status[$i][0], $strays[$i][0], $message[$i];
}
$mcount--;
$i++;
}
@mresults = sort { $a->[0] cmp $b->[0] } @mresults;
$i = 0;
$mcount = (scalar @mresults);
while ($mcount > 0) {
print "$mresults[$i][1]: $mresults[$i][2]$mresults[$i][3]\n";
$mcount--;
$i++;
}
}
sub check_consumables {
my %pr_oids = (
'Table' => '.1.3.6.1.2.1.43.11.1.1',
'Names' => '.1.3.6.1.2.1.43.11.1.1.6.1',
'CurCap' => '.1.3.6.1.2.1.43.11.1.1.9.1',
'MaxCap' => '.1.3.6.1.2.1.43.11.1.1.8.1',
'CTable' => '.1.3.6.1.2.1.43.31.1.1',
'CNames' => '.1.3.6.1.2.1.43.31.1.1.5.1',
'CCurCap' => '.1.3.6.1.2.1.43.31.1.1.8.1',
'CMaxCap' => '.1.3.6.1.2.1.43.31.1.1.7.1'
);
my ($consumable,$measurable,$perfcount);
my $pct_remaining = "";
my $result = $snmp->get_entries(-columns => [$pr_oids{Names}, $pr_oids{CurCap}, $pr_oids{MaxCap}]);
if ($snmp->error() =~ m/genError/) {
$result = retry_snmp($pr_oids{Names}, $pr_oids{CurCap}, $pr_oids{MaxCap},undef,undef,undef,undef,undef);
}
if(not defined($result)) {
print "CRITICAL - snmp error: " . $snmp->error() . "\n";
exit($ERRORS{'CRITICAL'});
}
my $cresult = $snmp->get_entries(-columns => [$pr_oids{CNames}, $pr_oids{CCurCap}, $pr_oids{CMaxCap}]);
get_consumables($result, $pr_oids{Table}, $pr_oids{Names}, $pr_oids{CurCap}, $pr_oids{MaxCap});
get_consumables($cresult, $pr_oids{CTable}, $pr_oids{CNames}, $pr_oids{CCurCap}, $pr_oids{CMaxCap});
$tcount = (scalar @consumables);
if (@percentages != 0 ) { $measurable = 1; }
if ($measurable) {
if ($consumables[0] eq "Puncher Waste") {
$pct_remaining = " is ".$percentages[0]. "% full.";
} elsif ($consumables[0] eq "Stapler") {
$pct_remaining = "";
} elsif (check_model(2) =~ m/brother/) {
if ($measurables[$i] eq "b0") {
$pct_remaining = " levels are OK.";
}
if ($measurables[$i] eq "b1") {
$pct_remaining = " levels are LOW.";
}
if ($measurables[$i] eq "b2") {
$pct_remaining = " has no toner installed.";
}
if ($measurables[$i] eq "b3") {
$pct_remaining = " levels are EMPTY.";
}
} elsif ($percentages[$i] eq "-2") {
if ($measurables[$i] eq "0") {
$pct_remaining = " levels cannot be measured.";
} else { $pct_remaining = " is at 0% remaining."; }
} else {
$pct_remaining = " is at ".$percentages[0]. "% remaining.";
}
push (@message, $pct_remaining);
}
my $perfcount = $tcount;
if ($tcount > 1) {
$tcount--;
while ($tcount > 0) {
$i++;
if ($consumables[$i] eq "Waste") {
$tcount--;
next;
}
if ($measurable) {
if ($consumables[$i] eq "Puncher Waste") {
$pct_remaining = " is ".$percentages[$i]. "% full.";
} elsif ($consumables[$i] eq "Stapler") {
$pct_remaining = "";
} elsif (check_model(2) =~ m/brother/) {
if ($measurables[$i] eq "b0") {
$pct_remaining = " levels are OK.";
}
if ($measurables[$i] eq "b1") {
$pct_remaining = " levels are LOW.";
}
if ($measurables[$i] eq "b2") {
$pct_remaining = " has no toner installed.";
}
if ($measurables[$i] eq "b3") {
$pct_remaining = " levels are EMPTY.";
}
} elsif ($percentages[$i] eq "-2") {
if ($measurables[$i] eq "0") {
$pct_remaining = " levels cannot be measured.";
} else { $pct_remaining = " is at 0% remaining."; }
} elsif ($percentages[$i] eq "-3") {
if ($measurables[$i] eq "lt") {
$pct_remaining = " levels are LOW.";
}
if ($measurables[$i] eq "gt") {
$pct_remaining = " levels are OK.";
}
} else {
$pct_remaining = " is at ".$percentages[$i]. "% remaining.";
}
}
push (@message, $pct_remaining);
$tcount--;
}
}
prioritize_results('consumables');
$i = 0;
$EXITSTRING.= "|";
while ($perfcount > 0) {
if ($consumables[$i] eq "Waste") {
$i++;
$perfcount--;
next;
}
($consumable = $consumables[$i]) =~ s/ /_/g;
if ($measurable) {
if ($consumable eq "Stapler") {
if ($status[$i] eq 'CRITICAL') { $EXITSTRING.= $consumable."=0"; }
elsif ($status[$i] eq 'OK') { $EXITSTRING.= $consumable."=100"; }
} elsif ($percentages[$i] eq "-2") {
if ($measurables[$i] eq "0") { }
else { $EXITSTRING.= "$consumable=0"; }
} else {
$EXITSTRING.= $consumable."=".$percentages[$i];
}
} else {
if ($status[$i] == "CRITICAL") {
$EXITSTRING.= $consumable."=0";
} else {
$EXITSTRING.= $consumable."=1";
}
}
$i++;
$perfcount--;
if ($perfcount == 0) { $EXITSTRING.= ";;;;"; } else { $EXITSTRING.=";;;; "; }
}
}
sub check_paper_trays {
my $found=0;
my %tmpprs = ();
my ($name,$lcname,$feeder,$cap,$tstatus,$traymessage,$maxcap,$feeddim,$xfeeddim,$cap_pct);
my %tray_oids = (
'Table' => '.1.3.6.1.2.1.43.8.2.1',
'Cap' => '.1.3.6.1.2.1.43.8.2.1.10.1',
'Status' => '.1.3.6.1.2.1.43.8.2.1.11.1',
'MaxCap' => '.1.3.6.1.2.1.43.8.2.1.9.1',
'Name' => '.1.3.6.1.2.1.43.8.2.1.13.1',
'FeedDim' => '.1.3.6.1.2.1.43.8.2.1.4.1',
'FeedDimUnits' => '.1.3.6.1.2.1.43.8.2.1.2.1',
'XFeedDim' => '.1.3.6.1.2.1.43.8.2.1.5.1',
'XFeedDimUnits' => '.1.3.6.1.2.1.43.8.2.1.3.1'
);
my $result = $snmp->get_entries(-columns => [$tray_oids{Name},$tray_oids{Cap},$tray_oids{MaxCap},$tray_oids{FeedDim},$tray_oids{FeedDimUnits},$tray_oids{XFeedDim},$tray_oids{XFeedDimUnits},$tray_oids{Status}]);
my $model = "Unknown Model";
my $mresult = $snmp->get_request(-varbindlist => [".1.3.6.1.2.1.25.3.2.1.3.1"]);
($mresult) && ($model=$mresult->{".1.3.6.1.2.1.25.3.2.1.3.1"});
if ($snmp->error() =~ m/genError/) {
$result = retry_snmp($tray_oids{Name},$tray_oids{Cap},$tray_oids{MaxCap},$tray_oids{FeedDim},$tray_oids{FeedDimUnits},$tray_oids{XFeedDim},$tray_oids{XFeedDimUnits},$tray_oids{Status});
}
if(not defined($result)) {
print "CRITICAL - snmp error: " . $snmp->error() . "\n";
exit($ERRORS{'CRITICAL'});
}
foreach my $key (keys(%$result)) {
my($base, $index) = ($key =~ /($tray_oids{Table}\.\d+\.\d+)\.(\d+)/);
$result->{$key} =~ s/\"//g;
if($base eq $tray_oids{Cap}) { $tmpprs{$index}{cap} = $result->{$key}; }
if($base eq $tray_oids{Status}) { $tmpprs{$index}{tstatus} = $result->{$key}; }
if($base eq $tray_oids{MaxCap}) { $tmpprs{$index}{maxcap} = $result->{$key}; }
if($base eq $tray_oids{Name}) { $tmpprs{$index}{name} = $result->{$key}; }
if($base eq $tray_oids{FeedDim}) { $tmpprs{$index}{feeddim} = $result->{$key}; }
if($base eq $tray_oids{XFeedDim}) { $tmpprs{$index}{xfeeddim} = $result->{$key}; }
}
foreach my $key (keys(%tmpprs)) {
$name=$tmpprs{$key}{name};
$cap=$tmpprs{$key}{cap};
$tstatus=$tmpprs{$key}{tstatus};
$maxcap=$tmpprs{$key}{maxcap};
$feeddim=$tmpprs{$key}{feeddim};
$xfeeddim=$tmpprs{$key}{xfeeddim};
# if name is empty, make one with the number
if ($name eq "") {
$name="Tray $key";
}
if ($name =~ m/(MPT)/) {
$name =~ s/ \(MPT\)//g;
}
if ($name =~ m/Paper Tray/) {
($name) = $name =~ /[^ ]* (.*)/;
}
$name =~ s/\n/\!/g;
if ($name =~ m/TRAY/) {
if ($name =~ /(?<=TRAY)[0-9]/) {
my @split = split(/(?<=\d)(?=\D)|(?<=\D)(?=\d)/, $name);
$name = @split[0]." ".@split[1];
}
$name = (ucfirst(lc($name)));
}
$lcname = lc($name);
if (($lcname =~ m/stack bypass|mp tray|manual paper|manual envelope|multi-purpose_tray/) and ($opt_nofeeder)) { $feeder=1; next; }
if (($lcname =~ m/tray 1/) and ($opt_nofeeder) and (scalar(keys(%tmpprs) > 1)) and $feeder != 1) { next; }
$found=1;
push @{ $trays[$traynumber] }, $name, $cap, $maxcap, $feeddim, $xfeeddim, $tstatus;
$traynumber++;
}
$traynumber = 0;
@strays = sort { $a->[0] cmp $b->[0] } @trays;
$tcount = scalar(@strays);
my $perfcount = $tcount;
while ($tcount > 0) {
$name = $strays[$i][0];
$cap = $strays[$i][1];
$maxcap = $strays[$i][2];
$feeddim = $strays[$i][3];
$xfeeddim = $strays[$i][4];
$tstatus = $strays[$i][5];
$lcname = lc($name);
if ($feeddim eq '-2') { $feeddim = "Any"; }
if ($xfeeddim eq '-2') { $xfeeddim = "Any"; }
$model = check_model(2);
if (($feeddim || $xfeeddim) ne 'Any') {
if ($model =~ m/canon|xerox|ricoh|brother/) {
if ($opt_metric) {
$feeddim = sprintf("%.0f", $feeddim * .001)."mm";
$xfeeddim = sprintf("%.0f", $xfeeddim * .001)."mm";
} else {
$feeddim = sprintf("%.2f", (($feeddim / 2.54) * .0001))."in";
$xfeeddim = sprintf("%.2f", (($xfeeddim / 2.54) * .0001))."in";
}
} else {
if ($opt_metric) {
$feeddim = sprintf("%.0f", (($feeddim * 2.54) * .001))."mm";
$xfeeddim = sprintf("%.0f", (($xfeeddim * 2.54) * .001))."mm";
} else {
$feeddim = sprintf("%.2f", $feeddim * .0001)."in";
$xfeeddim = sprintf("%.2f", $xfeeddim * .0001)."in";
}
}
}
if ($cap == -3) {
# The value (-3) means that the printer knows that at least one unit remains.
if ($model =~ m/lexmark/) { # When -3, Lexmark is really low status.
if (($opt_critical == 0) or ($opt_warning == 0 )) {
$state = "OK";
} else {
$state = "WARNING";
}
$traymessage = " is LOW. ($xfeeddim x $feeddim)";
} else {
$state = "OK";
$traymessage = " ($xfeeddim x $feeddim)";
}
} elsif ($cap == -2) {
# The value (-2) means unknown
# so lets check the tray status instead
if ($tstatus eq '0') {
if ($model =~ m/canon|hp|ricoh/) {
$state = "OK";
$traymessage = " ($xfeeddim x $feeddim)";
} else {
$state = "WARNING";
$traymessage = " is in an UNKNOWN state.";
}
if (($lcname =~ m/tray 1|stack bypass|mp tray|manual paper|manual envelope|multi-purpose_tray/) and ($state ne 'WARNING')) {
$traymessage = "";
}
} elsif ($tstatus eq '4') {
if ($model =~ m/lexmark/) {
$state = "OK";
$traymessage = " ($xfeeddim x $feeddim)";
}
} elsif ($tstatus eq '9') {
if ($model =~ m/hp/) {
$state = "OK";
$traymessage = " ($xfeeddim x $feeddim)";
}
} else {
# still unknown so we'll mark it warning because we just don't know
$state = "WARNING";
$traymessage = " is in UNKNOWN status.";
}
} elsif ($cap == 0) {
# 0 means there is no paper left! This is our only critical value.
# first lets check to see if it's a bypass tray, we'll always assume Tray 1 is such.
if ($lcname =~ m/tray 1|stack bypass|mp tray|manual paper|manual envelope|multi-purpose_tray/) {
$state = "CRITICAL";
if (($xfeeddim || $feeddim) ne 'Any') {
$traymessage = " ($xfeeddim x $feeddim)";
} else { $traymessage = " is empty."; }
} else {
if ($opt_critical > 0) {
$state = "CRITICAL";
} else {
$state = "OK";
}
$traymessage = " ($xfeeddim x $feeddim) is at 0% paper remaining.";
}
$cap_pct=sprintf("%.2f",$cap*100/$maxcap);
} else {
($maxcap==0) && ($maxcap=1);
$cap_pct=sprintf("%.2f",$cap*100/$maxcap);
if (($cap_pct <= $opt_warning) and ($opt_warning > 0 )) {
$state = "WARNING";
} else {
$state = "OK";
}
$traymessage = " ($xfeeddim x $feeddim) is at $cap_pct% paper remaining.";
}
push @{ $status[$traynumber] }, $state, $cap_pct;
push (@message, $traymessage);
$traynumber++;
$tcount--;
$i++;
}
prioritize_results('trays');
$i = 0;
$EXITSTRING.= "|";
while ($perfcount > 0) {
(my $tray = $strays[$i][0]) =~ s/ /_/g;
if ($status[$i][0] eq 'CRITICAL') {
if ($status[$i][1] != "") {
$EXITSTRING.= $tray."=$status[$i][1]";
} else { $EXITSTRING.= $tray."=0"; }
}
if ($status[$i][0] eq 'WARNING') {
if ($status[$i][1] != "") {
$EXITSTRING.= $tray."=$status[$i][1]";
} else { $EXITSTRING.= $tray."=10"; }
}
if ($status[$i][0] eq 'OK') {
if ($status[$i][1] != "") {
$EXITSTRING.= $tray."=$status[$i][1]";
} else { $EXITSTRING.= $tray."=100"; }
}
$i++;
$perfcount--;
if ($perfcount == 0) { $EXITSTRING.= ";;;;"; } else { $EXITSTRING.=";;;; "; }
}
}
sub retry_snmp {
my ($sr1,$sr2,$sr3,$sr4,$sr5,$sr6,$sr7,$sr8) = @_;
if ($sr8) {
return $snmp->get_entries(-columns => [$sr1,$sr2,$sr3,$sr4,$sr5,$sr6,$sr7,$sr8]);
} elsif ($sr2) {
return $snmp->get_entries(-columns => [$sr1,$sr2,$sr3]);
} else {
return $snmp->get_request(-varbindlist => [$sr1]);
}
}
# set alarm in case we hang
$SIG{ALRM} = sub {
print "CRITICAL - Timeout after $opt_timeout seconds\n";
exit($ERRORS{'CRITICAL'});
};
alarm($opt_timeout*$opt_retries);
# connect to the snmp server
($snmp, $errstr) = Net::SNMP->session(
-hostname => $opt_host,
-version => $opt_snmpver,
-community => $opt_community,
-timeout => $opt_timeout,
-retries => $opt_retries,
);
if (!$snmp) {
print "Could not create SNMP session: $errstr\n";
exit($ERRORS{'UNKNOWN'});
}
if ($opt_messages) {check_messages();}
if ($opt_model) {check_model(1); exit($ERRORS{'OK'});}
if ($opt_pagecount) {check_page_count();}
if ($opt_consum) {check_consumables();}
if (defined($opt_tray)) {check_paper_trays($opt_tray);}
$i = 0;
$scount = (scalar @status);
while ($scount > 0) {
if ($status[$i][0] eq "CRITICAL") { $critcount++; }
if (($status[$i][0] eq "WARNING") && ($state ne "CRITICAL")) { $warncount++; }
$scount--;
$i++;
}
if ($critcount > 0) { $state = "CRITICAL"; }
elsif ($warncount > 0) { $state = "WARNING"; }
else { $state = "OK"; }
stop($EXITSTRING, $state);
sub stop {
my $result = shift;
my $exit_code = shift;
print $result . "\n";
exit ( $STATUS_CODE{$exit_code} );
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment