[BACK]Return to check_hw_sensors CVS log [TXT][DIR] Up to [local] / nagios / check_hw_sensors

Diff for /nagios/check_hw_sensors/check_hw_sensors between version 1.12 and 1.18

version 1.12, 2006/05/03 22:54:43 version 1.18, 2006/12/02 02:15:17
Line 1 
Line 1 
 #!/usr/bin/perl  #!/usr/bin/perl -T
 # $RedRiver: check_hw_sensors,v 1.11 2006/05/03 20:01:09 holligan Exp $  # $RedRiver: check_hw_sensors,v 1.17 2006/10/25 23:30:23 andrew Exp $
 ########################################################################  ########################################################################
 # check_hw_sensors *** A nagios check for OpenBSD hw.sensors  # check_hw_sensors *** A nagios check for OpenBSD hw.sensors
 #  #
Line 7 
Line 7 
 ########################################################################  ########################################################################
 # TODO:  # TODO:
 #   Really need real documentation.  #   Really need real documentation.
 #  
 #   I want the ability to just check the "status" entry that is in  
 #   some output.  For example the OK here:  
 #     hw.sensors.1=esm0, CPU 1, OK, temp, 31.00 degC / 87.80 degF  
 ########################################################################  ########################################################################
 use strict;  use strict;
 use warnings;  use warnings;
   
 #use Data::Dumper;  %ENV = ();
   
 use constant NAGIOS_OUTPUT => 1;  use constant NAGIOS_OUTPUT => 1;
   
Line 36 
Line 32 
 my $state = 'UNKNOWN'; # tells whether the it is warning, critical, or OK  my $state = 'UNKNOWN'; # tells whether the it is warning, critical, or OK
 my %states; # This stores the count of states;  my %states; # This stores the count of states;
 my $filename;  my $filename;
   my $ignore_status;
 my $sensor;  my $sensor;
 my $warning;  my $warning;
 my $critical;  my $critical;
Line 48 
Line 45 
   
 #Option checking  #Option checking
 my $status = GetOptions(  my $status = GetOptions(
         "version|V"    => \$opt_V,          "version|V"       => \$opt_V,
         "help|h"       => \$opt_h,          "filename|f:s"    => \$filename,
         "filename|f:s" => \$filename,          "ignore-status|i" => \$ignore_status,
         "sensor|s=s"   => \$sensor,          "sensor|s=s"      => \$sensor,
         "warning|w=s"  => \$warning,          "warning|w=s"     => \$warning,
         "critical|c=s" => \$critical,          "critical|c=s"    => \$critical,
 );  );
   
 # set the default this way so it only happens if someone typed -f or --filename  # set the default this way so it only happens if someone typed -f or --filename
 $filename = $DEFAULT_CONFIG if (defined $filename && $filename eq '');  $filename = $DEFAULT_CONFIG if (defined $filename && $filename eq '');
   
   # Stuff is output in this file by print_sensor()
   # http://www.openbsd.org/cgi-bin/cvsweb/src/sbin/sysctl/sysctl.c
   my @Type_Map = (
           {
                   type  => 'temp',
                   regex => qr/\sdegC$/,
           },
           {
                   type  => 'fanrpm',
                   regex => qr/\sRPM$/,
           },
           {
                   type  => 'volts_dc',
                   regex => qr/\sV\sDC$/,
           },
           {
                   type  => 'amps',
                   regex => qr/\sA$/,
           },
           {
                   type  => 'watthour',
                   regex => qr/\sWh$/,
           },
           {
                   type  => 'amphour',
                   regex => qr/\sAh$/,
           },
           {
                   type  => 'indicator',
                   regex => qr/^(On|Off)$/,
           },
           {
                   type  => 'integer',
                   regex => qr/\sraw$/,
           },
           {
                   type  => 'lux',
                   regex => qr/\slx$/,
           },
           {
                   type  => 'drive',
                   regex => qr/^drive\s/,
           },
           {
                   type  => 'timedelta',
                   regex => qr/\ssecs$/,
           },
   );
   
 if ($status == 0) {  if ($status == 0) {
         print_help() ;          print_help() ;
         exit $ERRORS{'OK'};          exit $ERRORS{'OK'};
Line 69 
Line 115 
         exit $ERRORS{'OK'};          exit $ERRORS{'OK'};
 }  }
   
 if ($opt_h) {  unless (
         print_help();          (
         exit $ERRORS{'OK'};  
 }  
   
 unless ( (  
                 defined $filename ||                  defined $filename ||
                   (not defined $ignore_status) ||
                 (defined $sensor && ($warning || $critical))                  (defined $sensor && ($warning || $critical))
          ) &&           ) &&
          ( (!defined $filename) || (!defined $sensor) )           ( (!defined $filename) || (!defined $sensor) )
Line 91 
Line 134 
         }          }
         $CHECK_SENSOR = $sensor;          $CHECK_SENSOR = $sensor;
   
         $CHECKS{$sensor} = {          $CHECKS{$sensor}{'warn'} = $warning  if defined $warning;
                 'warn' => $warning,          $CHECKS{$sensor}{'crit'} = $critical if defined $critical;
                 'crit' => $critical,  
         };  
 } elsif (defined $filename) {  } elsif (defined $filename) {
         %CHECKS = parse_file($filename);          %CHECKS = parse_file($filename);
 }  }
