File check_contentage of Package monitoring-plugins-contentage

#!/usr/bin/perl -w
# nagios: -epn
#
# check_contentage - nagios plugin
#
# Copyright (C) 2012, SUSE Linux Products GmbH
# Copyright (C) 2020, SUSE LCC
# Author: Lars Vogdt
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
#   list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
#   this list of conditions and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
#
# * Neither the name of the Novell nor the names of its contributors may be
#   used to endorse or promote products derived from this software without
#   specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#

use lib "/usr/lib/nagios/plugins";
use utils qw{$TIMEOUT %ERRORS print_revision};
use Time::HiRes qw{time alarm};
use strict;
use warnings;
use Getopt::Long;
use File::Basename;
use File::stat;
use POSIX qw(strftime);

our $version="0.7";
our $time_warn=1440;
our $time_crit=4880;
our @pathnames=qw();
our $help=0;
our @ignores=qw();
our $rev=0;
our $recursive=0;
our $errorstr="";
our $DEBUG=0;
our %status;

# nagios requires a 3 for unknown errors.
$SIG{__DIE__} = sub {
  print @_;
  exit 3;
};

# Just in case of problems, let's not hang Nagios
$SIG{'ALRM'} = sub {
    print "UNKNOWN - Plugin timed out\n";
    exit $ERRORS{"UNKNOWN"};
};
alarm($TIMEOUT);

sub print_usage {
	print "This plugin checks one or more directory for files older than a specified age.\n";
	print "You can define the age of files for warning and critical states.\n\n";
	print "Usage: ".basename($0)." -w $time_warn -c $time_crit -p /tmp,/var/tmp -i /tmp/foo,/tmp/bar\n";
	print "Options:\n";
	print "       -w|--warning   : time for warnings (minutes)\n";
	print "       -c|--critical  : time for critical warnings (minutes)\n";
	print "       -p|--pathnames : absolute path to the folders, split mutliple pathnames with commata\n";
#	print "       -r|--recursive : dive into subfolders\n";
	print "       -t|--timeout   : timeout (default: $TIMEOUT)\n";
	print "       -i|--ignore    : ignore filenames (comma separated)\n";
	print "       -d|--debug     : print debug output\n";
}

sub print_help {
	my $exitcode=shift || 1;
	print "Copyright (c) 2020, SUSE LCC\n\n";
	print_usage();
	print "\n";
	exit $exitcode;
}

sub print_error {
	my $error=shift || '';
	print STDERR "\nERROR: $error\n\n";
	&print_usage;
	exit $ERRORS{'UNKNOWN'};
}

sub check_dir($$$$){
	my $dir = shift;	
	my $secwarn = shift;
	my $seccrit = shift;
	my $ignores_ref = shift;
	my %res;
	my $count=0;
	my $futurecount=0;
	my $oldcount=0;
	my $warncount=0;
	$res{'level'}=$ERRORS{'OK'};
	$res{'errorstr'}="";
	if (opendir(DIR,"$dir")){
	    print "Working in $dir\n" if ($DEBUG);
	    for my $file (readdir(DIR)) {
#		if ($recursive){
#			&check_dir("$dir/$file",$secwarn,$seccrit) if (-d "$dir/$file");
#		}
 	        $count++;
	        next if (! -f "$dir/$file");
		if (grep(/\Q$dir\/$file\E/, @$ignores_ref)){
			print "$dir/$file is in ignores\n" if ($DEBUG);
			next;
		}
	        my $mtime=stat("$dir/$file")->mtime;
	        my $age = time() - $mtime;
	        my $time=strftime("%a %b %e %H:%M:%S %Y",localtime($mtime));
	        print "$dir/$file : $mtime : $age sec\n" if ($DEBUG);
		if ( $age < 0 ){
			$res{'errorstr'}.="$dir/$file was modified in the future!\n";
			$res{'level'}=$ERRORS{'CRITICAL'};
			$futurecount++;
		} elsif ( $age >= $seccrit ){
			$res{'errorstr'}.="$dir/$file was last modified on $time\n";
        	        $res{'level'}=$ERRORS{'CRITICAL'};
			$oldcount++;
	        } elsif ( $age >= $secwarn ){
			$res{'errorstr'}.="$dir/$file was last modified on $time\n";
			$res{'level'}=$ERRORS{'WARNING'} if ($res{'level'} < $ERRORS{'WARNING'});
			$warncount++;
                }
            }
	} else {
		$res{'level'}=$ERRORS{'WARNING'};
		$res{'errorstr'}="$dir not found or not readable";
	}
  $res{'count'}=$count;
  $res{'futurecount'}=$futurecount;
  $res{'oldcount'}=$oldcount;
  $res{'warncount'}=$warncount;
  return \%res;
}

