📜 ⬆️ ⬇️

Nagios - monitor vmware, CMC-TC, Synology, UPS, printers and quite a bit of Cisco

The first part was here: Nagios - a monitoring system and some homemade plugins . As promised, part two is more interesting.

Here I will explain how and what can be monitored in nagios in vmware, CMC-TC, Synology, UPS (APC and Chloride), printers and monitoring of interfaces in Cisco by name and why it is needed.

Nagios and VMWARE


We have vmware clusters from vSphere 5.1, licensed, with technical support. Although vmware technical support is separate and not for the night. By snmp there you can monitor the standard branch HOST-RESOURCES-V2-MIB (oid 1.3.6.1.2.1.25) , there is usually a lot of interesting things, memory, processor, network. There is a reservation about the network - versions of vSphere (I suspect that iESX) have a cant before some build, which is that 64-bit traffic counters work for outgoing traffic and return 0 for incoming traffic. Then vmware fixed it, but if you suddenly have outgoing when monitoring network traffic, but there is no incoming one - this is it, don't be intimidated, you need to raise the version.

Storage systems (and it is easy to guess that they are external to the cluster and can fall off) are also available in the 25th branch (oid 1.3.6.1.2.1.25.2) with one reservation - vSphere is nowhere and does not return the names of the connected drives. Ie hrDeviceDescr see the name and lun number (LUN HP HSV300 0953 naa.50014380025cf510), and a mount point of something like / vmfs / volumes / 4e343177-a470f8bb-4e25-04257f664f9e, partiton label is also very informative (naa.600508b1001c1bc8b9036a0d8b117c88: one).
')
And even vmware admins it is important to see the name of the disk, not its cipher. Therefore, I had to collective-farm my own script, which would monitor disks on vmware and describe them in terms understandable to others.

check_vmwarediskstatus.pl
#!/usr/local/bin/perl # # (C) Smithson Inc # # #use strict; use lib "/usr/local/libexec/nagios"; use utils qw($TIMEOUT %ERRORS &print_revision &support); use vars qw($PROGNAME); use Getopt::Long; use Time::gmtime; use vars qw($opt_V $opt_h $verbose $opt_w $opt_c $opt_H); $PROGNAME = `basename $0`; my $warning = 90; my $critical = 95; my $community = 'public'; my $MAX = 16; Getopt::Long::Configure('bundling'); GetOptions ( "w=s" => \$opt_w, "warning=s" => \$opt_w, "c=s" => \$opt_c, "critical=s" => \$opt_c, "H=s" => \$opt_H, "hostname=s" => \$opt_H); $opt_H = shift unless ($opt_H); my $host = $1 if ($opt_H =~ m/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z][-a-zA-Z0]+(\.[a-zA-Z][-a-zA-Z0]+)*)$/); if (!(defined($host))) { print_usage(); exit $ERRORS{'UNKNOWN'}; }; my $server = $host; ($opt_c) || ($opt_c = shift) || ($opt_c = 95); $critical = $1 if ($opt_c =~ /([0-9]+)/); ($opt_w) || ($opt_w = shift) || ($opt_w = 90); $warning = $1 if ($opt_w =~ /([0-9]+)/); $RETURN_CODE = $ERRORS{'UNKNOWN'}; $SNMP = "/usr/local/bin/snmpwalk -v2c -c $community"; $OID_SYSNAME = '1.3.6.1.2.1.1.5.0'; $OID_STORAGE = '1.3.6.1.2.1.25.2'; my $s = getStorageState($server); my $code = 'UNKNOWN'; if ($RETURN_CODE == $ERRORS{'OK'}) { $code = 'OK '; } if ($RETURN_CODE == $ERRORS{'WARNING'}) { $code = 'WARNING '; } if ($RETURN_CODE == $ERRORS{'CRITICAL'}) { $code = 'CRITICAL '; } print "$code - $s \n"; exit $RETURN_CODE; # ================================================================ sub getStorageState { my $ip = shift; my $ret = ''; my $i; my @size, @used, @name= (); for ($i = 0; $i<$MAX+1; $i++) { $size[$i] = 0; } my @s = getSNMPdata($ip, $OID_STORAGE); if ($#s == 0) { return ''; } $RETURN_CODE = $ERRORS{'OK'}; foreach $q (@s) { chomp($q); if ($q =~ /hrStorageSize\.(\d+) = INTEGER: (\d+)/) { $size[$1] = $2; } if ($q =~ /hrStorageUsed\.(\d+) = INTEGER: (\d+)/) { $used[$1] = $2; } if ($q =~ /hrStorageDescr\.(\d+) = STRING: \/vmfs\/volumes\/(.+)/) { $name[$1] = getdatastoragename($2); } if ($q =~ /hrStorageAllocationFailures\.(\d+) = Counter32: (\d+)/) { if ($2 != 0) { $ret = $ret."\# $1 failure! (code $2) "; $RETURN_CODE = $ERRORS{'CRITICAL'}; } } }; for ($i = 0; $i<$MAX+1; $i++) { if ($size[$i] > 0) { my $p = (100*$used[$i])/$size[$i]; my $sp = sprintf("%0.2f", $p); if (length($ret) > 1) { $ret = $ret.", "; } $ret = $ret."$name[$i]=$sp\%"; if (($p > $warning) && ($RETURN_CODE == $ERRORS{'OK'})) { $RETURN_CODE = $ERRORS{'WARNING'}; } if ($p > $critical) { $RETURN_CODE = $ERRORS{'CRITICAL'}; } }; } return $ret; } # ================================================================ sub getSNMPdata { my $ip = shift; my $snmpquery = shift; my $q, @dat; $q = "$SNMP $ip $snmpquery"; @dat = `$q`; return @dat; } # ================================================================ sub getSNMPstring { my $ip = shift; my $snmpquery = shift; my $q, $dat; $q = "$SNMP $ip $snmpquery"; $dat = `$q`; chomp $dat; if (length($dat) < 1) { return ''; } if ($dat =~ /= STRING:\ (.+)/) { $dat = $1 }; return $dat; } # ================================================================ sub getdatastoragename () { my $id = shift; my $ret = '?'; my %names = ( '4b4468fe-c310d5c8-e0ee-002481e8ae94' => 'EVA2Tb', '4f3b9661-776069e9-5002-78e7d158f891' => 'EVA360Gb', '54f5b0bc-97f70749-e088-f0921c1099b0' => 'NN1.5Tb', '52e8d119-309fe1b1-10fb-d89d676e0ce0' => 'EVA2TB_2', '55c07bc8-6365350e-c56b-3c4a92e5f7f4' => '0CLONE', ); foreach $key (keys %names) { if ($id eq $key) { return $names{$key}; }; }; return $ret; } # ================================================================ sub print_usage () { print "Usage: $PROGNAME -H <host> [-w <warn>] [-c <crit>] \n"; } # ================================================================ sub print_help () { print_revision($PROGNAME,''); print "Copyright (c) Smithson Inc, 2012\n"; print "\n"; print_usage(); print "\n"; print "<warn> = Signal strength at which a warning message will be generated.\n"; print "<crit> = Signal strength at which a critical message will be generated.\n"; support(); }; # ================================================================ 

