===================================================================
RCS file: /cvs/nagios/check_hw_sensors/check_hw_sensors,v
retrieving revision 1.12
retrieving revision 1.18
diff -u -r1.12 -r1.18
--- nagios/check_hw_sensors/check_hw_sensors 2006/05/03 22:54:43 1.12
+++ nagios/check_hw_sensors/check_hw_sensors 2006/12/02 02:15:17 1.18
@@ -1,5 +1,5 @@
-#!/usr/bin/perl
-# $RedRiver: check_hw_sensors,v 1.11 2006/05/03 20:01:09 holligan Exp $
+#!/usr/bin/perl -T
+# $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
#
@@ -7,15 +7,11 @@
########################################################################
# TODO:
# 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 warnings;
-#use Data::Dumper;
+%ENV = ();
use constant NAGIOS_OUTPUT => 1;
@@ -36,6 +32,7 @@
my $state = 'UNKNOWN'; # tells whether the it is warning, critical, or OK
my %states; # This stores the count of states;
my $filename;
+my $ignore_status;
my $sensor;
my $warning;
my $critical;
@@ -48,34 +45,80 @@
#Option checking
my $status = GetOptions(
- "version|V" => \$opt_V,
- "help|h" => \$opt_h,
- "filename|f:s" => \$filename,
- "sensor|s=s" => \$sensor,
- "warning|w=s" => \$warning,
- "critical|c=s" => \$critical,
+ "version|V" => \$opt_V,
+ "filename|f:s" => \$filename,
+ "ignore-status|i" => \$ignore_status,
+ "sensor|s=s" => \$sensor,
+ "warning|w=s" => \$warning,
+ "critical|c=s" => \$critical,
);
-
+
# set the default this way so it only happens if someone typed -f or --filename
$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) {
print_help() ;
exit $ERRORS{'OK'};
}
if ($opt_V) {
- print_revision($PROGNAME,'$Revision: 1.12 $ ');
+ print_revision($PROGNAME,'$Revision: 1.18 $ ');
exit $ERRORS{'OK'};
}
-if ($opt_h) {
- print_help();
- exit $ERRORS{'OK'};
-}
-
-unless ( (
+unless (
+ (
defined $filename ||
+ (not defined $ignore_status) ||
(defined $sensor && ($warning || $critical))
) &&
( (!defined $filename) || (!defined $sensor) )
@@ -91,10 +134,9 @@
}
$CHECK_SENSOR = $sensor;
- $CHECKS{$sensor} = {
- 'warn' => $warning,
- 'crit' => $critical,
- };
+ $CHECKS{$sensor}{'warn'} = $warning if defined $warning;
+ $CHECKS{$sensor}{'crit'} = $critical if defined $critical;
+
} elsif (defined $filename) {
%CHECKS = parse_file($filename);
}
@@ -107,12 +149,26 @@
my ($id, $output) = split /=/;
my @o = split /,\s*/, $output;
- my $source = $o[0];
- my $descr = $o[1];
- my $status = $o[2] if @o == 5;
- my $type = $o[-2];
- my $data = $o[-1];
+ my ($type, $source, $descr, $data, $status);
+ $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} = {
id => $id,
output => $output,
@@ -134,18 +190,21 @@
$_a <=> $_b;
}
-foreach my $check (sort as_if_numeric keys %CHECKS) {
- if (exists $SENSORS{$check}) {
- my $r = check_sensor($CHECKS{$check}, $SENSORS{$check});
- push @{ $states{ $r } },
- $check . '=' . $SENSORS{$check}{'output'};
+foreach my $s (sort as_if_numeric keys %SENSORS) {
+ my ($r, $data);
+ if (exists $CHECKS{$s}) {
+ $r = check_sensor($SENSORS{$s}, $CHECKS{$s});
+ $data = $s . '=' . $SENSORS{$s}{'output'};
+ } elsif (not $ignore_status) {
+ $r = check_sensor($SENSORS{$s});
+ $data = $s . '=' . $SENSORS{$s}{'output'};
} 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';
my $have_results = 0;
foreach my $error (sort { $ERRORS{$a} <=> $ERRORS{$b} } keys %ERRORS) {
@@ -160,7 +219,7 @@
print "$error (" . scalar(@{ $states{ $error } }) . ")";
unless ($error eq 'OK') {
print '
';
- print map { " - $_
" } @{ $states{ $error } };
+ print map {" - $_
"} @{ $states{ $error } };
}
} else {
print "$error (" . scalar(@{ $states{ $error } }) . "):\n";
@@ -179,15 +238,23 @@
sub parse_file {
my $filename = shift;
my %contents;
+
+ die "file '$filename' does not exist." unless -e $filename;
open my $fh, '-|', $GETCAP, '-a', '-f', $filename
or die "Couldn't open FILE '$GETCAP -a -f $filename': $!";
- while (<$fh>) {
+ LINE: while (<$fh>) {
chomp;
my ($key, @c) = split /\:/;
foreach (@c) {
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;
@@ -199,6 +266,10 @@
my $type = shift;
my $check = shift;
+ return undef unless $check;
+ return undef if $check->{'STATUS'};
+ return 'IGNORE' if $check->{'IGNORE'};
+
foreach my $code ('crit', 'warn') {
if (defined $check->{$code} && $check->{$code} =~ /:/) {
if (my ($low, $high) = split /:/, $check->{$code}) {
@@ -222,8 +293,8 @@
}
sub check_sensor {
- my $check = shift;
my $sensor = shift;
+ my $check = shift;
my $result = 'UNKNOWN';
my %errors = (
'warn' => 'WARNING',
@@ -231,12 +302,22 @@
);
return $result unless ref $sensor eq 'HASH';
+ $check = parse_check($sensor->{'type'}, $check) if $check;
- $check = parse_check($sensor->{'type'}, $check);
- #print Dumper $check, $sensor;
+ unless ($check) {
+ 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') {
if (
$sensor->{'type'} eq 'volts_dc' ||
@@ -289,7 +370,7 @@
next;
}
- if ($_ eq $data) {
+ if ($c eq $data) {
$matched = 1;
last;
}
@@ -300,6 +381,7 @@
} elsif ($sensor->{'type'} eq 'temp') {
my ($degC, $degF) = split /\//, $sensor->{'data'};
$degC =~ s/[^\d\.]//g;
+ $degF ||= $degC * 9 / 5 + 32;
$degF =~ s/[^\d\.]//g;
if (
defined $check->{$code . ".low"} ||
@@ -367,7 +449,7 @@
next;
}
- if ($_ eq $data) {
+ if ($c eq $data) {
$matched = 1;
last;
}
@@ -379,6 +461,7 @@
$sensor->{'type'} eq 'drive' ||
$sensor->{'type'} eq 'indicator'
) {
+ $sensor->{'type'} =~ s/^drive\s+//;
if (@{ $check->{$code} }) {
my $matched = 0;
foreach (@{ $check->{$code} }) {
@@ -402,26 +485,28 @@
sub print_help {
print <]|(-s -w limit -c limit))
+ $PROGNAME [-i] (-f []|(-s [-w limit] [-c limit]))
Usage:
+ -i, --ignore-status
+ Don't check the status of sensors that report it.
-f, --filename=FILE
FILE to load checks from (defaults to /etc/sensorsd.conf)
-s, --sensor=ID
ID of a single sensor. "-s 0" means hw.sensors.0.
-w, --warning=RANGE or single 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
- -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:
- 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)
can be used when appropriate, or you can use the following:
@@ -448,8 +533,15 @@
It can also be low: or :high with the other side left blank to only
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
-
- print_revision($PROGNAME, '$Revision: 1.12 $');
+
+ print_revision($PROGNAME, '$Revision: 1.18 $');
}