source: trunk/server/fedora/config/etc/nagios/check_uptime.pl @ 2803

Last change on this file since 2803 was 2803, checked in by leee, 7 years ago
Commit upstream check_uptime.pl From https://github.com/willixix/WL-NagiosPlugins
  • Property svn:executable set to *
File size: 26.0 KB
Line 
1#!/usr/bin/perl -w
2#
3# ============================== SUMMARY =====================================
4#
5# Program : check_uptime.pl
6# Version : 0.521
7# Date    : Oct 4, 2012
8# Authors : William Leibzon - william@leibzon.org
9# Licence : GPL - summary below, full text at http://www.fsf.org/licenses/gpl.txt
10#
11# =========================== PROGRAM LICENSE =================================
12#
13# This program is free software; you can redistribute it and/or modify
14# it under the terms of the GNU General Public License as published by
15# the Free Software Foundation; either version 2 of the License, or
16# (at your option) any later version.
17#
18# This program is distributed in the hope that it will be useful,
19# but WITHOUT ANY WARRANTY; without even the implied warranty of
20# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21# GNU General Public License for more details.
22#
23# You should have received a copy of the GNU General Public License
24# along with this program; if not, write to the Free Software
25# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26#
27# ===================== INFORMATION ABOUT THIS PLUGIN =========================
28#
29#  This plugin returns uptime of the system returning data in text (readable)
30#  format as well as in minutes for performance graphing. The plugin can either
31#  run on local system unix system (that supports standard 'uptime' command
32#  or check remote system by SNMP. The plugin can report one CRITICAL or
33#  WARNING alert if system has been rebooted since last check.
34#
35# ======================  SETUP AND PLUGIN USE NOTES  =========================
36#
37#  The plugin can either retrieve information from local system (when you
38#  run it through check_nrpe for example) or by SNMP from remote system.
39#
40#  On local system it will execute standard unix 'uptime' and 'uname -a'.
41#
42#  On a remote system it'll retrieve data from sysSystem for system type
43#  and use that to decide if further data should be retrieved from
44#    sysUptime (OID 1.3.6.1.2.1.1.3.0) for windows or
45#    hostUptime (OID 1.3.6.1.2.1.25.1.1.0) for unix system or
46#    snmpEngineTime (OID 1.3.6.1.6.3.10.2.1.3) for cisco switches
47#
48#  For information on available options please execute it with --help i.e:
49#    check_uptime.pl --help
50#
51#  As I dont have time for extensive documentation below is all very brief:
52#
53#  1. You can also specify warning and critical thresholds which will
54#     give warning or critical alert if system has been up for lees then
55#     specified number of minutes. Example:
56#        check_uptime.pl -w 5
57#     Will give warning alert if system has been up for less then 5 minutes
58#
59#  2. For performance data results you can use '-f' option which will give
60#     total number of minutes the system has been up.
61#
62#  3. A special case is use of performance to feed data from previous run
63#     back into the plugin. This is used to cache results about what type
64#     of system it is (you can also directly specify this with -T option)
65#     and also means -w and -c threshold values are ignored and instead
66#     plugin will issue ONE alert (warning or critical) if system uptime
67#     changes from highier value to lower
68#
69# ============================ EXAMPLES =======================================
70#
71# 1. Local server (use with NRPE or on nagios host), warning on < 5 minutes:
72#
73# define command {
74#        command_name check_uptime
75#        command_line $USER1$/check_uptime.pl -f -w 5
76# }
77#
78# 2. Local server (use with NRPE or on nagios host),
79#    one critical alert on reboot:
80#
81# define command {
82#        command_name check_uptime
83#        command_line $USER1$/check_uptime.pl -f -c -P "SERVICEPERFDATA$"
84# }
85#
86# 3. Remote server SNMP v2, one warning alert on reboot,
87#    autodetect and cache type of server:
88#
89# define command {
90#        command_name check_snmp_uptime_v2
91#        command_line $USER1$/check_uptime.pl -2 -f -w -H $HOSTADDRESS$ -C $_HOSTSNMP_COMMUNITY$ -P "$SERVICEPERFDATA$"
92# }
93#
94# 4. Remote server SNMP v3, rest as above
95#
96#define command {
97#        command_name check_snmp_uptime_v3
98#        command_line $USER1$/check_uptime.pl -f -w -H $HOSTADDRESS$ -l $_HOSTSNMP_V3_USER$ -x $_HOSTSNMP_V3_AUTH$ -X $_HOSTSNMP_V3_PRIV$ -L sha,aes -P "$SERVICEPERFDATA$"
99# }
100#
101# 5. Example of service definition using above
102#
103# define service{
104#      use                              std-service
105#      hostgroup_name                   all_snmp_hosts
106#      service_description              SNMP Uptime
107#      max_check_attempts               1
108#      check_command                    check_snmp_uptime
109# }
110#
111# 6. And this is optional dependency definition for above which makes
112#    every SNMP service (service beloning to SNMP servicegroup) on
113#    same host dependent on this SNMP Uptime check. Then if SNMP
114#    daemon goes down you only receive one alert
115#
116# define servicedependency{
117#        service_description SNMP Uptime
118#        dependent_servicegroup_name snmp
119# }
120#
121# ============================= VERSION HISTORY ==============================
122#
123# 0.1 - sometime 2006 : Simple script for tracking local system uptime
124# 0.2 - sometime 2008 : Update to get uptime by SNMP, its now alike my other plugins
125# 0.3 -  Nov 14, 2009 : Added getting system info line and using that to decide
126#                       format of uptime line and how to process it. Added support
127#                       for getting uptime with SNMP from windows systems.
128#                       Added documentation header alike my other plugins.
129#                       Planned to release it to public, but forgot.
130# 0.4  - Dec 19, 2011 : Update to support SNMP v3, released to public
131# 0.41 - Jan 13, 2012 : Added bug fix by Rom_UA posted as comment on Nagios Exchange
132#                       Added version history you're reading right now.
133# 0.42 - Feb 13, 2012 : Bug fix to not report WARNING if uptime is not correct output
134# 0.5  - Feb 29, 2012 : Added support for "netswitch" engine type that retrieves
135#                       snmpEngineTime. Added proper support for sysUpTime interpreting
136#                       it as 1/100s of a second and converting to days,hours,minutes
137#                       Changed internal processing structure, now reported uptime
138#                       info text is based on uptime_minutes and not separate.
139# 0.51 - Jun 05, 2012 : Bug fixed for case when when snmp system info is < 3 words.
140# 0.52 - Jun 19, 2012 : For switches if snmpEngineTime OID is not available,
141#                       the plugin will revert back to checking hostUptime and
142#                       then sysUptime. Entire logic has in fact been changed
143#                       to support trying more than just two OIDs. Also added
144#                       support to specify filename to '-v' option for debug
145#                       output to go to instead of console and for '--debug'
146#                       option as an alias to '--verbose'.
147# 0.521 - Oct 4, 2012 : Small bug in one of regex, see issue #11 on github
148#
149# TODO:
150#   0) Add '--extra-opts' to allow to read options from a file as specified
151#      at http://nagiosplugins.org/extra-opts. This is TODO for all my plugins
152#   1) Add support for ">", "<" and other threshold qualifiers
153#      as done in check_snmp_temperature.pl or check_mysqld.pl
154#   2) Support for more types, in particular network equipment such as cisco: [DONE]
155#            sysUpTime is a 32-bit counter in 1/100 of a second, it rolls over after 496 days
156#            snmpEngineTime (.1.3.6.1.6.3.10.2.1.3) returns the uptime in seconds and will not
157#            roll over, however some cisco switches (29xx) are buggy and it gets reset too.
158#            Routers running 12.0(3)T or higher can use the snmpEngineTime object from
159#            the SNMP-FRAMEWORK-MIB.  This keeps track of seconds since SNMP engine started.
160#   3) Add threshold into perfout as ';warn;crit'
161#
162# ========================== START OF PROGRAM CODE ===========================
163
164use strict;
165use Getopt::Long;
166
167# Nagios specific
168our $TIMEOUT;
169our %ERRORS;
170eval 'use utils qw(%ERRORS $TIMEOUT)';
171if ($@) {
172 $TIMEOUT = 10;
173 %ERRORS = ('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4);
174}
175
176our $no_snmp=0;
177eval 'use Net::SNMP';
178if ($@) {
179  $no_snmp=1;
180}
181
182# Version
183my $Version='0.52';
184
185# SNMP OID
186my $oid_sysSystem = '1.3.6.1.2.1.1.1.0';             # windows and some unix
187my $oid_hostUptime = '1.3.6.1.2.1.25.1.1.0';         # hostUptime, usually unix systems
188my $oid_sysUptime = '1.3.6.1.2.1.1.3.0';             # sysUpTime, windows
189my $oid_engineTime = '1.3.6.1.6.3.10.2.1.3';         # SNMP-FRAMEWORK-MIB
190
191my @oid_uptime_types = ( ['', '', ''],                        # type 0 is reserved
192           [ 'local', '', ''],                                # type 1 is local
193           [ 'win', 'sysUpTime', $oid_sysUptime ],            # type 2 is windows
194           [ 'unix-host', 'hostUpTime', $oid_hostUptime ],    # type 3 is unix-host
195           [ 'unix-sys', 'sysUpTime', $oid_sysUptime ],       # type 4 is unix-sys
196           [ 'net', 'engineTime', $oid_engineTime ]);         # type 5 is netswitch
197
198# Not used, but perhaps later
199my $oid_hrLoad = '1.3.6.1.2.1.25.3.3.1.2.1';
200my $oid_sysLoadInt1 = '1.3.6.1.4.1.2021.10.1.5.1';
201my $oid_sysLoadInt5 = '1.3.6.1.4.1.2021.10.1.5.2';
202my $oid_sysLoadInt15 = '1.3.6.1.4.1.2021.10.1.5.3';
203
204# Standard options
205my $o_host =            undef;  # hostname
206my $o_timeout=          undef;  # Timeout (Default 10)
207my $o_help=             undef;  # wan't some help ?
208my $o_verb=             undef;  # verbose mode
209my $o_version=          undef;  # print version
210my $o_label=            undef;  # change label instead of printing uptime
211my $o_perf=             undef;  # Output performance data (uptime in minutes)
212my $o_prevperf=         undef;  # performance data given with $SERVICEPERFDATA$ macro
213my $o_warn=             undef;  # WARNING alert if system has been up for < specified number of minutes
214my $o_crit=             undef;  # CRITICAL alert if system has been up for < specified number of minutes
215my $o_type=             undef;  # type of check (local, auto, unix, win)
216
217# Login and other options specific to SNMP
218my $o_port =            161;    # SNMP port
219my $o_community =       undef;  # community
220my $o_version2  =       undef;  # use snmp v2c
221my $o_login=            undef;  # Login for snmpv3
222my $o_passwd=           undef;  # Pass for snmpv3
223my $v3protocols=        undef;  # V3 protocol list.
224my $o_authproto=        'md5';  # Auth protocol
225my $o_privproto=        'des';  # Priv protocol
226my $o_privpass=         undef;  # priv password
227
228## Additional global variables
229my %prev_perf=  ();     # array that is populated with previous performance data
230my $check_type = 0;
231
232sub p_version { print "check_uptime version : $Version\n"; }
233
234sub print_usage {
235    print "Usage: $0 [-v [debugfilename]] [-T local|unix-host|unix-sys|win|net] [-H <host> (-C <snmp_community>) [-2] | (-l login -x passwd [-X pass -L <authp>,<privp>) [-p <port>]] [-w <warn minutes> -s <crit minutes>] [-f] [-P <previous perf data from nagios \$SERVICEPERFDATA\$>] [-t <timeout>] | [-V] [--label <string>]\n";
236}
237
238sub isnnum { # Return true if arg is not a number
239  my $num = shift;
240  if ( $num =~ /^(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;}
241  return 1;
242}
243
244sub div_mod { return int( $_[0]/$_[1]) , ($_[0] % $_[1]); }
245
246sub help {
247   print "\nUptime Plugin for Nagios (check_uptime) v. ",$Version,"\n";
248   print "GPL licence, (c) 2008-2012 William Leibzon\n\n";
249   print_usage();
250   print <<EOT;
251
252Debug & Console Options:
253 -v, --verbose[=FILENAME], --debug[=FILENAME]
254   print extra debugging information.
255   if filename is specified instead of STDOUT the debug data is written to that file
256 -h, --help
257   print this help message
258 -V, --version
259   prints version number
260
261Standard Options:
262 -T, --type=auto|local|unix-host|unis-sys|windows|netswitch
263   Type of system:
264     local           : localhost (executes 'uptime' command), default if no -C or -l
265     unix-host       : SNMP check from hostUptime ($oid_hostUptime) OID
266     unix-sys        : SNMP check from sysUptime ($oid_sysUptime) OID
267     win | windows   : SNMP check from sysUptime ($oid_sysUptime) OID
268     net | netswitch : SNMP check from snmpEngineTime ($oid_engineTime) OID
269     auto            : Autodetect what system by checking sysSystem OID first, default
270 -w, --warning[=minutes]
271   Report nagios WARNING alert if system has been up for less then specified
272   number of minutes. If no minutes are specified but previous preformance
273   data is fed back with -P option then alert is sent ONLY ONCE when
274   uptime changes from greater value to smaller
275 -c, --critical[=minutes]
276   Report nagios CRITICAL alert if system has been up for less then
277   specified number of minutes or ONE ALERT if -P option is used and
278   system's previous uptime is larger then current on
279 -f, --perfparse
280   Perfparse compatible output
281 -P, --prev_perfdata
282   Previous performance data (normally put '-P \$SERVICEPERFDATA\$' in
283   nagios command definition). This is recommended if you dont specify
284   type of system with -T so that previously checked type of system info
285   is reused. This is also used to decide on warning/critical condition
286   if number of seconds is not specified with -w or -c.
287 --label=[string]
288   Optional custom label before results prefixed to results
289 -t, --timeout=INTEGER
290   timeout for SNMP in seconds (Default: 15)
291
292SNMP Access Options:
293 -H, --hostname=HOST
294   name or IP address of host to check (if not localhost)
295 -C, --community=COMMUNITY NAME
296   community name for the SNMP agent (used with v1 or v2c protocols)
297 -2, --v2c
298   use snmp v2c (can not be used with -l, -x)
299 -l, --login=LOGIN ; -x, --passwd=PASSWD
300   Login and auth password for snmpv3 authentication
301   If no priv password exists, implies AuthNoPriv
302 -X, --privpass=PASSWD
303   Priv password for snmpv3 (AuthPriv protocol)
304 -L, --protocols=<authproto>,<privproto>
305   <authproto> : Authentication protocol (md5|sha : default md5)
306   <privproto> : Priv protocols (des|aes : default des)
307 -p, --port=PORT
308   SNMP port (Default 161)
309EOT
310}
311
312# For verbose output (updated 06/06/12 to write to debug file if specified)
313sub verb {
314    my $t=shift;
315    if (defined($o_verb)) {
316        if ($o_verb eq "") {
317                print $t,"\n";
318        }
319        else {
320            if (!open(DEBUGFILE, ">>$o_verb")) {
321                print $t, "\n";
322            }
323            else {
324                print DEBUGFILE $t,"\n";
325                close DEBUGFILE;
326            }
327        }
328    }
329}
330
331# load previous performance data
332sub process_perf {
333 my %pdh;
334 my ($nm,$dt);
335 foreach (split(' ',$_[0])) {
336   if (/(.*)=(.*)/) {
337        ($nm,$dt)=($1,$2);
338        verb("prev_perf: $nm = $dt");
339        # in some of my plugins time_ is to profile how long execution takes for some part of plugin
340        # $pdh{$nm}=$dt if $nm !~ /^time_/;
341        $pdh{$nm}=$dt;
342   }
343 }
344 return %pdh;
345}
346
347sub type_from_name {
348  my $type=shift;
349  for(my $i=1; $i<scalar(@oid_uptime_types); $i++) {
350      if ($oid_uptime_types[$i][0] eq $type) {
351          return $i;
352      }
353   }
354   return -1;
355}
356
357
358sub check_options {
359    Getopt::Long::Configure ("bundling");
360        GetOptions(
361        'v:s'   => \$o_verb,            'verbose:s'     => \$o_verb,  "debug:s" => \$o_verb,
362        'h'     => \$o_help,            'help'          => \$o_help,
363        'H:s'   => \$o_host,            'hostname:s'    => \$o_host,
364        'p:i'   => \$o_port,            'port:i'        => \$o_port,
365        'C:s'   => \$o_community,       'community:s'   => \$o_community,
366         '2'    => \$o_version2,        'v2c'           => \$o_version2,
367        'l:s'   => \$o_login,           'login:s'       => \$o_login,
368        'x:s'   => \$o_passwd,          'passwd:s'      => \$o_passwd,
369        'X:s'   => \$o_privpass,        'privpass:s'    => \$o_privpass,
370        'L:s'   => \$v3protocols,       'protocols:s'   => \$v3protocols,
371        't:i'   => \$o_timeout,         'timeout:i'     => \$o_timeout,
372        'V'     => \$o_version,         'version'       => \$o_version,
373        'f'     => \$o_perf,            'perfparse'     => \$o_perf,
374        'w:i'   => \$o_warn,            'warning:i'     => \$o_warn,
375        'c:i'   => \$o_crit,            'critical:i'    => \$o_crit,
376        'label:s'   => \$o_label,
377        'P:s'   => \$o_prevperf,        'prev_perfdata:s' => \$o_prevperf,
378        'T:s'   => \$o_type,            'type:s'        => \$o_type,
379    );
380    if (defined ($o_help) ) { help(); exit $ERRORS{"UNKNOWN"}};
381    if (defined($o_version)) { p_version(); exit $ERRORS{"UNKNOWN"}};
382
383    $o_type = "win" if defined($o_type) && $o_type eq 'windows';
384    $o_type = "net" if defined($o_type) && $o_type eq 'netswitch';
385    if (defined($o_type) && $o_type ne 'auto' && type_from_name($o_type)==-1) {
386        print "Invalid system type specified\n"; print_usage(); exit $ERRORS{"UNNKNOWN"};
387    }
388
389    if (!defined($o_community) && (!defined($o_login) || !defined($o_passwd)) ) {
390         $o_type='local' if !defined($o_type) || $o_type eq 'auto';
391         if ($o_type ne 'local') {
392            print "Put snmp login info!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}
393         }
394         if (defined($o_host)) {
395            print "Why are you specifying hostname without SNMP parameters?\n"; print_usage(); exit $ERRORS{"UNKNOWN"};
396         }
397    }
398    else {
399         $o_type='auto' if !defined($o_type);
400         if ($o_type eq 'local' ) {
401             print "Why are you specifying SNMP login for local system???\n"; print_usage(); exit $ERRORS{"UNKNOWN"}
402         }
403         if (!defined($o_host)) {
404             print "Hostname required for SNMP check.\n"; print_usage(); exit $ERRORS{"UNKNOWN"};
405         }
406         if ($no_snmp) {
407             print "Can't locate Net/SNMP.pm\n"; print_usage(); exit $ERRORS{"UNKNOWN"};
408         }
409    }
410
411    # check snmp information
412    if ((defined($o_login) || defined($o_passwd)) && (defined($o_community) || defined($o_version2)) )
413        { print "Can't mix snmp v1,2c,3 protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}}
414    if (defined ($v3protocols)) {
415        if (!defined($o_login)) { print "Put snmp V3 login info with protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}}
416        my @v3proto=split(/,/,$v3protocols);
417        if ((defined ($v3proto[0])) && ($v3proto[0] ne "")) {$o_authproto=$v3proto[0];  }       # Auth protocol
418        if (defined ($v3proto[1])) {$o_privproto=$v3proto[1];   }       # Priv  protocol
419        if ((defined ($v3proto[1])) && (!defined($o_privpass)))
420          { print "Put snmp V3 priv login info with priv protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}}
421    }
422
423    if (defined($o_timeout) && (isnnum($o_timeout) || ($o_timeout < 2) || ($o_timeout > 60)))
424        { print "Timeout must be >1 and <60 !\n"; print_usage(); exit $ERRORS{"UNKNOWN"}}
425    if (!defined($o_timeout)) {$o_timeout=$TIMEOUT+5;}
426
427    if (defined($o_prevperf)) {
428        if (defined($o_perf)) {
429               %prev_perf=process_perf($o_prevperf);
430               $check_type = $prev_perf{type} if $o_type eq 'auto' && exists($prev_perf{tye}) && exists($oid_uptime_types[$prev_perf{type}][0]);
431        }
432        else {
433               print "need -f option first \n"; print_usage(); exit $ERRORS{"UNKNOWN"};
434        }
435    }
436
437    if ($o_type eq 'auto') {
438        $check_type=0;
439    }
440    else {
441        $check_type = type_from_name($o_type);
442    }
443}
444
445sub create_snmp_session {
446  my ($session,$error);
447
448  if ( defined($o_login) && defined($o_passwd)) {
449    # SNMPv3 login
450    if (!defined ($o_privpass)) {
451     verb("SNMPv3 AuthNoPriv login : $o_login, $o_authproto");
452     ($session, $error) = Net::SNMP->session(
453      -hostname         => $o_host,
454      -version          => '3',
455      -port             => $o_port,
456      -username         => $o_login,
457      -authpassword     => $o_passwd,
458      -authprotocol     => $o_authproto,
459      -timeout          => $o_timeout
460     );
461    } else {
462     verb("SNMPv3 AuthPriv login : $o_login, $o_authproto, $o_privproto");
463     ($session, $error) = Net::SNMP->session(
464      -hostname         => $o_host,
465      -version          => '3',
466      -username         => $o_login,
467      -port             => $o_port,
468      -authpassword     => $o_passwd,
469      -authprotocol     => $o_authproto,
470      -privpassword     => $o_privpass,
471      -privprotocol     => $o_privproto,
472      -timeout          => $o_timeout
473     );
474    }
475  } else {
476    if (defined ($o_version2)) {
477    # SNMPv2c Login
478      verb("SNMP v2c login");
479      ($session, $error) = Net::SNMP->session(
480       -hostname  => $o_host,
481       -version   => 2,
482       -community => $o_community,
483       -port      => $o_port,
484       -timeout   => $o_timeout
485      );
486    } else {
487    # SNMPV1 login
488      verb("SNMP v1 login");
489      ($session, $error) = Net::SNMP->session(
490       -hostname  => $o_host,
491       -community => $o_community,
492       -port      => $o_port,
493       -timeout   => $o_timeout
494      );
495    }
496  }
497  if (!defined($session)) {
498     printf("ERROR opening session: %s.\n", $error);
499     exit $ERRORS{"UNKNOWN"};
500  }
501
502  return $session;
503}
504
505$SIG{'ALRM'} = sub {
506 print "Alarm timeout\n";
507 exit $ERRORS{"UNKNOWN"};
508};
509
510########## MAIN #######
511my $system_info="";
512my $uptime_info=undef;
513my $uptime_minutes=undef;
514my $perf_out="";
515my $status=0;
516my $uptime_output;
517my ($days, $hrs, $mins);
518
519check_options();
520
521# Check gobal timeout if snmp screws up
522if (defined($o_timeout)) {
523  verb("Alarm at $o_timeout + 5");
524  alarm($o_timeout+5);
525}
526
527if ($check_type==1) {  # local
528  # Process unix uptime command output
529  $uptime_output=`uptime`;
530  verb("Local Uptime Result is: $uptime_output");
531  if ($uptime_output =~ /(\d+)\s+days?,\s+(\d+)\:(\d+)/) {
532     ($days, $hrs, $mins) = ($1, $2, $3);
533  }
534  elsif ($uptime_output =~ /up\s+(\d+)\shours?\s+(\d+)/) {
535     ($days, $hrs, $mins) = (0, $1, $2);
536  }
537  elsif ($uptime_output =~ /up\s+(\d+)\:(\d+)/) {
538     ($days, $hrs, $mins) = (0, $1, $2);
539  }
540  elsif ($uptime_output =~ /up\s+(\d+)\s+min/) {
541     ($days, $hrs, $mins) = (0,0,$1);
542  }
543  elsif ($uptime_output =~ /up\s+(\d+)s+days?,s+(\d+)s+min/) {
544     ($days, $hrs, $mins) = ($1,0,$2);
545  }
546  else {
547     $uptime_info = "up ".$uptime_output;
548  }
549  if (defined($days) && defined($hrs) && defined($mins)) {
550     $uptime_minutes = $days*24*60+$hrs*60+$mins;
551  }
552  my @temp=split(' ',`uname -a`);
553  if (scalar(@temp)<3) {
554        $system_info=`uname -a`;
555  }
556  else {
557        $system_info=join(' ',$temp[0],$temp[1],$temp[2]);
558  }
559}
560else {
561  # SNMP connection
562  my $session=create_snmp_session();
563  my $result=undef;
564  my $oid="";
565  my $guessed_check_type=0;
566
567  if ($check_type==0){
568      $result = $session->get_request(-varbindlist=>[$oid_sysSystem]);
569      if (!defined($result)) {
570            printf("ERROR: Can not retrieve $oid_sysSystem table: %s.\n", $session->error);
571            $session->close;
572            exit $ERRORS{"UNKNOWN"};
573      }
574      verb("$o_host SysInfo Result from OID $oid_sysSystem: $result->{$oid_sysSystem}");
575      if ($result->{$oid_sysSystem} =~ /Windows/) {
576          $guessed_check_type=2;
577          verb('Guessing Type: 2 = windows');
578      }
579      if ($result->{$oid_sysSystem} =~ /Cisco/) {
580          $guessed_check_type=5;
581          verb('Guessing Type: 5 = netswitch');
582      }
583      if ($guessed_check_type==0) {
584          $guessed_check_type=3; # will try hostUptime first
585      }
586      $oid=$oid_uptime_types[$guessed_check_type][2];
587  }
588  else {
589      $oid=$oid_uptime_types[$check_type][2];
590  }
591
592  do {
593      $result = $session->get_request(-varbindlist=>[$oid,$oid_sysSystem]);
594      if (!defined($result)) {
595          if ($check_type!=0) {
596              printf("ERROR: Can not retrieve uptime OID table $oid: %s.\n", $session->error);
597              $session->close;
598              exit $ERRORS{"UNKNOWN"};
599          }
600          else {
601              if ($session->error =~ /noSuchName/) {
602                  if ($guessed_check_type==4) {
603                      verb("Received noSuchName error for sysUpTime OID $oid. Giving up.");
604                      $guessed_check_type=0;
605                  }
606                  if ($guessed_check_type==3) {
607                      verb("Received noSuchName error for hostUpTime OID $oid, will now try sysUpTime");
608                      $guessed_check_type=4;
609                  }
610                  else {
611                      verb("Received noSuchName error for OID $oid, will now try hostUpTime");
612                      $guessed_check_type=3;
613                  }
614                  if ($guessed_check_type!=0) {
615                      $oid=$oid_uptime_types[$guessed_check_type][2];
616                  }
617              }
618              else {
619                  printf("ERROR: Can not retrieve uptime OID table $oid: %s.\n", $session->error);
620                  $session->close;
621                  exit $ERRORS{"UNKNOWN"};
622              }
623          }
624      }
625      else {
626          if ($check_type==0) {
627              $check_type=$guessed_check_type;
628          }
629      }
630  }
631  while (!defined($result) && $guessed_check_type!=0);
632
633  $session->close;
634  if ($check_type==0 && $guessed_check_type==0) {
635        printf("ERROR: Can not autodetermine proper uptime OID table. Giving up.\n");
636        exit $ERRORS{"UNKNOWN"};
637  }
638
639  my ($days, $hrs, $mins);
640  $uptime_output=$result->{$oid};
641  verb("$o_host Uptime Result from OID $oid: $uptime_output");
642
643  if ($uptime_output =~ /(\d+)\s+days?,\s+(\d+)\:(\d+)/) {
644    ($days, $hrs, $mins) = ($1, $2, $3);
645  }
646  elsif ($uptime_output =~ /(\d+)\s+hours?,\s+(\d+)\:(\d+)/) {
647    ($days, $hrs, $mins) = (0, $1, $2);
648  }
649  elsif ($uptime_output =~ /(\d+)\s+min/) {
650    ($days, $hrs, $mins) = (0, 0, $1);
651  }
652  if (defined($days) && defined($hrs) && defined($mins)) {
653    $uptime_minutes = $days*24*60+$hrs*60+$mins;
654  }
655  elsif ($uptime_output =~ /^(\d+)$/) {
656    my $upnum = $1;
657    if ($oid eq $oid_sysUptime) {
658        $uptime_minutes = $upnum/100/60;
659    }
660    elsif ($oid eq $oid_engineTime) {
661        $uptime_minutes = $upnum/60;
662    }
663  }
664  else {
665    $uptime_info = "up ".$uptime_output;
666  }
667  my @temp=split(' ',$result->{$oid_sysSystem});
668  if (scalar(@temp)<3) {
669        $system_info=$result->{$oid_sysSystem};
670  }
671  else {
672        $system_info=join(' ',$temp[0],$temp[1],$temp[2]);
673  }
674}
675
676if (defined($uptime_minutes) && !defined($uptime_info)) {
677  ($hrs,$mins) = div_mod($uptime_minutes,60);
678  ($days,$hrs) = div_mod($hrs,24);
679  $uptime_info = "up ";
680  $uptime_info .= "$days days " if $days>0;
681  $uptime_info .= "$hrs hours " if $hrs>0;
682  $uptime_info .= "$mins minutes";
683}
684
685verb("System Type: $check_type (".$oid_uptime_types[$check_type][0].")");
686verb("System Info: $system_info") if $system_info;
687verb("Uptime Text: $uptime_info") if defined($uptime_info);
688verb("Uptime Minutes: $uptime_minutes") if defined($uptime_minutes);
689
690if (!defined($uptime_info)) {
691  $uptime_info = "Can not determine uptime";
692  $status = 3;
693}
694
695if (defined($o_perf)) {
696  $perf_out = "type=$check_type";
697  $perf_out .= " uptime_minutes=$uptime_minutes" if defined($uptime_minutes);
698}
699
700if (defined($uptime_minutes)) {
701  if (defined($o_prevperf)) {
702        $status = 1 if defined($o_warn) && exists($prev_perf{uptime_minutes}) && $prev_perf{uptime_minutes} > $uptime_minutes;
703        $status = 2 if defined($o_crit) && exists($prev_perf{uptime_minutes}) && $prev_perf{uptime_minutes} > $uptime_minutes;
704  }
705  else {
706        $status = 1 if defined($o_warn) && !isnnum($o_warn) && $o_warn >= $uptime_minutes;
707        $status = 2 if defined($o_crit) && !isnnum($o_crit) && $o_crit >= $uptime_minutes;
708  }
709}
710alarm(0);
711
712my $exit_status="UNKNOWN";
713$exit_status="OK" if $status==0;
714$exit_status="WARNING" if $status==1;
715$exit_status="CRITICAL" if $status==2;
716$exit_status="UNKNOWN" if $status==3;
717$exit_status="$o_label $exit_status" if defined($o_label);
718print "$exit_status: $system_info";
719print " - $uptime_info";
720print " | ",$perf_out if $perf_out;
721print "\n";
722exit $status;
Note: See TracBrowser for help on using the repository browser.