The magic lies in the line

  my %names = ( '4b4468fe-c310d5c8-e0ee-002481e8ae94' => 'EVA2Tb', '4f3b9661-776069e9-5002-78e7d158f891' => 'EVA360Gb', '54f5b0bc-97f70749-e088-f0921c1099b0' => 'NN1.5Tb', '52e8d119-309fe1b1-10fb-d89d676e0ce0' => 'EVA2TB_2', '55c07bc8-6365350e-c56b-3c4a92e5f7f4' => '0CLONE', ); 

it has to be edited every time a new disk is added to the servers. For four years - already twice.

No matter how mysterious it may seem, but on different vSphere servers located in different clusters, these codes are the same for the same disk.

The names and ciphers of local disks for all servers are different, but in our case they are not interesting for us, locally we only have test projects, so the overflow of local storage doesn’t bother us in the long run. But if it is important to you, then you can add here cipher and name matches for local datastore.

Another specific to vmware is information on virtual machines. It lies behind the OID 1.3.6.1.4.1.6876

    1.3.6.1.4.1.6876.2.1.1.5     1.3.6.1.4.1.6876.2.1.1.6   CPU 1.3.6.1.4.1.6876.3.1.1 

This script pushes the data into the rrdtool database, since we do not need to respond to changes in the RAM load or the number of virtual machines. But based on it you can make a plugin for nagios.

check_vmwaregetstatus.pl
 #!/usr/local/bin/perl # # (C) by Smithson Inc, 2013 # require "srv.list"; my $RRD = '/usr/local/bin/rrdtool'; my $EMPTY = ":U:U:U:U:U:U:U:U:U:U"; my @DATA = (), @VM = (); my $OID_VMWARE = '1.3.6.1.4.1.6876'; my $OID_IF_OUT = '.1.3.6.1.2.1.31.1.1.1.6'; my $OID_IF_IN = '.1.3.6.1.2.1.31.1.1.1.10'; ##my $OID_IF_IN = '.1.3.6.1.2.1.2.2.1.16'; my $SNMP = '/usr/local/bin/snmpwalk -v2c -c '; my $AWK = '/usr/bin/awk'; my $FILENAME='vmware.snmpdata'; my $MEMORY_MASK = '.6876.2.1.1.5.'; my $CORES_MASK = '.6876.2.1.1.9.'; my $MEMSIZE_MASK = '.6876.3.2.1'; my $CPUCOUNT_MASK = '.6876.3.1.1'; my $POWERED_MASK = '.6876.2.1.1.6.'; my $i; foreach $i (sort keys %servers) { my $traf= getIFinfo($i); my $t = getVMinfo($i); $t='N'.$traf.':'.$t.$EMPTY; my $rrd = "$RRD update $DBPATH/$i.rrd $t"; system("$rrd") && print "ERROR update '$DBPATH/$i.rrd': $!\n"; } # ================================================================ sub searchinfo { # Search info by MASK my $mask = shift; my $i, @ret = (), $r = 0; my $c = @DATA+1; for ($i = 0; $i < $c; $i++) { if ($DATA[$i] =~ /$mask(.+)\s*=\s*([a-zA-Z0-9]+)\:\s+(.+)$/) { $ret[$r] = $3; $r++; } } return @ret; } # ================================================================ sub IsVMrun { # Return 0 if VM is Off or 1 is VM is On my $id = shift; # VM id my $r = 0; for ($i = 0; $i < @VM; $i++) { if ($id == $VM[$i]) { $r = 1; last; } } return $r; } # ================================================================ sub memoryinfo { # Return 2 values - Memory Allocated All & Memory Allocated on run VMs my $mask = $MEMORY_MASK; my $i, $all = 0, $used = 0; my $c = @DATA+1; for ($i = 0; $i < $c; $i++) { if ($DATA[$i] =~ /$mask(.+)\s*=\s*([a-zA-Z0-9]+)\:\s+(.+)$/) { $all = $all + $3; if (IsVMrun($1) == 1) { $used = $used + $3; } } } $all = $all*1000*1000; $used = $used*1000*1000; return ($all, $used); } # ================================================================ sub coresinfo { # Return 2 values - Cores Total Allocated & Cores Allocated on run VMs my $mask = $CORES_MASK; my $i, $all = 0, $used = 0; my $c = @DATA+1; for ($i = 0; $i < $c; $i++) { if ($DATA[$i] =~ /$mask(.+)\s*=\s*([a-zA-Z0-9]+)\:\s+(.+)$/) { $all = $all + $3; if (IsVMrun($1) == 1) { $used = $used + $3; } } } return ($all, $used); } # ================================================================ sub getVMinfo { my $ip = shift; my $ret, $s, $count = 0; my $q = "$SNMP $ip $OID_VMWARE >$FILENAME.$ip"; `$q`; $#DATA = -1; open(F, "<$FILENAME.$ip"); while (defined($s=<F> )) { chomp $s; push @DATA, $s; } close F; unlink("$FILENAME.$ip"); ($count, $oncount) = countVM(); my ($memall, $memused) = memoryinfo(); my ($corecount, $coreused) = coresinfo(); my ($memsize) = searchinfo($MEMSIZE_MASK); $memsize = ($memsize/1024)*1000000; my ($cpucount) = searchinfo($CPUCOUNT_MASK); $ret = "$count:$corecount:$cpucount:$servers{$ip}:U:U:U:U:$memsize:$memused:$oncount:$memall:$coreused"; return $ret; } # ================================================================ sub countVM { # Return 2 values - VMcount & VMUpCount; filled the @VM array by indexs of UP VMs. my $r = 0, $up = 0, $i, $c = @DATA+1; @VM = (); for ($i = 0; $i < $c; $i++) { if ($DATA[$i] =~ /$POWERED_MASK(.+)\s*=\s*([a-zA-Z0-9]+)\:\s+\"(powered.+)\"/) { $r++; my $f1 = $1, $f2 = $2, $f3 = $3; if ($f3 =~ /on/i) { $up++; push @VM, $f1; } } } return ($r, $up); }; # ================================================================ sub getIFinfo { my $ip = shift; my $i, $c = 0; my $q, $ret = ""; for ($i = 1; $i < 5; $i++) { $q = $SNMP." $ip $OID_IF_IN\.$i | $AWK \'\{print \$4\}\'"; my $s = `$q`; chomp $s; if ($s =~ /^(\d+)$/) { $ret=$ret.":$s"; $c++; } }; for ( ; $c < 4; $c++ ) { $ret = $ret.':U'; } for ($i = 1; $i < 5; $i++) { $q = $SNMP." $ip $OID_IF_OUT\.$i | $AWK \'\{print \$4\}\'"; my $s = `$q`; chomp $s; if ($s =~ /^(\d+)$/) { $ret=$ret.":$s"; $c++; } }; for ( ; $c < 8; $c++ ) { $ret = $ret.':U'; } return $ret; } 