Line 107 
Line 149 
         my ($id, $output) = split /=/;          my ($id, $output) = split /=/;
         my @o = split /,\s*/, $output;          my @o = split /,\s*/, $output;
   
         my $source = $o[0];          my ($type, $source, $descr, $data, $status);
         my $descr  = $o[1];  
         my $status = $o[2] if @o == 5;  
         my $type   = $o[-2];  
         my $data   = $o[-1];  
   
           $source = $o[0];
           $descr  = $o[1];
           $type   = $o[-2] if @o >= 4;
           $data   = $o[-1];
   
           $status = $o[2] if ($type && @o == 5) || @o == 4;
   
           unless ($type) {
                   foreach my $t (@Type_Map) {
                           if ($data =~ /$t->{'regex'}/) {
                                   $type = $t->{'type'};
                                   last;
                           }
                   }
           }
   
           $type ||= 'unknown';
   
         $SENSORS{$id} = {          $SENSORS{$id} = {
                 id          => $id,                  id          => $id,
                 output      => $output,                  output      => $output,
Line 134 
Line 190 
         $_a <=> $_b;          $_a <=> $_b;
 }  }
   
 foreach my $check (sort as_if_numeric keys %CHECKS) {  foreach my $s (sort as_if_numeric keys %SENSORS) {
         if (exists $SENSORS{$check}) {          my ($r, $data);
                 my $r = check_sensor($CHECKS{$check}, $SENSORS{$check});          if (exists $CHECKS{$s}) {
                 push @{ $states{ $r } },                  $r    = check_sensor($SENSORS{$s}, $CHECKS{$s});
                         $check . '=' . $SENSORS{$check}{'output'};                  $data = $s . '=' . $SENSORS{$s}{'output'};
           } elsif (not $ignore_status) {
                   $r = check_sensor($SENSORS{$s});
                   $data = $s . '=' . $SENSORS{$s}{'output'};
         } else {          } else {
                 push @{ $states{'UNKNOWN'} }, $check . '=No sensor with this id';                  # ignore this sensor
         }          }
           next unless defined $r;
           push @{ $states{ $r } }, $data;
 }  }
   
 #print Dumper \%states;  
   
 $state = 'OK';  $state = 'OK';
 my $have_results = 0;  my $have_results = 0;
 foreach my $error (sort { $ERRORS{$a} <=> $ERRORS{$b} } keys %ERRORS) {  foreach my $error (sort { $ERRORS{$a} <=> $ERRORS{$b} } keys %ERRORS) {
Line 160 
Line 219 
                         print "$error (" . scalar(@{ $states{ $error } }) . ")";                          print "$error (" . scalar(@{ $states{ $error } }) . ")";
                         unless ($error eq 'OK') {                          unless ($error eq 'OK') {
                                 print '<br>';                                  print '<br>';
                                 print map { " - $_<br>" } @{ $states{ $error } };                                  print map {" - $_<br>"} @{ $states{ $error } };
                         }                          }
                 } else {                  } else {
                         print "$error (" . scalar(@{ $states{ $error } }) . "):\n";                          print "$error (" . scalar(@{ $states{ $error } }) . "):\n";
Line 179 
Line 238 
 sub parse_file {  sub parse_file {
         my $filename = shift;          my $filename = shift;
         my %contents;          my %contents;
   
           die "file '$filename' does not exist." unless -e $filename;
   
         open my $fh, '-|', $GETCAP, '-a', '-f', $filename          open my $fh, '-|', $GETCAP, '-a', '-f', $filename
                 or die "Couldn't open FILE '$GETCAP -a -f $filename': $!";                  or die "Couldn't open FILE '$GETCAP -a -f $filename': $!";
         while (<$fh>) {          LINE: while (<$fh>) {
                 chomp;                  chomp;
                 my ($key, @c) = split /\:/;                  my ($key, @c) = split /\:/;
                 foreach (@c) {                  foreach (@c) {
                         my ($k, $v) = split /\=/;                          my ($k, $v) = split /\=/;
                         $contents{$key}{$k} = $v;                          if (lc($k) eq 'ignore') {
                                   $contents{$key}{'IGNORE'} = 1;
                           } elsif (lc($k) eq 'status') {
                                   $contents{$key}{'STATUS'} = 1;
                           } else {
                                   $contents{$key}{$k} = $v;
                           }
                 }                  }
         }          }
         close $fh;          close $fh;
Line 199 
Line 266 
         my $type  = shift;          my $type  = shift;
         my $check = shift;          my $check = shift;
   
           return undef unless $check;
           return undef    if $check->{'STATUS'};
           return 'IGNORE' if $check->{'IGNORE'};
   
         foreach my $code ('crit', 'warn') {          foreach my $code ('crit', 'warn') {
                 if (defined $check->{$code} && $check->{$code} =~ /:/) {                  if (defined $check->{$code} && $check->{$code} =~ /:/) {
                         if (my ($low, $high) = split /:/, $check->{$code}) {                          if (my ($low, $high) = split /:/, $check->{$code}) {
Line 222 
Line 293 
 }  }
   
 sub check_sensor {  sub check_sensor {
         my $check  = shift;  
         my $sensor = shift;          my $sensor = shift;
           my $check  = shift;
         my $result = 'UNKNOWN';          my $result = 'UNKNOWN';
         my %errors = (          my %errors = (
                 'warn' => 'WARNING',                  'warn' => 'WARNING',
Line 231 
Line 302 
         );          );
   
         return $result unless ref $sensor eq 'HASH';          return $result unless ref $sensor eq 'HASH';
           $check = parse_check($sensor->{'type'}, $check) if $check;
   
         $check = parse_check($sensor->{'type'}, $check);          unless ($check) {
         #print Dumper $check, $sensor;                  if ($sensor->{'status'}) {
                           # It looks like doing this should be safe, from
                           # src/sbin/sysctl/sysctl.c
                           $result = $sensor->{'status'}
                   } else {
                           return undef;
                   }
                   return $result;
           }
   
         $result = 'OK';          return undef if $check eq 'IGNORE';
   
           $result = 'OK';
         foreach my $code ('warn', 'crit') {          foreach my $code ('warn', 'crit') {
                 if (                  if (
                         $sensor->{'type'} eq 'volts_dc' ||                          $sensor->{'type'} eq 'volts_dc' ||
Line 289 
Line 370 
                                                 next;                                                  next;
                                         }                                          }
   
                                         if ($_ eq $data) {                                          if ($c eq $data) {
                                                 $matched = 1;                                                  $matched = 1;
                                                 last;                                                  last;
                                         }                                          }
Line 300 
Line 381 
                 } elsif ($sensor->{'type'} eq 'temp') {                  } elsif ($sensor->{'type'} eq 'temp') {
                         my ($degC, $degF) = split /\//, $sensor->{'data'};                          my ($degC, $degF) = split /\//, $sensor->{'data'};
                         $degC =~ s/[^\d\.]//g;                          $degC =~ s/[^\d\.]//g;
                           $degF ||= $degC * 9 / 5 + 32;
                         $degF =~ s/[^\d\.]//g;                          $degF =~ s/[^\d\.]//g;
                         if (                          if (
                                 defined $check->{$code . ".low"} ||                                  defined $check->{$code . ".low"} ||
Line 367 
Line 449 
                                                 next;                                                  next;
                                         }                                          }
   
                                         if ($_ eq $data) {                                          if ($c eq $data) {
                                                 $matched = 1;                                                  $matched = 1;
                                                 last;                                                  last;
                                         }                                          }
Line 379 
Line 461 
                         $sensor->{'type'} eq 'drive' ||                          $sensor->{'type'} eq 'drive' ||
                         $sensor->{'type'} eq 'indicator'                          $sensor->{'type'} eq 'indicator'
                 ) {                  ) {
                           $sensor->{'type'} =~ s/^drive\s+//;
                         if (@{ $check->{$code} }) {                          if (@{ $check->{$code} }) {
                                 my $matched = 0;                                  my $matched = 0;
                                 foreach (@{ $check->{$code} }) {                                  foreach (@{ $check->{$code} }) {
Line 402 
Line 485 
 sub print_help {  sub print_help {
         print <<EOL;          print <<EOL;
 $PROGNAME plugin for Nagios monitors sysctl hw.sensors on OpenBSD  $PROGNAME plugin for Nagios monitors sysctl hw.sensors on OpenBSD
     $PROGNAME (-f [<FILENAME>]|(-s <hw.sensors id> -w limit -c limit))      $PROGNAME [-i] (-f [<FILENAME>]|(-s <hw.sensors id> [-w limit] [-c limit]))
   
 Usage:  Usage:
       -i, --ignore-status
           Don't check the status of sensors that report it.
     -f, --filename=FILE      -f, --filename=FILE
         FILE to load checks from (defaults to /etc/sensorsd.conf)          FILE to load checks from (defaults to /etc/sensorsd.conf)
     -s, --sensor=ID      -s, --sensor=ID
         ID of a single sensor.  "-s 0" means hw.sensors.0.          ID of a single sensor.  "-s 0" means hw.sensors.0.
     -w, --warning=RANGE or single ENTRY      -w, --warning=RANGE or single ENTRY
         Exit with WARNING status if outside of RANGE or if != ENTRY          Exit with WARNING status if outside of RANGE or if != ENTRY
     -c, --critical=INTEGER      -c, --critical=RANGE or single ENTRY
         Exit with CRITICAL status if outside of RANGE or if != ENTRY          Exit with CRITICAL status if outside of RANGE or if != ENTRY
   
     -h (--help)       usage help  FILE is in the same format as sensorsd.conf(5) plus some additional
   entries.  These additional entries in the file are ignored by
   sensorsd(8).
   
 FILE is in the same format as sensorsd.conf(5).  These additional  
 entries in the file are ignored by sensorsd(8).  
   
 $PROGNAME understands the following entries:  $PROGNAME understands the following entries:
   
     low, high, crit, warn, crit.low, crit.high, warn.low, warn.high      low, high, crit, warn, crit.low, crit.high, warn.low, warn.high,
       ignore, status
   
 An ENTRY depends on the type.  The descriptions in sensorsd.conf(5)  An ENTRY depends on the type.  The descriptions in sensorsd.conf(5)
 can be used when appropriate, or you can use the following:  can be used when appropriate, or you can use the following:
Line 448 
Line 533 
 It can also be low: or :high with the other side left blank to only  It can also be low: or :high with the other side left blank to only
 make the single check..  make the single check..
   
   An entry marked "ignore" will cause that sensor to be skipped.
   Generally used with state checking of all sensors to ignore sensors you
   don't care about or that report incorrectly.
   
   If you are using --ignore-status, you can still check the status of
   individual sensors with a status entry.
   
 EOL  EOL
   
         print_revision($PROGNAME, '$Revision$');          print_revision($PROGNAME, '$Revision$');
 }  }
   

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.18

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>