Getopt::Long::Configure('bundling');
if(!GetOptions(	'w|warning=i'  => \$time_warn,
				'c|critical=i' => \$time_crit,
				'd|debug'      => \$DEBUG,
				'i|ignore=s'   => \@ignores,
				'p|pathname=s' => \@pathnames,
				'r|recursive'  => \$recursive,
				't|timeout=i'  => \$TIMEOUT,
				'h|help'       => \$help,
				'v|version'    => \$rev,
	)){
  &print_help(1);
}
&print_help(0) if ($help);
if ($rev){
	&print_revision(basename($0),$version);	
	exit $ERRORS{'UNKNOWN'};
}

print_error("warning must be greater than 0") if ($time_warn <= 0);
print_error("critical must be greater than 0") if ($time_crit <= 0);
print_error("critical ($time_crit) must be greater than warning ($time_warn)") if ($time_crit <= $time_warn);
print_error("Please provide at least one pathname") if (!defined($pathnames[0]) || ( $pathnames[0] eq "" ));
@pathnames=split(/,/,join(',',@pathnames));
@ignores=split(/,/,join(',',@ignores));
our $secwarn = $time_warn * 60;
our $seccrit = $time_crit * 60;
print STDERR "TIMEOUT: $TIMEOUT\nWARN: $time_warn\nCRIT: $time_crit\nPATHNAMES: ".join(" ",@pathnames)."\nIGNORES: ".join(" ",@ignores)."\n" if ($DEBUG);

foreach my $path (@pathnames){
	$status{"$path"}=check_dir("$path",$secwarn, $seccrit, \@ignores);
}

our $exitcode=0;
our ($total_count,$future_count,$old_count,$warncount)=0;
foreach my $path (sort(keys %status)){
	if ((defined($status{$path}{'level'})) && ($status{$path}{'level'} > $exitcode)){
		$exitcode=$status{$path}{'level'};
	}
	if ((defined($status{$path}{'errorstr'})) && ($status{$path}{'errorstr'} ne '')){
		$errorstr .= $status{$path}{'errorstr'};
	}
	$total_count+=$status{$path}{'count'};
	$future_count+=$status{$path}{'futurecount'};
	$old_count+=$status{$path}{'oldcount'};
	$warncount+=$status{$path}{'warncount'}
}

if ($exitcode){
	if ( $exitcode == $ERRORS{'WARNING'}){
		print "WARNING: Found files older than $time_warn minutes ";
	} elsif ( $exitcode == $ERRORS{'CRITICAL'}){
		print "CRITICAL: Found files older than $time_crit minutes ";
	}
	print "$errorstr";
	print "| total_files=$total_count;;;old_files=$old_count;;;warn_files=$warncount;;;files_with_future_timestamp=$future_count;;;\n";
	exit $exitcode;
} else {
	print "OK: Tested ".join(" ",@pathnames)." - no files older than $time_warn minutes found ";
	print "| total_files=$total_count;;;old_files=$old_count;;;warn_files=$warncount;;;files_with_future_timestamp=$future_count;;;\n";
	exit $ERRORS{"OK"};
}
openSUSE Build Service is sponsored by