srv.lst
 %servers = ( '10.11.1.11' => 40,'10.11.1.12' => 40,'10.11.1.14' => 40,'10.11.1.15' => 40, '10.11.1.8' => 32,'10.11.1.9' => 32,'10.11.1.7' => 32, '10.11.1.3' => 24,'10.11.1.6' => 24 ); $targetdir = '/data//rrdtool/www/vmware'; $DBPATH = '/data/rrdtool/vmware/data'; @periodlist = ('10h', '2d', '10d', '30d', '1y', '3y'); 

The hash values ​​are the maximum number of processors (cores) on this server. It was easier for me to do this than to calculate this number each time based on the line counting of a ProcessorLoad or CPU Pkg / ID / Node. The number of processors at the server varies very rarely :)

srv.lst is such a common file that will attack both the monitoring script and the html-page generation script and the drawing script.

Now let's talk about Rittal CMC-TC .

Rittal CMC-TC is a development by rittal for monitoring environmental conditions - temperature, humidity and airflow. True, the airflow sensors are ugly there, they do not return the “wind” speed, but 0 means no flow and 1 means there is flow. And they are regulated by analog, twist the Werner sensor with a bayonet screwdriver and thus set the threshold between "wind is" and "there is no wind." But the song is not about that.

The system itself consists of a processor module PU, to which you can connect up to 4 (the sockets are numbered 1, 2, 3 and 4) of the sensor hubs. Up to 4 sensors can be connected to each hub.

Further, incomprehensible logic comes into force. Monitoring for snmp is possible (snmp is configured in the network settings) and is hidden behind the OID .1.3.6.1.4.1.2606.4.2 . The first sensor hub connected is number 3, the second is 4, the third is 5, and the fourth is 6. Everything is logical, isn't it? The sensors on the hub, in turn, are numbered 1, 2, 3, and 4, which suggests that the two devices were programmed by different unfamiliar people. And between the sensor number and the hub number there are 4 more (!) OID branches.

Again:

.1.3.6.1.4.1.2606.4.2. 3 .5.2.1.5. 1 is the reading of the first sensor of the first hub.
.1.3.6.1.4.1.2606.4.2. 6 .5.2.1.5. 4 is the readings of the fourth sensor of the fourth hub.
And don't ask me why :)

Now about monitoring
 define command { command_name check_snmp_oid command_line $USER1$/check_snmp -H $HOSTADDRESS$ -o $ARG1$ -C $ARG2$ -w $ARG3$ -c $ARG4$ -u $ARG5$ -l "" } define service{ name temperature-service use generic-service register 0 contact_groups conditions notification_options c,r } define service{ use temperature-service host_name CMC-02 service_description Temperature Floor 12 point 1 check_command check_snmp_oid!.1.3.6.1.4.1.2606.4.2.5.5.2.1.5.3!!20!31!C } 

As you can easily guess now, this is a poll of the third sensor on the third hub on the SMS-2 processor module. And judging by the "C" is the temperature :)

Where and how you place the sensors is your business, do not forget to just draw a map, it will come in handy.

Nagios and Synology

.
Synology has excellent semi-wholesale network disk storages that we use for backup backups (typing 40 TB on synology costs about 300,000 rubles, and on HP EVA or HP 3PAR - even three million may not be enough). Therefore, we have a lot of synology, there are also quite a few disks in them and we need to keep track of all this. What do you want?

Inside Synology, the usual linux (ssh works, you can put packages, for example, rrdtool or mc, rsync works) and respond to snmp-requests for the 25th branch ( OID 1.3.6.1.2.1.25 ).
Additionally, you can find out the status of the disks and their temperature.

get-synologydisks.pl
 #!/usr/local/bin/perl # # (C) Smithson Inc # # #use strict; use lib "/usr/local/libexec/nagios"; use utils qw($TIMEOUT %ERRORS &print_revision &support); use vars qw($PROGNAME); use Getopt::Long; use Time::gmtime; use vars qw($opt_V $opt_h $verbose $opt_w $opt_c $opt_H $volname $opt_mode $mode); $PROGNAME = `basename $0`; Getopt::Long::Configure('bundling'); GetOptions ("V" => \$opt_V, "version" => \$opt_V, "h" => \$opt_h, "help" => \$opt_h, "m=s" => \$opt_mode, "mode=s" => \$opt_mode, "w=s" => \$opt_w, "warning=s" => \$opt_w, "c=s" => \$opt_c, "critical=s" => \$opt_c, "H=s" => \$opt_H, "hostname=s" => \$opt_H); if ($opt_V) { print_revision($PROGNAME,''); #' exit $ERRORS{'OK'}; } if ($opt_h) { print_help(); exit $ERRORS{'OK'}; } $opt_H = shift unless ($opt_H); my $host = $1 if ($opt_H =~ m/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z][-a-zA-Z0]+(\.[a-zA-Z][-a-zA-Z0]+)*)$/); if (!(defined($host))) { print_help(); exit $ERRORS{'ERROR'}; }; ($opt_c) || ($opt_c = shift) || ($opt_c = 4); my $critical = $1 if ($opt_c =~ /([0-9]+)/); ($opt_w) || ($opt_w = shift) || ($opt_w = 3); my $warning = $1 if ($opt_w =~ /([0-9]+)/); # # $mode == 0 - get temperature # $mode == 1 - get disk status # my $mode = 0; ($opt_mode) || ($opt_mode = shift) || ($opt_mode = 'temp'); if ($opt_mode =~ /status/i) { $mode = 1; } $code = $ERRORS{'OK'}; my $community = 'public'; my $snmpwalk = "/usr/local/bin/snmpwalk -v 2c -c $community -t 15"; my $OID_DISKSTAT = '.1.3.6.1.4.1.6574.2.1.1.5'; my $OID_DISKTEMP = '.1.3.6.1.4.1.6574.2.1.1.6'; my $n = ''; if ($mode == 0) { # get temp $n = $OID_DISKTEMP; } if ($mode == 1) { # get status $n = $OID_DISKSTAT; } $n = getsyn($host, $n); print "Results: $n\n"; exit ($code); # ================================================================ sub getsyn { my $ip = shift, $s, $ret; my $OID = shift; my @D = getSNMPwalk($ip, $OID); foreach $s (@D) { if ($s eq 'U') { exit $ERRORS{'ERROR'}; }; if (length($ret) > 0) { $ret = $ret.", "; } if ($s =~ /\= INTEGER\: (\d+)/) { $ret = $ret."$1"; if ($1 >= $critical) { $code = $ERRORS{'CRITICAL'}; } if ($code != $ERRORS{'CRITICAL'} && $1 >= $warning) { $code = $ERRORS{'WARNING'}; } } } return $ret; } # ================================================================ sub getSNMPwalk { my $ip = shift; my $snmpquery = shift; my $q, @dat; $q = "$snmpwalk $ip $snmpquery"; @dat = `$q`; if ($#dat < 1) { return ('U'); } return @dat; } # ================================================================ sub print_usage () { print "Usage: $PROGNAME -H <host> [-v <volumename>] [-w <warn>] [-c <crit>] [-m <mode>]\n"; } # ================================================================ sub print_help () { print_revision($PROGNAME,''); print "Copyright (c) Smithson Inc, 2011\n"; print "\n"; print_usage(); print "\n"; print "<warn> = Signal strength at which a warning message will be generated.\n"; print "<crit> = Signal strength at which a critical message will be generated.\n"; print "<mode> = temp or status. Default is temp.\n\t Temp return temperature of disks\n\t Status return disks status in RAID. Correct status is 1";\n"; }; # ================================================================ 

