aboutsummaryrefslogtreecommitdiff
path: root/plugins-scripts
diff options
context:
space:
mode:
authorGravatar RincewindsHat <12514511+RincewindsHat@users.noreply.github.com> 2021-12-02 16:42:05 +0100
committerGravatar GitHub <noreply@github.com> 2021-12-02 16:42:05 +0100
commit911e44045d7291f5ede22739fd176ef55dd3de4a (patch)
treecf36b95a4a964b03d6ecf75770ced2cb3a2ac3a9 /plugins-scripts
parent8294af907bd8482a86df749f562b7ec09e3faeed (diff)
parented7cdf82a42f16532801ea4f118870ce9a130fcf (diff)
downloadmonitoring-plugins-911e44045d7291f5ede22739fd176ef55dd3de4a.tar.gz
Merge branch 'master' into fix/shellcheck
Diffstat (limited to 'plugins-scripts')
-rw-r--r--plugins-scripts/Makefile.am2
-rwxr-xr-xplugins-scripts/check_disk_smb.pl7
-rwxr-xr-xplugins-scripts/check_file_age.pl61
-rwxr-xr-xplugins-scripts/check_ifoperstatus.pl2
-rwxr-xr-xplugins-scripts/check_ircd.pl4
-rwxr-xr-xplugins-scripts/check_log.sh88
-rwxr-xr-xplugins-scripts/check_mailq.pl34
-rwxr-xr-xplugins-scripts/check_uptime.pl315
-rw-r--r--plugins-scripts/t/check_file_age.t75
-rw-r--r--plugins-scripts/t/check_uptime.t129
-rw-r--r--plugins-scripts/t/utils.t1
11 files changed, 641 insertions, 77 deletions
diff --git a/plugins-scripts/Makefile.am b/plugins-scripts/Makefile.am
index ea65aed1..088a4459 100644
--- a/plugins-scripts/Makefile.am
+++ b/plugins-scripts/Makefile.am
@@ -16,11 +16,13 @@ VPATH=$(top_srcdir) $(top_srcdir)/plugins-scripts $(top_srcdir)/plugins-scripts/
libexec_SCRIPTS = check_breeze check_disk_smb check_flexlm check_ircd \
check_log check_oracle check_rpc check_sensors check_wave \
check_ifstatus check_ifoperstatus check_mailq check_file_age \
+ check_uptime \
utils.sh utils.pm
EXTRA_DIST=check_breeze.pl check_disk_smb.pl check_flexlm.pl check_ircd.pl \
check_log.sh check_oracle.sh check_rpc.pl check_sensors.sh \
check_ifstatus.pl check_ifoperstatus.pl check_wave.pl check_mailq.pl check_file_age.pl \
+ check_uptime.pl \
utils.sh.in utils.pm.in t
EDIT = sed \
diff --git a/plugins-scripts/check_disk_smb.pl b/plugins-scripts/check_disk_smb.pl
index 98992268..28c49e84 100755
--- a/plugins-scripts/check_disk_smb.pl
+++ b/plugins-scripts/check_disk_smb.pl
@@ -19,7 +19,7 @@
#
require 5.004;
-use POSIX;
+use POSIX qw(setsid);
use strict;
use Getopt::Long;
use vars qw($opt_P $opt_V $opt_h $opt_H $opt_s $opt_W $opt_u $opt_p $opt_w $opt_c $opt_a $verbose);
@@ -28,6 +28,9 @@ use FindBin;
use lib "$FindBin::Bin";
use utils qw($TIMEOUT %ERRORS &print_revision &support &usage);
+# make us session leader which makes all childs exit if we do
+setsid;
+
sub print_help ();
sub print_usage ();
@@ -175,6 +178,8 @@ my @lines = undef;
# Just in case of problems, let's not hang the monitoring system
$SIG{'ALRM'} = sub {
print "No Answer from Client\n";
+ $SIG{'INT'} = 'IGNORE';
+ kill(-2, $$);
exit $ERRORS{"UNKNOWN"};
};
alarm($TIMEOUT);
diff --git a/plugins-scripts/check_file_age.pl b/plugins-scripts/check_file_age.pl
index 56b8e97c..26281ddd 100755
--- a/plugins-scripts/check_file_age.pl
+++ b/plugins-scripts/check_file_age.pl
@@ -43,8 +43,6 @@ $ENV{'ENV'}='';
$opt_w = 240;
$opt_c = 600;
-$opt_W = 0;
-$opt_C = 0;
$opt_f = "";
Getopt::Long::Configure('bundling');
@@ -53,10 +51,10 @@ GetOptions(
"h" => \$opt_h, "help" => \$opt_h,
"i" => \$opt_i, "ignore-missing" => \$opt_i,
"f=s" => \$opt_f, "file" => \$opt_f,
- "w=f" => \$opt_w, "warning-age=f" => \$opt_w,
- "W=f" => \$opt_W, "warning-size=f" => \$opt_W,
- "c=f" => \$opt_c, "critical-age=f" => \$opt_c,
- "C=f" => \$opt_C, "critical-size=f" => \$opt_C);
+ "w=s" => \$opt_w, "warning-age=s" => \$opt_w,
+ "W=s" => \$opt_W, "warning-size=s" => \$opt_W,
+ "c=s" => \$opt_c, "critical-age=s" => \$opt_c,
+ "C=s" => \$opt_C, "critical-size=s" => \$opt_C);
if ($opt_V) {
print_revision($PROGNAME, '@NP_VERSION@');
@@ -91,18 +89,47 @@ unless (-e $opt_f) {
$st = File::stat::stat($opt_f);
$age = time - $st->mtime;
$size = $st->size;
-$perfdata = "age=${age}s;${opt_w};${opt_c} size=${size}B;${opt_W};${opt_C};0";
-
$result = 'OK';
-if (($opt_c and $age > $opt_c) or ($opt_C and $size < $opt_C)) {
- $result = 'CRITICAL';
+if ($opt_c !~ m/^\d+$/ or ($opt_C and $opt_C !~ m/^\d+$/)
+ or $opt_w !~ m/^\d+$/ or ($opt_W and $opt_W !~ m/^\d+$/)) {
+ # range has been specified so use M::P::R to process
+ require Monitoring::Plugin::Range;
+ # use permissive range defaults for size when none specified
+ $opt_W = "0:" unless ($opt_W);
+ $opt_C = "0:" unless ($opt_C);
+
+ if (Monitoring::Plugin::Range->parse_range_string($opt_c)
+ ->check_range($age) == 1) { # 1 means it raises an alert because it's OUTSIDE the range
+ $result = 'CRITICAL';
+ }
+ elsif (Monitoring::Plugin::Range->parse_range_string($opt_C)
+ ->check_range($size) == 1) {
+ $result = 'CRITICAL';
+ }
+ elsif (Monitoring::Plugin::Range->parse_range_string($opt_w)
+ ->check_range($age) == 1) {
+ $result = 'WARNING';
+ }
+ elsif (Monitoring::Plugin::Range->parse_range_string($opt_W)
+ ->check_range($size) == 1) {
+ $result = 'WARNING';
+ }
}
-elsif (($opt_w and $age > $opt_w) or ($opt_W and $size < $opt_W)) {
- $result = 'WARNING';
+else {
+ # use permissive defaults for size when none specified
+ $opt_W = 0 unless ($opt_W);
+ $opt_C = 0 unless ($opt_C);
+ if ($age > $opt_c or $size < $opt_C) {
+ $result = 'CRITICAL';
+ }
+ elsif ($age > $opt_w or $size < $opt_W) {
+ $result = 'WARNING';
+ }
}
+$perfdata = "age=${age}s;${opt_w};${opt_c} size=${size}B;${opt_W};${opt_C};0";
print "FILE_AGE $result: $opt_f is $age seconds old and $size bytes | $perfdata\n";
exit $ERRORS{$result};
@@ -120,7 +147,15 @@ sub print_help () {
print "\n";
print " -i | --ignore-missing : return OK if the file does not exist\n";
print " <secs> File must be no more than this many seconds old (default: warn 240 secs, crit 600)\n";
- print " <size> File must be at least this many bytes long (default: crit 0 bytes)\n";
+ print " <size> File must be at least this many bytes long (default: file size is ignored (0 bytes))\n\n";
+ print " Both <secs> and <size> can specify a range using the standard plugin syntax\n";
+ print " If any of the warning and critical arguments are in range syntax (not just bare numbers)\n";
+ print " then all warning and critical arguments will be interpreted as ranges.\n";
+ print " To use range processing the perl module Monitoring::Plugin must be installed\n";
+ print " For range syntax see https://www.monitoring-plugins.org/doc/guidelines.html#THRESHOLDFORMAT\n";
+ print " It is strongly recommended when using range syntax that all four of -w, -W, -c and -C are specified\n";
+ print " otherwise it is unlikely that the size test will be doing what is desired\n";
print "\n";
support();
}
+
diff --git a/plugins-scripts/check_ifoperstatus.pl b/plugins-scripts/check_ifoperstatus.pl
index 9ede1633..c190ce95 100755
--- a/plugins-scripts/check_ifoperstatus.pl
+++ b/plugins-scripts/check_ifoperstatus.pl
@@ -124,10 +124,10 @@ if (!defined($session)) {
## 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 {
+ # escape "/" in ifdescr - very common in the Cisco world
$ifdescr =~ s/\//\\\//g;
$status=fetch_ifindex($snmpIfDescr, $ifdescr); # if using on device with large number of interfaces
# recommend use of SNMP v2 (get-bulk)
diff --git a/plugins-scripts/check_ircd.pl b/plugins-scripts/check_ircd.pl
index 22d21c2e..d869ae7b 100755
--- a/plugins-scripts/check_ircd.pl
+++ b/plugins-scripts/check_ircd.pl
@@ -69,7 +69,9 @@ $ENV{'ENV'}='';
# -----------------------------------------------------------------[ Global ]--
$PROGNAME = "check_ircd";
-my $NICK="ircd$$";
+# nickname shouldn't be longer than 9 chars, this might happen with large PIDs
+# To prevent this, we cut of the part over 10000
+my $NICK="ircd" . $$ % 10000;
my $USER_INFO="monitor localhost localhost : ";
# -------------------------------------------------------------[ connection ]--
diff --git a/plugins-scripts/check_log.sh b/plugins-scripts/check_log.sh
index 8f76b1b5..61131236 100755
--- a/plugins-scripts/check_log.sh
+++ b/plugins-scripts/check_log.sh
@@ -1,8 +1,7 @@
#!/bin/sh
#
# Log file pattern detector plugin for monitoring
-# Written by Ethan Galstad (nagios@nagios.org)
-# Last Modified: 07-31-1999
+# Written originally by Ethan Galstad (nagios@nagios.org)
#
# Usage: ./check_log <log_file> <old_log_file> <pattern>
#
@@ -70,6 +69,11 @@ print_usage() {
echo "Usage: $PROGNAME -F logfile -O oldlog -q query"
echo "Usage: $PROGNAME --help"
echo "Usage: $PROGNAME --version"
+ echo ""
+ echo "Other parameters:"
+ echo " -a|--all : Print all matching lines"
+ echo " -p|--perl-regex : Use perl style regular expressions in the query"
+ echo " -e|--extended-regex : Use extended style regular expressions in the query (not necessary for GNU grep)"
}
print_help() {
@@ -116,34 +120,58 @@ while test -n "$1"; do
;;
--filename)
logfile=$2
- shift
+ shift 2
;;
-F)
logfile=$2
- shift
+ shift 2
;;
--oldlog)
oldlog=$2
- shift
+ shift 2
;;
-O)
oldlog=$2
- shift
+ shift 2
;;
--query)
query=$2
- shift
+ shift 2
;;
-q)
query=$2
- shift
+ shift 2
;;
-x)
exitstatus=$2
- shift
+ shift 2
;;
--exitstatus)
exitstatus=$2
+ shift 2
+ ;;
+ --extended-regex)
+ ERE=1
+ shift
+ ;;
+ -e)
+ ERE=1
+ shift
+ ;;
+ --perl-regex)
+ PRE=1
+ shift
+ ;;
+ -p)
+ PRE=1
+ shift
+ ;;
+ --all)
+ ALL=1
+ shift
+ ;;
+ -a)
+ ALL=1
shift
;;
*)
@@ -152,9 +180,24 @@ while test -n "$1"; do
exit "$STATE_UNKNOWN"
;;
esac
- shift
done
+# Parameter sanity check
+if [ $ERE ] && [ $PRE ] ; then
+ echo "Can not use extended and perl regex at the same time"
+ exit "$STATE_UNKNOWN"
+fi
+
+GREP="grep"
+
+if [ $ERE ]; then
+ GREP="grep -E"
+fi
+
+if [ $PRE ]; then
+ GREP="grep -P"
+fi
+
# If the source log file doesn't exist, exit
if [ ! -e "$logfile" ]; then
@@ -180,9 +223,10 @@ fi
# The temporary file that the script should use while
# processing the log file.
if [ -x /bin/mktemp ]; then
- tempdiff=$(/bin/mktemp /tmp/check_log.XXXXXXXXXX)
+
+ tempdiff=$(/bin/mktemp /tmp/check_log.XXXXXXXXXX)
else
- tempdiff=$(/bin/date '+%H%M%S')
+ tempdiff=$(/bin/date '+%H%M%S')
tempdiff="/tmp/check_log.${tempdiff}"
touch "$tempdiff"
chmod 600 "$tempdiff"
@@ -190,11 +234,21 @@ fi
diff "$logfile" "$oldlog" | grep -v "^>" > "$tempdiff"
-# Count the number of matching log entries we have
-count=$(grep -c "$query" "$tempdiff")
-# Get the last matching entry in the diff file
-lastentry=$(grep "$query" "$tempdiff" | tail -1)
+if [ $ALL ]; then
+ # Get the last matching entry in the diff file
+ entry=$($GREP "$query" "$tempdiff")
+
+ # Count the number of matching log entries we have
+ count=$(echo "$entry" | wc -l)
+
+else
+ # Count the number of matching log entries we have
+ count=$($GREP -c "$query" "$tempdiff")
+
+ # Get the last matching entry in the diff file
+ entry=$($GREP "$query" "$tempdiff" | tail -1)
+fi
rm -f "$tempdiff"
cat "$logfile" > "$oldlog"
@@ -203,7 +257,7 @@ if [ "$count" = "0" ]; then # no matches, exit with no error
echo "Log check ok - 0 pattern matches found"
exitstatus=$STATE_OK
else # Print total matche count and the last entry we found
- echo "($count) $lastentry"
+ echo "($count) $entry"
exitstatus=$STATE_CRITICAL
fi
diff --git a/plugins-scripts/check_mailq.pl b/plugins-scripts/check_mailq.pl
index 32f498d3..3914f4a7 100755
--- a/plugins-scripts/check_mailq.pl
+++ b/plugins-scripts/check_mailq.pl
@@ -28,9 +28,9 @@
use POSIX;
use strict;
use Getopt::Long;
-use vars qw($opt_V $opt_h $opt_v $verbose $PROGNAME $opt_w $opt_c $opt_t $opt_s
- $opt_M $mailq $status $state $msg $msg_q $msg_p $opt_W $opt_C $mailq @lines
- %srcdomains %dstdomains);
+use vars qw($opt_V $opt_h $opt_v $verbose $PROGNAME $opt_w $opt_c $opt_t $opt_s $opt_d
+ $opt_M $mailq $status $state $msg $msg_q $msg_p $opt_W $opt_C $mailq $mailq_args
+ @lines %srcdomains %dstdomains);
use FindBin;
use lib "$FindBin::Bin";
use utils qw(%ERRORS &print_revision &support &usage );
@@ -48,6 +48,8 @@ $PROGNAME = "check_mailq";
$mailq = 'sendmail'; # default
$msg_q = 0 ;
$msg_p = 0 ;
+# If appended, must start with a space
+$mailq_args = '' ;
$state = $ERRORS{'UNKNOWN'};
Getopt::Long::Configure('bundling');
@@ -68,6 +70,10 @@ if ($opt_s) {
$sudo = "";
}
+if ($opt_d) {
+ $mailq_args = $mailq_args . ' -C ' . $opt_d;
+}
+
$SIG{'ALRM'} = sub {
print ("ERROR: timed out waiting for $utils::PATH_TO_MAILQ \n");
exit $ERRORS{"WARNING"};
@@ -309,8 +315,8 @@ elsif ( $mailq eq "postfix" ) {
## open mailq
if ( defined $utils::PATH_TO_MAILQ && -x $utils::PATH_TO_MAILQ ) {
- if (! open (MAILQ, "$sudo $utils::PATH_TO_MAILQ | " ) ) {
- print "ERROR: could not open $utils::PATH_TO_MAILQ \n";
+ if (! open (MAILQ, "$sudo $utils::PATH_TO_MAILQ$mailq_args | " ) ) {
+ print "ERROR: could not open $utils::PATH_TO_MAILQ$mailq_args \n";
exit $ERRORS{'UNKNOWN'};
}
}elsif( defined $utils::PATH_TO_MAILQ){
@@ -330,7 +336,7 @@ elsif ( $mailq eq "postfix" ) {
close MAILQ;
if ( $? ) {
- print "CRITICAL: Error code ".($?>>8)." returned from $utils::PATH_TO_MAILQ",$/;
+ print "CRITICAL: Error code ".($?>>8)." returned from $utils::PATH_TO_MAILQ$mailq_args",$/;
exit $ERRORS{CRITICAL};
}
@@ -343,7 +349,7 @@ elsif ( $mailq eq "postfix" ) {
}elsif ($lines[0]=~/Mail queue is empty/) {
$msg_q = 0;
}else{
- print "Couldn't match $utils::PATH_TO_MAILQ output\n";
+ print "Couldn't match $utils::PATH_TO_MAILQ$mailq_args output\n";
exit $ERRORS{'UNKNOWN'};
}
@@ -533,7 +539,7 @@ elsif ( $mailq eq "nullmailer" ) {
while (<MAILQ>) {
#2006-06-22 16:00:00 282 bytes
- if (/^[1-9][0-9]*-[01][0-9]-[0-3][0-9]\s[0-2][0-9]\:[0-2][0-9]\:[0-2][0-9]\s{2}[0-9]+\sbytes$/) {
+ if (/^[1-9][0-9]*-[01][0-9]-[0-3][0-9]\s[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]\s+[0-9]+\sbytes/) {
$msg_q++ ;
}
}
@@ -568,7 +574,10 @@ sub process_arguments(){
"w=i" => \$opt_w, "warning=i" => \$opt_w, # warning if above this number
"c=i" => \$opt_c, "critical=i" => \$opt_c, # critical if above this number
"t=i" => \$opt_t, "timeout=i" => \$opt_t,
- "s" => \$opt_s, "sudo" => \$opt_s
+ "s" => \$opt_s, "sudo" => \$opt_s,
+ "d:s" => \$opt_d, "configdir:s" => \$opt_d,
+ "W=i" => \$opt_W, # warning if above this number
+ "C=i" => \$opt_C, # critical if above this number
);
if ($opt_V) {
@@ -649,7 +658,7 @@ sub process_arguments(){
}
sub print_usage () {
- print "Usage: $PROGNAME -w <warn> -c <crit> [-W <warn>] [-C <crit>] [-M <MTA>] [-t <timeout>] [-s] [-v]\n";
+ print "Usage: $PROGNAME -w <warn> -c <crit> [-W <warn>] [-C <crit>] [-M <MTA>] [-t <timeout>] [-s] [-d <CONFIGDIR>] [-v]\n";
}
sub print_help () {
@@ -662,11 +671,12 @@ sub print_help () {
print " Feedback/patches to support non-sendmail mailqueue welcome\n\n";
print "-w (--warning) = Min. number of messages in queue to generate warning\n";
print "-c (--critical) = Min. number of messages in queue to generate critical alert ( w < c )\n";
- print "-W (--Warning) = Min. number of messages for same domain in queue to generate warning\n";
- print "-C (--Critical) = Min. number of messages for same domain in queue to generate critical alert ( W < C )\n";
+ print "-W = Min. number of messages for same domain in queue to generate warning\n";
+ print "-C = Min. number of messages for same domain in queue to generate critical alert ( W < C )\n";
print "-t (--timeout) = Plugin timeout in seconds (default = $utils::TIMEOUT)\n";
print "-M (--mailserver) = [ sendmail | qmail | postfix | exim | nullmailer ] (default = autodetect)\n";
print "-s (--sudo) = Use sudo to call the mailq command\n";
+ print "-d (--configdir) = Config file or directory\n";
print "-h (--help)\n";
print "-V (--version)\n";
print "-v (--verbose) = debugging output\n";
diff --git a/plugins-scripts/check_uptime.pl b/plugins-scripts/check_uptime.pl
new file mode 100755
index 00000000..4c9f22da
--- /dev/null
+++ b/plugins-scripts/check_uptime.pl
@@ -0,0 +1,315 @@
+#!@PERL@ -w
+
+# check_uptime - check uptime to see how long the system is running.
+#
+
+# License Information:
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+# USA
+#
+############################################################################
+
+use POSIX;
+use strict;
+use Getopt::Long;
+use vars qw($opt_V $opt_h $opt_v $verbose $PROGNAME $opt_w $opt_c
+ $opt_f $opt_s
+ $lower_warn_threshold $upper_warn_threshold
+ $lower_crit_threshold $upper_crit_threshold
+ $status $state $msg);
+use FindBin;
+use lib "$FindBin::Bin";
+use utils qw(%ERRORS &print_revision &support &usage );
+
+sub print_help ();
+sub print_usage ();
+sub process_arguments ();
+
+$ENV{'PATH'}='@TRUSTED_PATH@';
+$ENV{'BASH_ENV'}='';
+$ENV{'ENV'}='';
+$PROGNAME = "check_uptime";
+$state = $ERRORS{'UNKNOWN'};
+
+my $uptime_file = "/proc/uptime";
+
+
+# Process arguments
+
+Getopt::Long::Configure('bundling');
+$status = process_arguments();
+if ($status){
+ print "ERROR: processing arguments\n";
+ exit $ERRORS{"UNKNOWN"};
+}
+
+
+# Get uptime info from file
+
+if ( ! -r $uptime_file ) {
+ print "ERROR: file '$uptime_file' is not readable\n";
+ exit $ERRORS{"UNKNOWN"};
+}
+
+if ( ! open FILE, "<", $uptime_file ) {
+ print "ERROR: cannot read from file '$uptime_file'\n";
+ exit $ERRORS{"UNKNOWN"};
+}
+
+chomp( my $file_content = <FILE> );
+close FILE;
+
+print "$uptime_file: $file_content\n" if $verbose;
+
+# Get first digit value (without fraction)
+my ( $uptime_seconds ) = $file_content =~ /^([\d]+)/;
+
+# Bail out if value is not numeric
+if ( $uptime_seconds !~ /^\d+$/ ) {
+ print "ERROR: no numeric value: $uptime_seconds\n";
+ exit $ERRORS{"UNKNOWN"};
+}
+
+
+# Do calculations for a "pretty" format (2 weeks, 5 days, ...)
+
+my ( $secs, $mins, $hours, $days, $weeks );
+$secs = $uptime_seconds;
+$mins = $hours = $days = $weeks = 0;
+if ( $secs > 100 ) {
+ $mins = int( $secs / 60 );
+ $secs -= $mins * 60;
+}
+if ( $mins > 100 ) {
+ $hours = int( $mins / 60 );
+ $mins -= $hours * 60;
+}
+if ( $hours > 48 ) {
+ $days = int( $hours / 24 );
+ $hours -= $days * 24;
+}
+if ( $days > 14 ) {
+ $weeks = int( $days / 7 );
+ $days -= $weeks * 7;
+}
+
+my $pretty_uptime = "";
+$pretty_uptime .= sprintf( "%d week%s, ", $weeks, $weeks == 1 ? "" : "s" ) if $weeks;
+$pretty_uptime .= sprintf( "%d day%s, ", $days, $days == 1 ? "" : "s" ) if $days;
+$pretty_uptime .= sprintf( "%d hour%s, ", $hours, $hours == 1 ? "" : "s" ) if $hours;
+$pretty_uptime .= sprintf( "%d minute%s, ", $mins, $mins == 1 ? "" : "s" ) if $mins;
+# Replace last occurence of comma with "and"
+$pretty_uptime =~ s/, $/ and /;
+# Always print the seconds (though it may be 0 seconds)
+$pretty_uptime .= sprintf( "%d second%s", $secs, $secs == 1 ? "" : "s" );
+
+
+# Default to catch errors in program
+my $state_str = "UNKNOWN";
+
+# Check values
+my $out_of_bounds_text = "";
+if ( $uptime_seconds > $upper_crit_threshold ) {
+ $state_str = "CRITICAL";
+ $out_of_bounds_text = "upper crit";
+} elsif ( $uptime_seconds < $lower_crit_threshold ) {
+ $state_str = "CRITICAL";
+ $out_of_bounds_text = "lower crit";
+} elsif ( $uptime_seconds > $upper_warn_threshold ) {
+ $state_str = "WARNING";
+ $out_of_bounds_text = "upper warn";
+} elsif ( $uptime_seconds < $lower_warn_threshold ) {
+ $state_str = "WARNING";
+ $out_of_bounds_text = "lower warn";
+} else {
+ $state_str = "OK";
+}
+
+$msg = "$state_str: ";
+
+$msg .= "uptime is $uptime_seconds seconds. ";
+$msg .= "Exceeds $out_of_bounds_text threshold. " if $out_of_bounds_text;
+$msg .= "Running for $pretty_uptime. " if $opt_f;
+if ( $opt_s ) {
+ my $up_since = strftime( "%Y-%m-%d %H:%M:%S", localtime( time - $uptime_seconds ) );
+ $msg .= "Running since $up_since. ";
+}
+
+$state = $ERRORS{$state_str};
+
+# Perfdata support
+print "$msg|uptime=${uptime_seconds}s;$upper_warn_threshold;$upper_crit_threshold;0\n";
+exit $state;
+
+
+#####################################
+#### subs
+
+
+sub process_arguments(){
+ GetOptions
+ ("V" => \$opt_V, "version" => \$opt_V,
+ "v" => \$opt_v, "verbose" => \$opt_v,
+ "h" => \$opt_h, "help" => \$opt_h,
+ "w=s" => \$opt_w, "warning=s" => \$opt_w, # warning if above this number
+ "c=s" => \$opt_c, "critical=s" => \$opt_c, # critical if above this number
+ "f" => \$opt_f, "for" => \$opt_f, # show "running for ..."
+ "s" => \$opt_s, "since" => \$opt_s, # show "running since ..."
+ );
+
+ if ($opt_V) {
+ print_revision($PROGNAME,'@NP_VERSION@');
+ exit $ERRORS{'UNKNOWN'};
+ }
+
+ if ($opt_h) {
+ print_help();
+ exit $ERRORS{'UNKNOWN'};
+ }
+
+ if (defined $opt_v) {
+ $verbose = $opt_v;
+ }
+
+ unless ( defined $opt_w && defined $opt_c ) {
+ print_usage();
+ exit $ERRORS{'UNKNOWN'};
+ }
+
+ # Check if a range was supplied ("lowvalue:highvalue") for warning and critical
+ # Otherwise, set 0 as the lower threshold and the parameter value as upper threshold
+ # (the uptime should always be positive, so there should be no issue)
+ if ( $opt_w =~ /^(.+):(.+)$/ ) {
+ $lower_warn_threshold = $1;
+ $upper_warn_threshold = $2;
+ } else {
+ $lower_warn_threshold = 0;
+ $upper_warn_threshold = $opt_w;
+ }
+ if ( $opt_c =~ /^(.+):(.+)$/ ) {
+ $lower_crit_threshold = $1;
+ $upper_crit_threshold = $2;
+ } else {
+ $lower_crit_threshold = 0;
+ $upper_crit_threshold = $opt_c;
+ }
+
+ # Set as seconds (calculate if suffix present)
+ $lower_warn_threshold = calc_as_seconds( $lower_warn_threshold );
+ $lower_crit_threshold = calc_as_seconds( $lower_crit_threshold );
+ $upper_warn_threshold = calc_as_seconds( $upper_warn_threshold );
+ $upper_crit_threshold = calc_as_seconds( $upper_crit_threshold );
+
+ # Check for numeric value of warning parameter
+ if ( $lower_warn_threshold !~ /^\d+$/ ) {
+ print "Lower warning (-w) is not numeric\n";
+ exit $ERRORS{'UNKNOWN'};
+ }
+ if ( $upper_warn_threshold !~ /^\d+$/ ) {
+ print "Upper warning (-w) is not numeric\n";
+ exit $ERRORS{'UNKNOWN'};
+ }
+ # Check for numeric value of critical parameter
+ if ( $lower_crit_threshold !~ /^\d+$/ ) {
+ print "Lower critical (-c) is not numeric\n";
+ exit $ERRORS{'UNKNOWN'};
+ }
+ if ( $upper_crit_threshold !~ /^\d+$/ ) {
+ print "Upper critical (-c) is not numeric\n";
+ exit $ERRORS{'UNKNOWN'};
+ }
+
+ # Check boundaries
+ if ( $upper_warn_threshold >= $upper_crit_threshold ) {
+ print "Upper Warning (-w) cannot be greater than Critical (-c)!\n";
+ exit $ERRORS{'UNKNOWN'};
+ }
+ # No "<=" since both values are zero if no range (only upper threshold values) is given
+ if ( $lower_warn_threshold < $lower_crit_threshold ) {
+ print "Lower Warning (-w) cannot be less than Critical (-c)!\n";
+ exit $ERRORS{'UNKNOWN'};
+ }
+
+ return $ERRORS{'OK'};
+}
+
+sub print_usage () {
+ print "Usage: $PROGNAME -w <warn> -c <crit> [-v]\n";
+}
+
+sub print_help () {
+ print_revision($PROGNAME,'@NP_VERSION@');
+ print "Copyright (c) 2002 Subhendu Ghosh/Carlos Canau/Benjamin Schmid\n";
+ print "Copyright (c) 2018 Bernd Arnold\n";
+ print "\n";
+ print_usage();
+ print "\n";
+ print " Checks the uptime of the system using $uptime_file\n";
+ print "\n";
+ print "-w (--warning) = Min. number of uptime to generate warning\n";
+ print "-c (--critical) = Min. number of uptime to generate critical alert ( w < c )\n";
+ print "-f (--for) = Show uptime in a pretty format (Running for x weeks, x days, ...)\n";
+ print "-s (--since) = Show last boot in yyyy-mm-dd HH:MM:SS format (output from 'uptime -s')\n";
+ print "-h (--help)\n";
+ print "-V (--version)\n";
+ print "-v (--verbose) = debugging output\n";
+ print "\n\n";
+ print "Note: -w and -c are required arguments.\n";
+ print " You can suffix both values with s for seconds (default), m (minutes), h (hours), d (days) or w (weeks).\n";
+ print "\n";
+ print "Range support: You may specify a range for both warning and critical thresholds.\n";
+ print " This works without additional Perl modules.\n";
+ print "Example: ./check_uptime -w 10m:4w -c 1m:8w\n";
+ print " Results in a critical state when uptime is below 60 seconds or higher than 8 weeks,\n";
+ print " and in a warning state when uptime is below 10 minutes or above 4 weeks.\n";
+ print "\n\n";
+ support();
+}
+
+sub calc_as_seconds () {
+
+ my $parameter = shift;
+
+ # Check if suffix is present
+ # Calculate parameter to seconds (to get an integer value finally)
+ # If no suffix is present, just return the value
+
+ # Possible suffixes:
+ # s = seconds
+ # m = minutes
+ # h = hours
+ # d = days
+ # w = weeks
+ my %factor = ( "s" => 1,
+ "m" => 60,
+ "h" => 60 * 60,
+ "d" => 60 * 60 * 24,
+ "w" => 60 * 60 * 24 * 7,
+ );
+
+ if ( $parameter =~ /^(\d+)([a-z])$/ ) {
+ my $value = $1;
+ my $suffix = $2;
+ print "detected: value=$value, suffix=$suffix\n" if $verbose;
+ if ( ! defined $factor{$suffix} ) {
+ print "Error: wrong suffix ($suffix) for value '$parameter'";
+ exit $ERRORS{'UNKNOWN'};
+ }
+ $parameter = $value * $factor{$suffix};
+ }
+
+ return $parameter;
+
+}
diff --git a/plugins-scripts/t/check_file_age.t b/plugins-scripts/t/check_file_age.t
index 50a2e699..8b876708 100644
--- a/plugins-scripts/t/check_file_age.t
+++ b/plugins-scripts/t/check_file_age.t
@@ -5,14 +5,14 @@
#
use strict;
-use Test::More tests => 17;
+use Test::More tests => 27;
use NPTest;
my $successOutput = '/^FILE_AGE OK: /';
my $warningOutput = '/^FILE_AGE WARNING: /';
my $criticalOutput = '/^FILE_AGE CRITICAL: /';
my $unknownOutput = '/^FILE_AGE UNKNOWN: /';
-my $performanceOutput = '/ \| age=[0-9]+s;[0-9]+;[0-9]+ size=[0-9]+B;[0-9]+;[0-9]+;0$/';
+my $performanceOutput = '/ \| age=[0-9]+s;[0-9:]+;[0-9:]+ size=[0-9]+B;[0-9:]+;[0-9:]+;0$/';
my $result;
my $temp_file = "/tmp/check_file_age.tmp";
@@ -20,64 +20,75 @@ my $temp_link = "/tmp/check_file_age.link.tmp";
unlink $temp_file, $temp_link;
-$result = NPTest->testCmd(
- "./check_file_age"
- );
+$result = NPTest->testCmd("./check_file_age");
cmp_ok( $result->return_code, '==', 3, "Missing parameters" );
like ( $result->output, $unknownOutput, "Output for unknown correct" );
-$result = NPTest->testCmd(
- "./check_file_age -f $temp_file"
- );
+$result = NPTest->testCmd("./check_file_age -f $temp_file");
cmp_ok( $result->return_code, '==', 2, "File not exists" );
like ( $result->output, $criticalOutput, "Output for file missing correct" );
write_chars(100);
-$result = NPTest->testCmd(
- "./check_file_age -f $temp_file"
- );
+$result = NPTest->testCmd("./check_file_age -f $temp_file");
cmp_ok( $result->return_code, '==', 0, "File is new enough" );
like ( $result->output, $successOutput, "Output for success correct" );
sleep 2;
-$result = NPTest->testCmd(
- "./check_file_age -f $temp_file -w 1"
- );
+$result = NPTest->testCmd("./check_file_age -f $temp_file -w 1");
cmp_ok( $result->return_code, '==', 1, "Warning for file over 1 second old" );
like ( $result->output, $warningOutput, "Output for warning correct" );
-$result = NPTest->testCmd(
- "./check_file_age -f $temp_file -c 1"
- );
+$result = NPTest->testCmd("./check_file_age -f $temp_file -c 1");
cmp_ok( $result->return_code, '==', 2, "Critical for file over 1 second old" );
like ( $result->output, $criticalOutput, "Output for critical correct" );
-$result = NPTest->testCmd(
- "./check_file_age -f $temp_file -c 1000 -W 100"
- );
+$result = NPTest->testCmd("./check_file_age -f $temp_file -c 1000 -W 100");
cmp_ok( $result->return_code, '==', 0, "Checking file size" );
-$result = NPTest->testCmd(
- "./check_file_age -f $temp_file -c 1000 -W 100"
- );
+$result = NPTest->testCmd("./check_file_age -f $temp_file -c 1000 -W 100");
like( $result->output, $performanceOutput, "Checking for performance Output" );
-$result = NPTest->testCmd(
- "./check_file_age -f /non/existent --ignore-missing"
- );
+$result = NPTest->testCmd("./check_file_age -f $temp_file -c 1000 -W 100");
+like( $result->output, $performanceOutput, "Checking for performance Output from range" );
+
+$result = NPTest->testCmd("./check_file_age -f /non/existent --ignore-missing");
cmp_ok( $result->return_code, '==', 0, "Honours --ignore-missing" );
-$result = NPTest->testCmd(
- "./check_file_age -f $temp_file -c 1000 -W 101"
- );
+$result = NPTest->testCmd("./check_file_age -f $temp_file -c 1000 -W 101");
cmp_ok( $result->return_code, '==', 1, "One byte too short" );
-$result = NPTest->testCmd(
- "./check_file_age -f $temp_file -c 1000 -C 101"
- );
+$result = NPTest->testCmd("./check_file_age -f $temp_file -c 1000 -C 101");
cmp_ok( $result->return_code, '==', 2, "One byte too short - critical" );
+SKIP: {
+ eval 'use Monitoring::Plugin::Range';
+ skip "Monitoring::Plugin::Range module require", 9 if $@;
+
+ $result = NPTest->testCmd("./check_file_age -f $temp_file -w 0:1");
+ cmp_ok( $result->return_code, '==', 1, "Warning for file over 1 second old by range" );
+ like ( $result->output, $warningOutput, "Output for warning by range correct" );
+
+ $result = NPTest->testCmd("./check_file_age -f $temp_file -c 0:1");
+ cmp_ok( $result->return_code, '==', 2, "Critical for file over 1 second old by range" );
+ like ( $result->output, $criticalOutput, "Output for critical by range correct" );
+
+ $result = NPTest->testCmd("./check_file_age -f $temp_file -c 0:1000 -W 0:100");
+ cmp_ok( $result->return_code, '==', 0, "Checking file size by range" );
+
+ $result = NPTest->testCmd("./check_file_age -f $temp_file -c 1000 -W 101:");
+ cmp_ok( $result->return_code, '==', 1, "One byte too short by range" );
+
+ $result = NPTest->testCmd("./check_file_age -f $temp_file -c 1000 -W 0:99");
+ cmp_ok( $result->return_code, '==', 1, "One byte too long by range" );
+
+ $result = NPTest->testCmd("./check_file_age -f $temp_file -c 1000 -C 101:");
+ cmp_ok( $result->return_code, '==', 2, "One byte too short by range - critical" );
+
+ $result = NPTest->testCmd("./check_file_age -f $temp_file -c 1000 -C 0:99");
+ cmp_ok( $result->return_code, '==', 2, "One byte too long by range - critical" );
+};
+
symlink $temp_file, $temp_link or die "Cannot create symlink";
$result = NPTest->testCmd("./check_file_age -f $temp_link -c 10");
cmp_ok( $result->return_code, '==', 0, "Works for symlinks" );
diff --git a/plugins-scripts/t/check_uptime.t b/plugins-scripts/t/check_uptime.t
new file mode 100644
index 00000000..c395307c
--- /dev/null
+++ b/plugins-scripts/t/check_uptime.t
@@ -0,0 +1,129 @@
+#!/usr/bin/perl -w -I ..
+#
+# check_uptime tests
+#
+#
+
+use strict;
+use Test::More tests => 40;
+use NPTest;
+
+my $result;
+
+$result = NPTest->testCmd(
+ "./check_uptime"
+ );
+cmp_ok( $result->return_code, '==', 3, "Missing parameters" );
+like ( $result->output, '/^Usage: check_uptime -w/', "Output for missing parameters correct" );
+
+$result = NPTest->testCmd(
+ "./check_uptime --help"
+ );
+cmp_ok( $result->return_code, '==', 3, "Help output requested" );
+like ( $result->output, '/ABSOLUTELY NO WARRANTY/', "Output for help correct" );
+
+$result = NPTest->testCmd(
+ "./check_uptime -w 5 -c 2"
+ );
+cmp_ok( $result->return_code, '==', 3, "Warning greater than critical" );
+like ( $result->output, '/^Upper Warning .*cannot be greater than Critical/', "Output for warning greater than critical correct" );
+
+$result = NPTest->testCmd(
+ "./check_uptime -c 1000 -W 100 2>&1"
+ );
+like ( $result->output, '/^Unknown option: W/', "Output with wrong parameter is correct" );
+
+$result = NPTest->testCmd(
+ "./check_uptime -f -w 1 -c 2"
+ );
+cmp_ok( $result->return_code, '==', 2, "Uptime higher than 2 seconds" );
+like ( $result->output, '/Running for \d+/', "Output for the f parameter correct" );
+
+$result = NPTest->testCmd(
+ "./check_uptime -s -w 1 -c 2"
+ );
+cmp_ok( $result->return_code, '==', 2, "Uptime higher than 2 seconds" );
+like ( $result->output, '/Running since \d+/', "Output for the s parameter correct" );
+
+$result = NPTest->testCmd(
+ "./check_uptime -w 1 -c 2"
+ );
+cmp_ok( $result->return_code, '==', 2, "Uptime higher than 2 seconds" );
+like ( $result->output, '/^CRITICAL: uptime is \d+ seconds/', "Output for uptime higher than 2 seconds correct" );
+
+$result = NPTest->testCmd(
+ "./check_uptime -w 1 -c 9999w"
+ );
+cmp_ok( $result->return_code, '==', 1, "Uptime lower than 9999 weeks" );
+like ( $result->output, '/^WARNING: uptime is \d+ seconds/', "Output for uptime lower than 9999 weeks correct" );
+
+$result = NPTest->testCmd(
+ "./check_uptime -w 9998w -c 9999w"
+ );
+cmp_ok( $result->return_code, '==', 0, "Uptime lower than 9998 weeks" );
+like ( $result->output, '/^OK: uptime is \d+ seconds/', "Output for uptime lower than 9998 weeks correct" );
+like ( $result->output, '/\|uptime=[0-9]+s;6046790400;6047395200;/', "Checking for performance output" );
+
+$result = NPTest->testCmd(
+ "./check_uptime -w 111222d -c 222333d"
+ );
+cmp_ok( $result->return_code, '==', 0, "Uptime lower than 111222 days" );
+like ( $result->output, '/^OK: uptime is \d+ seconds/', "Output for uptime lower than 111222 days correct" );
+like ( $result->output, '/\|uptime=[0-9]+s;9609580800;19209571200;/', "Checking for performance output" );
+
+# Same as before, hopefully uptime is higher than 2 seconds so no warning
+$result = NPTest->testCmd(
+ "./check_uptime -w 2:111222d -c 1:222333d"
+ );
+cmp_ok( $result->return_code, '==', 0, "Uptime lower than 111222 days, and higher 2 seconds" );
+like ( $result->output, '/^OK: uptime is \d+ seconds/', "Output for uptime lower than 111222 days, and higher 2 seconds correct" );
+like ( $result->output, '/\|uptime=[0-9]+s;9609580800;19209571200;/', "Checking for performance output" );
+
+# Same as before, now the low warning should trigger
+$result = NPTest->testCmd(
+ "./check_uptime -w 111221d:111222d -c 1:222333d"
+ );
+cmp_ok( $result->return_code, '==', 1, "Uptime lower than 111221 days raises warning" );
+like ( $result->output, '/^WARNING: uptime is \d+ seconds/', "Output for uptime lower than 111221 days correct" );
+like ( $result->output, '/Exceeds lower warn threshold/', "Exceeds text correct" );
+like ( $result->output, '/\|uptime=[0-9]+s;9609580800;19209571200;/', "Checking for performance output" );
+
+# Same as before, now the low critical should trigger
+$result = NPTest->testCmd(
+ "./check_uptime -w 111221d:111222d -c 111220d:222333d"
+ );
+cmp_ok( $result->return_code, '==', 2, "Uptime lower than 111220 days raises critical" );
+like ( $result->output, '/^CRITICAL: uptime is \d+ seconds/', "Output for uptime lower than 111220 days correct" );
+like ( $result->output, '/Exceeds lower crit threshold/', "Exceeds text correct" );
+like ( $result->output, '/\|uptime=[0-9]+s;9609580800;19209571200;/', "Checking for performance output" );
+
+
+#
+# Range values using ":" without two parts ("a:b") is invalid
+# Strings without two parts are always considered as upper threshold
+#
+
+$result = NPTest->testCmd(
+ "./check_uptime -w 2: -c 1:4"
+ );
+cmp_ok( $result->return_code, '==', 3, "Wrong parameter format raises unknown" );
+like ( $result->output, '/^Upper warning .* is not numeric/', "Output for wrong parameter format correct" );
+
+$result = NPTest->testCmd(
+ "./check_uptime -w 2:3 -c 1:"
+ );
+cmp_ok( $result->return_code, '==', 3, "Wrong parameter format raises unknown" );
+like ( $result->output, '/^Upper critical .* is not numeric/', "Output for wrong parameter format correct" );
+
+$result = NPTest->testCmd(
+ "./check_uptime -w :3 -c 1:4"
+ );
+cmp_ok( $result->return_code, '==', 3, "Wrong parameter format raises unknown" );
+like ( $result->output, '/^Upper warning .* is not numeric/', "Output for wrong parameter format correct" );
+
+$result = NPTest->testCmd(
+ "./check_uptime -w 2:3 -c :4"
+ );
+cmp_ok( $result->return_code, '==', 3, "Wrong parameter format raises unknown" );
+like ( $result->output, '/^Upper critical .* is not numeric/', "Output for wrong parameter format correct" );
+
diff --git a/plugins-scripts/t/utils.t b/plugins-scripts/t/utils.t
index 9c2c5695..5c231791 100644
--- a/plugins-scripts/t/utils.t
+++ b/plugins-scripts/t/utils.t
@@ -10,6 +10,7 @@ use strict;
use Test::More;
use NPTest;
+use lib ".";
use lib "..";
use utils;