monitoring-plugins-cyconet/check_file/check_file
2013-11-18 11:38:01 +01:00

416 lines
12 KiB
Perl
Executable file

#!/usr/bin/perl -w
# nagios: -epn
#####################
#
# check_file.pl - Nagios NRPE plugin to check file count, size and ages
#
# This program is distributed under the Artistic License.
# (http://www.opensource.org/licenses/artistic-license.php)
# Copyright 2007-2009, Tevfik Karagulle, ITeF!x Consulting (http://itefix.no)
use strict;
use warnings;
use Getopt::Long;
use File::Find;
use File::stat;
use Time::ParseDate;
our $VERSION = "1.4";
our $OK = 0;
our $WARNING = 1;
our $CRITICAL = 2;
our $UNKNOWN = 3;
our %status_text = (
$OK => "OK",
$WARNING => "WARNING",
$CRITICAL => "CRITICAL",
$UNKNOWN => "UNKNOWN"
);
our $numfiles = 0;
our $numdelete = 0;
our $numall = 0;
our @targets = ();
our $warning = undef;
our $critical = undef;
our @filters = ();
our $delete = 0;
our $verbose = 0;
our $rootonly = 0;
our $compare = 'gt'; # type of comprison operator for critical/warning thresholds
our $help = 0;
GetOptions (
"target=s" => \@targets,
"warning=i" => \$warning,
"critical=i" => \$critical,
"verbose" => \$verbose,
"rootonly" => \$rootonly,
"compare=s" => sub { $compare = lc $_[1] },
"delete" => \$delete,
"filter=s" => \@filters,
"help" => sub { PrintUsage() }
) || PrintUsage();
ExitProgram ($UNKNOWN, "No targets are specified.") if not scalar @targets;
grep (/$compare/, split (',', 'eq,ne,gt,ge,lt,le')) || ExitProgram($UNKNOWN, "Unsupported compare operator: $compare");
@targets = split(/,/,join(',', @targets));
@filters = split(/,/,join(',', @filters));
our @files = ();
foreach my $target (@targets)
{
-e $target || ExitProgram($UNKNOWN, "Target does not exist");
-d $target && do
{
if ($rootonly)
{
opendir(DIR, $target) || ExitProgram($UNKNOWN, "Can't opendir $target: $!");
my @rootfiles = grep { -f "$target/$_" } readdir(DIR);
closedir DIR;
foreach (@rootfiles) {
AddFile("$target/$_");
}
} else {
find (\&wanted, $target);
};
next;
};
-f $target && do
{
AddFile($target);
next;
}
}
my $message = "$numfiles files " . (($numfiles < $numall) ? "out of $numall " : "") . "to consider " . (($delete and $numdelete) ? ", $numdelete deleted.":"");
defined $critical && IsThreshold($numfiles, $critical, $compare) && ExitProgram ($CRITICAL, $message);
defined $warning && IsThreshold($numfiles, $warning, $compare) && ExitProgram ($WARNING, $message);
ExitProgram ($OK, $message);
#### SUBROUTINES ####
sub wanted
{
-f $File::Find::name && AddFile($File::Find::name);
}
##### AddFile #####
sub AddFile
{
$numall++;
my $file = shift;
my $infilter = 0;
my $sb = stat($file);
my $lage;
foreach my $filter (@filters)
{
# filters consist of three fields separated by white space
my ($filter_type, $filter_op, $filter_val) = ($filter =~ /(\S+)\s+(\S+)\s+(.*)/);
($filter_type && $filter_op && $filter_val)
|| ExitProgram($UNKNOWN, "A filterspec should consist of three fields : $filter");
$filter_type = lc $filter_type;
$filter_op = lc $filter_op;
$filter_type eq 'name' && $filter_op eq 'match' && $file =~ /$filter_val/ && $infilter++ && next;
$filter_type eq 'size' && IsThreshold($sb->size, $filter_val, $filter_op) && $infilter++ && next;
$filter_type eq 'age' && ($lage = parsedate($filter_val)) && IsThreshold($sb->mtime, $lage, $filter_op) && $infilter++ && print "ok " && next;
}
if ($infilter == scalar @filters) { # Are all filters passed through ??
$delete && (unlink $file) && $numdelete++; # delete function
print "$file - " . $sb->size . " bytes, modified at " . localtime($sb->mtime) . "\n" if $verbose;
$numfiles++;
}
}
##### IsThreshold #####
sub IsThreshold
{
my ($value, $threshold, $operand) = @_;
return
($operand eq 'eq' and $value == $threshold) ||
($operand eq 'ne' and $value != $threshold) ||
($operand eq 'gt' and $value > $threshold) ||
($operand eq 'ge' and $value >= $threshold) ||
($operand eq 'lt' and $value < $threshold) ||
($operand eq 'le' and $value <= $threshold);
}
##### PrintUsage #####
sub PrintUsage
{
print "
Usage:
check_file --target file/directory[,file/directory]...]] [[--target ...]
... ] --filter filterspec[,filterspec]...]] [[--filter ...] ... ]
[--delete] [--warning threshold] [--critical threshold] [--rootonly]
[--compare operator] [--verbose] [--help]
Options:
--target file/directory[,file/directory]...]] [[--target ...] ... ]
This option specifies targets to check. A target can be a simple
file or a recursive list of files in a directory. You can specify
several comma separated targets for one --target option, as well as
several --target options. At least one is required.
--filter filterspec[,filterspec]...]] [[--filter ...] ... ]
Specify filters to select files. A filterspec consist of three
fields: filter name, operator and value. You can specify several
comma separated filters for one --filter option, as well as several
--filter options. Defaults to all files if no filter is defined.
List of filters available:
Filter Name Valid Operators Valid Value(s)
----------- --------------- --------------
NAME match a regular expression
SIZE eq, ne, gt, lt, ge, le file size in bytes
AGE eq, ne, gt, lt, ge, le file age (see below)
check_file uses perl module Time::ParseDate for parsing of the file
age. A short sample of supported formats is
Dow, dd Mon yy
Dow, dd Mon yyyy
Dow, dd Mon
dd Mon yy
count \"days\"
count \"weeks\"
count \"months\"
count \"years\"
hh:mm:ss[.ddd]
hh:mm
hh:mm[AP]M
hh[AP]M
count \"minutes\"
count \"seconds\"
count \"hours\"
\"+\" count units
See the Time::ParseDate documentation for a complete list of
supported formats.
--delete
Delete selected files. Optional.
--warning threshold
Return WARNING if the number of files to consider is more than
threshold. Optional.
--critical threshold
Return CRITICAL if the number of files to consider is more than
threshold. Optional.
--rootonly
Limit file search to the top level of targets. No recursive
traversal of directories.
--compare operator
Specify the type of comparison operator for threshold checks.
Optional. Available values are:
'eq' equal to
'ne' not equal
'gt' greater than (default!)
'ge' greater or equal
'lt' less than
'le' less or equal
--verbose
Increases output verbosity for debugging.
--help
Produces a help message.
";
}
##### ExitProgram #####
sub ExitProgram
{
my ($exitcode, $message) = @_;
my $lcomp = "FILE";
print "$lcomp $status_text{$exitcode} - $message";
exit ($exitcode);
}
__END__
=head1 NAME
B<check_file> - Nagios NRPE plugin for file check
=head1 SYNOPSIS
B<check_file> B<--target> I<file/directory>[,I<file/directory>]...]] [[--target ...] ... ] B<--filter> I<filterspec>[,I<filterspec>]...]] [[--filter ...] ... ] [B<--delete>] [B<--warning> I<threshold>] [B<--critical> I<threshold>] [B<--rootonly>] [B<--compare> I<operator>] [B<--verbose>] [B<--help>]
=head1 DESCRIPTION
B<check_file> is a Nagios NRPE plugin for checking simple files or files in directories by using various types of filters like file count, size, age or name match.
=head1 OPTIONS
=over 4
=item B<--target> I<file/directory>[,I<file/directory>]...]] [[--target ...] ... ]
This option specifies targets to check. A target can be a simple file or a recursive list of files in a directory. You can specify several comma separated targets for one --target option, as well as several --target options. At least one is required.
=item B<--filter> I<filterspec>[,I<filterspec>]...]] [[--filter ...] ... ]
Specify filters to select files. A filterspec consist of three fields: filter name, operator and value. You can specify several comma separated filters for one --filter option, as well as several --filter options. Defaults to all files if no filter is defined. List of filters available:
Filter Name Valid Operators Valid Value(s)
----------- --------------- --------------
NAME match a regular expression
SIZE eq, ne, gt, lt, ge, le file size in bytes
AGE eq, ne, gt, lt, ge, le file age (see below)
check_file uses perl module B<Time::ParseDate> for parsing of the file age. A short sample of supported formats is
Dow, dd Mon yy
Dow, dd Mon yyyy
Dow, dd Mon
dd Mon yy
count "days"
count "weeks"
count "months"
count "years"
hh:mm:ss[.ddd]
hh:mm
hh:mm[AP]M
hh[AP]M
count "minutes"
count "seconds"
count "hours"
"+" count units
See the Time::ParseDate documentation for a complete list of supported formats.
=item B<--delete>
Delete selected files. Optional.
=item B<--warning> I<threshold>
Return WARNING if the number of files to consider is more than I<threshold>. Optional.
=item B<--critical> I<threshold>
Return CRITICAL if the number of files to consider is more than I<threshold>. Optional.
=item B<--rootonly>
Limit file search to the top level of targets. No recursive traversal of directories.
=item B<--compare> I<operator>
Specify the type of comparison operator for threshold checks. Optional. Available values are:
'eq' equal to
'ne' not equal
'gt' greater than (default!)
'ge' greater or equal
'lt' less than
'le' less or equal
=item B<--verbose>
Increases output verbosity for debugging.
=item B<--help>
Produces a help message.
=back
=head1 EXAMPLES
check_file.exe --target c:\temp --warn 100 --critical 250
Counts all files in the directory I<c:\temp>. Returns WARNING for more than 100 files or CRITICAL for more than 250 files.
check_file.exe -t c:\backup\db1,c:\backup\db2 --filter "age ge -24 hours" --critical 0
Returns CRITICAL if at least one of the files I<c:\backup\db1> and I<c:\backup\db2> is 24 hours old.
check_file.exe --target "c:\logfiles" --filter "size gt 10485760","age lt -15 minutes" --filter "name match \.log$" --delete --warning 10 --critical 50
Counts and deletes files with B<.log> extension, which are modified within last 15 minutes AND are larger than 10 MB. Returns WARNING if there are more than 10 files meeting the criteria, CRITICAL for more than 50 files.
=head1 EXIT VALUES
0 OK
1 WARNING
2 CRITICAL
3 UNKNOWN
=head1 AUTHOR
Tevfik Karagulle L<http://www.itefix.no>
=head1 SEE ALSO
=over 4
=item Nagios web site L<http://www.nagios.org>
=item Nagios NRPE documentation L<http://nagios.sourceforge.net/docs/nrpe/NRPE.pdf>
=item Regular Expressions L<http://en.wikipedia.org/wiki/Regular_expression>
=item Perl module Time::ParseDate L<http://search.cpan.org/~muir/Time-modules-2006.0814/lib/Time/ParseDate.pm>
=back
=head1 COPYRIGHT
This program is distributed under the Artistic License. L<http://www.opensource.org/licenses/artistic-license.php>
=head1 VERSION
Version 1.4, April 2009
=head1 CHANGELOG
=over 4
=item changes from 1.3
- check for non-existing targets (credits -ebo-)
- bugfix - "Can't call method "mtime" (credits -ebo-)
=item changes from 1.2
- use Time::ParseDate for more flexible file age parsing
- Bug fix - Don't treat directories as files as well
=item changes from 1.1
- Complete redesign of filter option. Options size and age are implemented as filters.
- Option --rootonly
- better performance
- Bug fix! Drop subdirectories from counting.
=item changes from 1.0
- Add options --filter and --delete. More verbose output.
=back
=cut