with mode = temp (default) returns the temperature of all disks, with mode = status - status of disks in RAID. 1 Normal, 2 Initialized, 3 Not Initialized, 4 System Partition Failed, 5 Crashed. Correspondingly, 1 is normal, 2 is warning, everything else is critical.

To poll synology, which have a lot of disks, you need to increase the timeout (it costs 15 seconds here), otherwise she does not have time to answer.

Nagios and UPS


We have bespereboynik two manufacturers - APC and Chloride. Let's start with APC . The information specific to these UPSs is behind the OID .1.3.6.1.4.1.318 . What can be extracted? A lot - ttl (how many more will the ups be under current load, if you take electricity away from it right now), does ups work on batteries or not, do you need to change batteries, what is the temperature inside the box, input-output voltage, charge level.

APC monitoring
 define service{ name ups-service active_checks_enabled 1 passive_checks_enabled 1 parallelize_check 1 obsess_over_service 1 check_freshness 0 notifications_enabled 1 event_handler_enabled 1 flap_detection_enabled 1 failure_prediction_enabled 1 process_perf_data 1 retain_status_information 1 retain_nonstatus_information 1 is_volatile 0 check_period 24x7 max_check_attempts 3 normal_check_interval 5 retry_check_interval 1 notification_options c,r notification_interval 120 notification_period 24x7 register 0 contact_groups admins,power-admins } #APC Battery needs replacement define service{ use ups-service hostgroup_name APC-smart service_description APC Battery needs replacement check_command check_snmp!-o .1.3.6.1.4.1.318.1.1.1.2.2.4.0 -C XXXX -c 2 notification_period workhours } #APC status define service{ use ups-service hostgroup_name APC-smart service_description APC status check_command check_snmp!-o .1.3.6.1.4.1.318.1.1.1.4.1.1.0 -C XXXX -c 2 contact_groups smsgroup,power-admins } #APC Battery temperature define service{ use ups-service hostgroup_name APC-smart service_description APC Battery temperature check_command check_snmp!-o .1.3.6.1.4.1.318.1.1.1.2.2.2.0 -C XXXX -w 38 -c 45 -u C contact_groups smsgroup,power-admins notification_period workhours } # APC worktime 100 ticks * 60 sec define service{ use ups-service hostgroup_name APC-smart service_description APC WorkTime check_command check_snmp!-o .1.3.6.1.4.1.318.1.1.1.2.2.3.0 -C XXXX -w 120000: -c 18000: -u sec*100 contact_groups power-admins notification_period workhours } 

ttl APC returns to 1/100 of a second (well, it’s convenient for him) and to get the minutes it should be divided by 6000. I think you can write such a script in one line.

From Chloride can extract less. TTL, temperature, condition (battery or mains), input-output voltage, charge level. It responds to the standard OID for UPS (1.3.6.1.2.1.33) .

nagios + chloride
 define service{ use ups-service host_name UPS1, UPS2 service_description Chloride temperature check_command check_snmp!-o 1.3.6.1.2.1.33.1.2.7.0 -C public -w 38 -c 45 -u C contact_groups smsgroup,power-admins } define service{ use ups-service host_name UPS1, UPS2 service_description Chloride WorkTime check_command check_snmp!-o 1.3.6.1.2.1.33.1.2.3.0 -C public -w 23: -c 11: -u min contact_groups smsgroup,power-admins } 


But the work time (ttl) it returns in minutes, not in hundredths of a second, like APC!
In addition, since chloride "cluster" UPS (trained to work on one load together), then they can still get information on the phases of the input and output signal. Confused by this, however, is not enough.

Since with UPS the jokes are bad, the information about the problems in them is duplicated on sms to several particularly lucky employees.

Printers


At once I will tell, nagios does not monitor printers for me. We monitor the iPrint queues, it's more convenient. But for the convenience of counting and predicting the consumption of cartridges, we have a script that draws in rrdtool graphs of consumption of cartridges and paper. It is possible for a certain period to understand whether or not they use the printer (300 sheets per year - you can take pictures :)), how cartridges are spent, what kind of cartridges are there, etc.

printers_get_snmp.pl
 #!/usr/bin/perl # # (C) Smithson Inc, 2008 # require "prn.list"; $RRD = '/usr/local/bin/rrdtool'; $DBNAME = '/data/rrdtool/printers/prn-pagecount.rrd'; $AWK = '/usr/bin/awk'; @DATA = (); for ($i=1; $i < 255; $i++) { $DATA{$i} = 'U'; } foreach $i (@usedip) { $DATA{$i} = getPageCount($i); } $s = 'N'; for ($i=1; $i < 255; $i++) { $s = $s.":$DATA{$i}"; } $rrd = "$RRD update $DBNAME $s"; #print "$rrd \n"; system("$rrd") && print "ERROR update '$DBNAME': $!\n"; sub getPageCount { my $ip = shift; #print "$ip\n"; $q = "/usr/local/bin/snmpget -v1 -c public 192.168.0.$ip 1.3.6.1.2.1.43.10.2.1.4.1.1 | $AWK \'\{print \$4\}\'"; $dat = `$q`; chomp $dat; if ($dat =~ /[Az]/) { $dat = 'U' }; if (length($dat) < 1) { $dat = 'U' }; return $dat } 


toners_get_snmp.pl
 #!/usr/bin/perl # # (C) Smithson Inc, 2008 # use Encode; require "prn.list"; $RRD = '/usr/local/bin/rrdtool'; $DBNAME = '/data/rrdtool/printers/prn-toner.rrd'; $SNMP = '/usr/local/bin/snmpget -v1'; $INDEXMAX = 6; $TONERDEBUG = ''; @TONERSTATUS = (); @PRNNAME = (); @TONERNAME = (); for ($i=1; $i < 256; $i++) { $TONERNAME[$i] = "X"; $TONERSTATUS[$i] = 'U:U:U:U:U:U'; $PRNNAME[$i] = ""; } LoadPRNData($PRNINFOfile); foreach $i (@usedip) { getPRNInfo($i); } $t = 'N'; for ($i=1; $i < 256; $i++) { $t = $t.":$TONERSTATUS[$i]"; } # --------- debug ! #print "$t\n"; #print "$TONERDEBUG\n"; # --------------- ! $rrd = "$RRD update $DBNAME $t"; my $q = `$rrd`; if (length($q) > 2) { print "ERROR update '$DBNAME': $q\n"; } StorePRNData($PRNINFOfile); sub getPRNInfo { my $ip = shift; my ($res,$r) = ''; my ($i,$k); my ($dat) = ''; my ($tonerstatus) = '1.3.6.1.2.1.43.11.1.1.9.1'; my ($tonername) = '1.3.6.1.2.1.43.11.1.1.6.1'; my ($prnname) = '1.3.6.1.2.1.1.5.0'; $q = "$SNMP -c public 192.168.0.$ip $prnname | awk \'\{print \$4\}\'"; $dat = `$q`; chomp $dat; # ------------ debug ---------------- #print "$ip (prnname) = $dat \n"; if (length($dat) < 1) { return } $PRNNAME[$ip] = $dat; $k = 1; for ($i = 1; $i <= $INDEXMAX; $i++) { $q = "$SNMP -c public 192.168.0.$ip $tonerstatus.$i | awk \'\{print \$4\}\'"; $dat = `$q`; chomp $dat; # ------------ debug ---------------- #print "$ip (status) = $dat \n"; if (length($dat) < 1) { last } if ($dat < 0) { if ($dat == -3) { $dat = 100 }; if ($dat == -2) { $dat = 30 }; if ($dat == -1) { $dat = 10 }; } if (length($res) < 1) { $res = $dat } else { $res = $res.":$dat"; } $k++; $q = "$SNMP -c public 192.168.0.$ip $tonername.$i"; $dat = `$q`; chomp $dat; $dat =~ s/\n//g; # ------------ debug ---------------- #print "$ip (name) = $dat \n"; if ($dat =~ /STRING: \"(.+)\"/) { $r = $r."$1 |"; } elsif ($dat =~ /Hex-STRING: (.+)/) { #print "$dat\n"; my $s = getStringH($1); $r = $r."$s |"; } else { last }; } Encode::from_to($r, 'utf-8', 'windows-1251'); $r =~ s/\?+//g; for ($i = $k; $i<= $INDEXMAX; $i++) { if (length($res) < 1) { $res = 'U' } else { $res = $res.':U'; } } $TONERSTATUS[$ip] = $res; $TONERNAME[$ip] = $r; $TONERDEBUG = $TONERDEBUG."$ip: $res \n"; } sub StorePRNData { my $filename = shift; my $i; my $s = ""; foreach $i (@usedip) { if ((length($PRNNAME[$i]) > 2) && (length($TONERNAME[$i]) > 2)) { $s = $s."$i = "; $s = $s."$PRNNAME[$i] / "; $s = $s."$TONERNAME[$i]"; $s = $s."\n"; } } open (F, ">$HOME/$filename"); print F $s; close F; } sub getStringH { my $s = shift; $s =~ s/(00)//egi; $s =~ s/([0-9a-f][0-9a-f])/chr(hex($1))/egi; $s =~ s/ //g; return $s; } 


toners_draw.pl
 #!/usr/bin/perl # # (C) Smithson Inc, 2008 # use Encode; require "prn.list"; $RRD = '/usr/local/bin/rrdtool'; $DBNAME = '/data/rrdtool/printers/prn-toner.rrd'; $IMGPATH= '/data/rrdtool/www/printers/img'; my $BLACK = '#000000'; my $YELLOW = '#FFFF00'; my $CYAN = '#00CCFF'; my $MAGENTA= '#EE00EE'; my $FUSION = '#00CC00'; my $FUSION1= '#CC0000'; my $TICKCOLOR = '#888888'; $INDEXMAX = 6; @TONERSTATUS = (); @PRNNAME = (); @TONERNAME = (); LoadPRNData ($PRNINFOfile); DrawToners(340, 230, "-48h"); foreach $j (@periodlist) { DrawToners(500, 300, "-$j"); } sub DrawBlack { #    -  -   - ,  -  my $ip = shift; # ip address my $width = shift; my $height = shift; my $period = shift; my ($toner, $fusion) = split (/ \|/, $TONERNAME[$ip]); my $title = $PRNNAME[$ip]; #   ,   ,   ip #      ,       ip if (length($title) < 2) { $title = "192.168.0.$ip" } elsif ($width > 350) { $title = $title." (192.168.0.$ip)" } my $q = "$RRD graph $IMGPATH/toner".$ip.$period.".png "; $q = $q."--start $period --end now "; $q = $q."--width $width --height $height "; $q = $q."--full-size-mode "; $q = $q."--title \"$title Info ($period)\" "; if ((length($fusion) > 31) && ($width < 350)) { $fusion = substr($fusion, 0, 29)."..."; } # else { $q = $q."--lazy "; } $q = $q."--lower-limit 0 "; $q = $q." DEF:p01=$DBNAME:prn".$ip."toner1status:AVERAGE "; $q = $q." CDEF:pp1=p01 "; $q = $q." CDEF:z1=p01,0,EQ "; if (length($fusion) > 1) { $q = $q." DEF:p02=$DBNAME:prn".$ip."toner2status:AVERAGE "; } else { $q = $q."CDEF:p02=p01,0,\* "; } $q = $q." CDEF:fusion1=p02,0.01,\* "; $q = $q." CDEF:fusion=0,fusion1,- "; # } $q = $q." AREA:p01$BLACK:\"$toner \" "; $q = $q."GPRINT:pp1:LAST:\"%0.0lf\\j\" "; $q = $q." TICK:z1$TICKCOLOR:1 "; # if (length($fusion) > 1) { $q = $q." LINE3:fusion$FUSION:\"$fusion\" "; $q = $q."GPRINT:p02:LAST:\"%0.0lf\\j\""; # } my $dat = `$q`; } sub DrawColor { #      -   -  , -- -  # - -  my $ip = shift; # ip address my $width = shift; my $height = shift; my $period = shift; my ($color0, $color1, $color2, $color3) = ($BLACK, $CYAN, $MAGENTA, $YELLOW); my ($toner0, $toner1, $toner2, $toner3, $fusion, $fusion1) = split (/ \|/, $TONERNAME[$ip]); ($color0, $color1, $color2, $color3) = SortColors(($toner0, $toner1, $toner2, $toner3)); my $title = $PRNNAME[$ip]; #   ,   ,   ip #      ,       ip if (length($title) < 2) { $title = "192.168.0.$ip" } elsif ($width > 350) { $title = $title." (192.168.0.$ip)" } my $q = "$RRD graph $IMGPATH/toner".$ip.$period.".png "; $q = $q."--start $period --end now "; $q = $q."--width $width --height $height "; $q = $q."--full-size-mode "; $q = $q."--title \"$title Info ($period)\" "; if ((length($fusion1) > 31) && ($width < 350)) { $fusion1 = substr($fusion1, 0, 29)."..."; } else { $q = $q."--lazy "; } $q = $q."--lower-limit 0 "; $q = $q." DEF:p01=$DBNAME:prn".$ip."toner1status:AVERAGE "; $q = $q." DEF:p02=$DBNAME:prn".$ip."toner2status:AVERAGE "; $q = $q." DEF:p03=$DBNAME:prn".$ip."toner3status:AVERAGE "; $q = $q." DEF:p04=$DBNAME:prn".$ip."toner4status:AVERAGE "; $q = $q." CDEF:pp1=p01 "; $q = $q." CDEF:pp2=p02 "; $q = $q." CDEF:pp3=p03 "; $q = $q." CDEF:pp4=p04 "; $q = $q." CDEF:z1=p01,0,EQ "; $q = $q." CDEF:z2=p02,0,EQ "; $q = $q." CDEF:z3=p03,0,EQ "; $q = $q." CDEF:z4=p04,0,EQ "; $q = $q." CDEF:z5=z1,z2,+ "; $q = $q." CDEF:z6=z5,z3,+ "; $q = $q." CDEF:z0=z6,z4,+ "; $q = $q." DEF:p05=$DBNAME:prn".$ip."toner5status:AVERAGE "; $q = $q." CDEF:fusion0=p05,0.1,\* "; $q = $q." CDEF:fusion=0,fusion0,- "; $q = $q." DEF:p06=$DBNAME:prn".$ip."toner6status:AVERAGE "; $q = $q." CDEF:fusion2=p06,0.1,\* "; $q = $q." CDEF:fusion1=0,fusion2,- "; $q = $q." TICK:z0$TICKCOLOR:1 "; $q = $q." AREA:pp1$color0:\"$toner0\" "; $q = $q."GPRINT:pp1:LAST:\"%0.0lf\\j\" "; $q = $q." STACK:pp2$color1:\"$toner1\" "; $q = $q."GPRINT:pp2:LAST:\"%0.0lf\\j\" "; $q = $q." STACK:pp3$color2:\"$toner2\" "; $q = $q."GPRINT:pp3:LAST:\"%0.0lf\\j\" "; $q = $q." STACK:pp4$color3:\"$toner3\" "; $q = $q."GPRINT:pp4:LAST:\"%0.0lf\\j\" "; if (length($fusion) > 1) { $q = $q." LINE3:fusion$FUSION:\"$fusion\" "; $q = $q."GPRINT:p05:LAST:\"%0.0lf\\j\" "; } if (length($fusion1) > 1) { $q = $q." LINE3:fusion1$FUSION1:\"$fusion1\" "; $q = $q."GPRINT:p06:LAST:\"%0.0lf\\j\" "; } my $dat = `$q`; } sub SortColors { #            my @list = @_; my (@c) = ($BLACK, $CYAN, $MAGENTA, $YELLOW); my $i; for ($i = 0; $i < 4; $i++) { my $s = $list[$i]; if ($s =~ /Black/i) { $c[$i] = $BLACK; } if ($s =~ /Cyan/i) { $c[$i] = $CYAN; } if ($s =~ /Magent/i) { $c[$i] = $MAGENTA; } if ($s =~ /Yellow/i) { $c[$i] = $YELLOW; } } return @c; } sub DrawToners { #    ,      - my $width = shift; my $height = shift; my $period = shift; my ($i); my ($name); foreach $i (@usedip) { $name = $TONERNAME[$i]; my @aa = split(/\|/, $name); my $qa = $#aa+1; #print "$i = $qa ($name) \n"; if ($qa > 3) { DrawColor($i, $width, $height, $period); } else { DrawBlack($i, $width, $height, $period); } }; } 


prn.list
 @usedip = ( 115, 122,124,125,128,129, 131,132,136,137, 140,141,142,145,147,148, 150,152,155,157, 160,162,164,165,166,167,168,169, 171,172,173,174,175,176,177,179, 180,182,183,185,186,188,189, 190,191,192,194,195,197,198,199, 201,202,203,205,207,208,209, 210,212,215,216,217,219, 220,225, 235,236,237, 241,245 ); @periodlist = ('14h', '2d', '10d', '30d', '1y'); $HOME = '/data/rrdtool/printers'; $PRNINFOfile = 'prn.info'; sub LoadPRNData { my $filename = shift; my $i; my $s = ""; my @data; open (F, "$HOME/$filename"); @data=<F>; close F; foreach $s (@data) { if ($s =~ /(\d+) = (.+) \/ (.*)/) { $i = $1; $PRNNAME[$i] = $2; $TONERNAME[$i] = $3; } } } 


, :

prn.info
 216 = NPI93F7F3 / Black Cartridge HP CE278A | 219 = NPID6E096 / Black Cartridge HP CE278A | 220 = HOZY / Black Print Cartridge HP Q1339A |Maintenance Kit HP 110V-Q2436A, 220V-Q2437A | 225 = NPIBAA4EA / Toner Cartridge HP C4127X | 235 = Ditat_HP4700_Color / Black Cartridge HP Q5950A |Cyan Cartridge HP Q5951A |Magenta Cartridge HP Q5953A |Yellow Cartridge HP Q5952A |Image Transfer Kit HP Q7504A |Image Fuser Kit HP 110V-Q7502A, 220V-Q7503A | 237 = NPI7C543C / BlackCartridgeHPCC364X |MaintenanceKitHP110V-CB388A,220V-CB389A | 241 = WorkCentre / Black Toner Cartridge |Yellow Toner Cartridge |Magenta Toner Cartridge |Cyan Toner Cartridge |Waste Toner Container | 245 = NPI0E8A4D / Black Print Cartridge HP C8543X |Maintenance Kit HP 110V-C9152A, 220V-C9153A | 


«» , .

Cisco


, cisco nagios . But there is a nuance. , routers switchs . , vlans , . , — , cisco , — mibs, — .

. — . . Tunnel40 — .

check_iftraf
 #! /usr/local/bin/perl -w use POSIX; use strict; use lib "/usr/local/libexec/nagios" ; use utils qw($TIMEOUT %ERRORS &print_revision &support); use Net::SNMP; use Getopt::Long; &Getopt::Long::config('bundling'); my $PROGNAME = "check_iftraf"; sub print_help (); sub usage ($); sub print_usage (); sub process_arguments (); my $timeout; my $status; my %ifOperStatus = ('1','up', '2','down', '3','testing', '4','unknown', '5','dormant', '6','notPresent', '7','lowerLayerDown'); # down due to the state of lower layer interface(s) my $state = "UNKNOWN"; my $answer = ""; my $snmpkey = 0; my $community = "public"; my $maxmsgsize = 1472 ; # Net::SNMP default is 1472 my ($seclevel, $authproto, $secname, $authpass, $privpass, $privproto, $auth, $priv, $context); my $port = 161; my @snmpoids; my $sysUptime = '1.3.6.1.2.1.1.3.0'; my $snmpIfDescr = '1.3.6.1.2.1.2.2.1.2'; my $snmpIfType = '1.3.6.1.2.1.2.2.1.3'; my $snmpIfAdminStatus = '1.3.6.1.2.1.2.2.1.7'; my $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8'; my $snmpIfName = '1.3.6.1.2.1.31.1.1.1.1'; my $snmpIfLastChange = '1.3.6.1.2.1.2.2.1.9'; my $snmpIfAlias = '1.3.6.1.2.1.31.1.1.1.18'; my $snmpLocIfDescr = '1.3.6.1.4.1.9.2.2.1.1.28'; my $snmpMIBIN = '1.3.6.1.2.1.2.2.1.10'; my $snmpMIBOUT = '1.3.6.1.2.1.2.2.1.16'; my $hostname; my $ifName; my $session; my $error; my $response; my $snmp_version = 2 ; my $ifXTable; my $opt_h ; my $opt_V ; my $ifdescr; my $iftype; my $key; my $lastc; my $dormantWarn; my $adminWarn; my $name; my %session_opts; ### Validate Arguments $status = process_arguments(); # Just in case of problems, let's not hang Nagios $SIG{'ALRM'} = sub { print ("ERROR: UU No snmp response from $hostname (alarm)\n"); exit $ERRORS{"UNKNOWN"}; }; alarm($timeout); ($session, $error) = Net::SNMP->session(%session_opts); if (!defined($session)) { $state='UNKNOWN'; $answer=' UU '.$error; print ("$state: $answer\n"); exit $ERRORS{$state}; } ## map ifdescr to ifindex - should look at being able to cache this value if (defined $ifdescr || defined $iftype) { # escape "/" in ifdescr - very common in the Cisco world if (defined $iftype) { $status=fetch_ifindex($snmpIfType, $iftype); } else { $ifdescr =~ s/\//\\\//g; $status=fetch_ifindex($snmpIfDescr, $ifdescr); # if using on device with large number of interfaces # recommend use of SNMP v2 (get-bulk) } if ($status==0) { $state = "UNKNOWN"; printf "$state: UU could not retrive ifdescr/iftype snmpkey - $status-$snmpkey\n"; $session->close; exit $ERRORS{$state}; } } ## Main function $snmpIfAdminStatus = $snmpIfAdminStatus . "." . $snmpkey; $snmpIfOperStatus = $snmpIfOperStatus . "." . $snmpkey; $snmpIfDescr = $snmpIfDescr . "." . $snmpkey; $snmpIfName = $snmpIfName . "." . $snmpkey ; $snmpIfAlias = $snmpIfAlias . "." . $snmpkey ; $snmpMIBIN = $snmpMIBIN . "." . $snmpkey ; $snmpMIBOUT = $snmpMIBOUT . "." . $snmpkey ; push(@snmpoids,$snmpIfAdminStatus); push(@snmpoids,$snmpIfOperStatus); push(@snmpoids,$snmpIfDescr); push(@snmpoids,$snmpIfName) if (defined $ifXTable) ; push(@snmpoids,$snmpIfAlias) if (defined $ifXTable) ; push(@snmpoids,$snmpMIBIN); push(@snmpoids,$snmpMIBOUT); if (!defined($response = $session->get_request(@snmpoids))) { $answer=$session->error; $session->close; $state = 'WARNING'; print ("$state: SNMP error: $answer\n"); exit $ERRORS{$state}; } $answer = sprintf("host '%s', %s(%s) is %s\n", $hostname, $response->{$snmpIfDescr}, $snmpkey, $ifOperStatus{$response->{$snmpIfOperStatus}} ); ## Check to see if ifName match is requested and it matches - exit if no match ## not the interface we want to monitor if ( defined $ifName && not ($response->{$snmpIfName} eq $ifName) ) { $state = 'UNKNOWN'; $answer = "UU Interface name ($ifName) doesn't match snmp value ($response->{$snmpIfName}) (index $snmpkey)"; print ("$state: $answer\n"); exit $ERRORS{$state}; } ## define the interface name if (defined $ifXTable) { $name = $response->{$snmpIfName} ." - " .$response->{$snmpIfAlias} ; }else{ $name = $response->{$snmpIfDescr} ; } ## if AdminStatus is down - some one made a consious effort to change config ## if ( not ($response->{$snmpIfAdminStatus} == 1) ) { $answer = "Interface $name (index $snmpkey) is administratively down."; if ( not defined $adminWarn or $adminWarn eq "w" ) { $state = 'WARNING'; } elsif ( $adminWarn eq "i" ) { $state = 'OK'; } elsif ( $adminWarn eq "c" ) { $state = 'CRITICAL'; } else { # If wrong value for -a, say warning $state = 'WARNING'; } } ## Check operational status elsif ( $response->{$snmpIfOperStatus} == 2 ) { $state = 'CRITICAL'; $answer = "UU Interface $name (index $snmpkey) is down."; } elsif ( $response->{$snmpIfOperStatus} == 5 ) { if (defined $dormantWarn ) { if ($dormantWarn eq "w") { $state = 'WARNING'; $answer = "UU Interface $name (index $snmpkey) is dormant."; }elsif($dormantWarn eq "c") { $state = 'CRITICAL'; $answer = "UU Interface $name (index $snmpkey) is dormant."; }elsif($dormantWarn eq "i") { $state = 'OK'; $answer = "UU Interface $name (index $snmpkey) is dormant."; } }else{ # dormant interface - but warning/critical/ignore not requested $state = 'CRITICAL'; $answer = "UU Interface $name (index $snmpkey) is dormant."; } } elsif ( $response->{$snmpIfOperStatus} == 6 ) { $state = 'CRITICAL'; $answer = "UU Interface $name (index $snmpkey) notPresent - possible hotswap in progress."; } elsif ( $response->{$snmpIfOperStatus} == 7 ) { $state = 'CRITICAL'; $answer = "UU Interface $name (index $snmpkey) down due to lower layer being down."; } elsif ( $response->{$snmpIfOperStatus} == 3 || $response->{$snmpIfOperStatus} == 4 ) { $state = 'CRITICAL'; $answer = "UU Interface $name (index $snmpkey) down (testing/unknown)."; } else { $state = 'OK'; my $inQ = $response->{$snmpMIBIN}; my $outQ = $response->{$snmpMIBOUT}; $answer = "$inQ $outQ"; } print ("$state: $answer\n"); exit $ERRORS{$state}; ### subroutines sub fetch_ifindex { my $oid = shift; my $lookup = shift; if (!defined ($response = $session->get_table($oid))) { $answer=$session->error; $session->close; $state = 'CRITICAL'; printf ("$state: SNMP error with snmp version $snmp_version ($answer)\n"); $session->close; exit $ERRORS{$state}; } foreach $key ( keys %{$response}) { if ($response->{$key} =~ /$lookup/) { $key =~ /.*\.(\d+)$/; $snmpkey = $1; #print "$lookup = $key / $snmpkey \n"; #debug } } unless (defined $snmpkey) { $session->close; $state = 'CRITICAL'; printf "$state: Could not match $ifdescr on $hostname\n"; exit $ERRORS{$state}; } return $snmpkey; } sub usage($) { print "$_[0]\n"; print_usage(); exit $ERRORS{"UNKNOWN"}; } sub print_usage() { printf "\n"; printf "usage: \n"; printf "check_iftraf -d <IF_NAME or IF_DESC> -H <HOSTNAME> [-C <community>]\n"; printf "Copyright (C) 2000 Christoph Kron\n"; printf "check_iftraf.pl 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"; } sub print_help() { print_revision($PROGNAME, ''); print_usage(); printf "check_iftraf plugin for Nagios monitors operational \n"; printf "status of a particular network interface on the target host\n"; printf "\nUsage:\n"; printf " -H (--hostname) Hostname to query - (required)\n"; printf " -C (--community) SNMP read community (defaults to public,\n"; printf " used with SNMP v1 and v2c\n"; printf " -v (--snmp_version) 1 for SNMP v1 (default)\n"; printf " 2 for SNMP v2c\n"; printf " SNMP v2c will use get_bulk for less overhead\n"; printf " if monitoring with -d\n"; printf " -L (--seclevel) choice of \"noAuthNoPriv\", \"authNoPriv\", or \"authPriv\"\n"; printf " -U (--secname) username for SNMPv3 context\n"; printf " -c (--context) SNMPv3 context name (default is empty string)\n"; printf " -A (--authpass) authentication password (cleartext ascii or localized key\n"; printf " in hex with 0x prefix generated by using \"snmpkey\" utility\n"; printf " auth password and authEngineID\n"; printf " -a (--authproto) Authentication protocol (MD5 or SHA1)\n"; printf " -X (--privpass) privacy password (cleartext ascii or localized key\n"; printf " in hex with 0x prefix generated by using \"snmpkey\" utility\n"; printf " privacy password and authEngineID\n"; printf " -P (--privproto) privacy protocol (DES or AES; default: DES)\n"; printf " -k (--key) SNMP IfIndex value\n"; printf " -d (--descr) SNMP ifDescr value\n"; printf " -T (--type) SNMP ifType integer value (see http://www.iana.org/assignments/ianaiftype-mib)\n"; printf " -p (--port) SNMP port (default 161)\n"; printf " -I (--ifmib) Agent supports IFMIB ifXTable. Do not use if\n"; printf " you don't know what this is. \n"; printf " -n (--name) the value should match the returned ifName\n"; printf " (Implies the use of -I)\n"; printf " -w (--warn =i|w|c) ignore|warn|crit if the interface is dormant (default critical)\n"; printf " -D (--admin-down =i|w|c) same for administratively down interfaces (default warning)\n"; printf " -M (--maxmsgsize) Max message size - usefull only for v1 or v2c\n"; printf " -t (--timeout) seconds before the plugin times out (default=$TIMEOUT)\n"; printf " -V (--version) Plugin version\n"; printf " -h (--help) usage help \n\n"; printf " -k or -d or -T must be specified\n\n"; printf "Note: either -k or -d or -T must be specified and -d and -T are much more network \n"; printf "intensive. Use it sparingly or not at all. -n is used to match against\n"; printf "a much more descriptive ifName value in the IfXTable to verify that the\n"; printf "snmpkey has not changed to some other network interface after a reboot.\n\n"; } sub process_arguments() { $status = GetOptions( "V" => \$opt_V, "version" => \$opt_V, "h" => \$opt_h, "help" => \$opt_h, "v=i" => \$snmp_version, "snmp_version=i" => \$snmp_version, "C=s" => \$community, "community=s" => \$community, "L=s" => \$seclevel, "seclevel=s" => \$seclevel, "a=s" => \$authproto, "authproto=s" => \$authproto, "U=s" => \$secname, "secname=s" => \$secname, "A=s" => \$authpass, "authpass=s" => \$authpass, "X=s" => \$privpass, "privpass=s" => \$privpass, "P=s" => \$privproto, "privproto=s" => \$privproto, "c=s" => \$context, "context=s" => \$context, "k=i" => \$snmpkey, "key=i",\$snmpkey, "d=s" => \$ifdescr, "descr=s" => \$ifdescr, "l=s" => \$lastc, "lastchange=s" => \$lastc, "p=i" => \$port, "port=i" =>\$port, "H=s" => \$hostname, "hostname=s" => \$hostname, "I" => \$ifXTable, "ifmib" => \$ifXTable, "n=s" => \$ifName, "name=s" => \$ifName, "w=s" => \$dormantWarn, "warn=s" => \$dormantWarn, "D=s" => \$adminWarn, "admin-down=s" => \$adminWarn, "M=i" => \$maxmsgsize, "maxmsgsize=i" => \$maxmsgsize, "t=i" => \$timeout, "timeout=i" => \$timeout, "T=i" => \$iftype, "type=i" => \$iftype, ); if ($status == 0){ print_help(); exit $ERRORS{'OK'}; } if ($opt_V) { print_revision($PROGNAME,''); exit $ERRORS{'OK'}; } if ($opt_h) { print_help(); exit $ERRORS{'OK'}; } if (! utils::is_hostname($hostname)){ usage("Hostname invalid or not given"); } unless ($snmpkey > 0 || defined $ifdescr || defined $iftype){ usage("Either a valid snmp key (-k) or a ifDescr (-d) must be provided"); } if (defined $ifName) { $ifXTable=1; } if (defined $dormantWarn) { unless ($dormantWarn =~ /^(w|c|i)$/ ) { printf "Dormant alerts must be one of w|c|i \n"; exit $ERRORS{'UNKNOWN'}; } } unless (defined $timeout) { $timeout = $TIMEOUT; } if ($snmp_version !~ /[123]/){ $state='UNKNOWN'; print ("$state: No support for SNMP v$snmp_version yet\n"); exit $ERRORS{$state}; } %session_opts = ( -hostname => $hostname, -port => $port, -version => $snmp_version, -maxmsgsize => $maxmsgsize ); $session_opts{'-community'} = $community if (defined $community && $snmp_version =~ /[12]/); if ($snmp_version =~ /3/ ) { # Must define a security level even though default is noAuthNoPriv # v3 requires a security username if (defined $seclevel && defined $secname) { $session_opts{'-username'} = $secname; # Must define a security level even though defualt is noAuthNoPriv unless ( grep /^$seclevel$/, qw(noAuthNoPriv authNoPriv authPriv) ) { usage("Must define a valid security level even though default is noAuthNoPriv"); } # Authentication wanted if ( $seclevel eq 'authNoPriv' || $seclevel eq 'authPriv' ) { if (defined $authproto && $authproto ne 'MD5' && $authproto ne 'SHA1') { usage("Auth protocol can be either MD5 or SHA1"); } $session_opts{'-authprotocol'} = $authproto if(defined $authproto); if ( !defined $authpass) { usage("Auth password/key is not defined"); }else{ if ($authpass =~ /^0x/ ) { $session_opts{'-authkey'} = $authpass ; }else{ $session_opts{'-authpassword'} = $authpass ; } } } # Privacy (DES encryption) wanted if ($seclevel eq 'authPriv' ) { if (! defined $privpass) { usage("Privacy passphrase/key is not defined"); }else{ if ($privpass =~ /^0x/){ $session_opts{'-privkey'} = $privpass; }else{ $session_opts{'-privpassword'} = $privpass; } } $session_opts{'-privprotocol'} = $privproto if(defined $privproto); } # Context name defined or default unless ( defined $context) { $context = ""; } }else { usage("Security level or name is not defined"); } } # end snmpv3 } ## End validation 


, , , . .

nagios .

Source: https://habr.com/ru/post/307918/


All Articles