Skip to content

Commit

Permalink
add check_folder plugin
Browse files Browse the repository at this point in the history
(cherry picked from commit b82aa53)
  • Loading branch information
sni committed Nov 30, 2020
1 parent 7a8856c commit 29a324e
Showing 1 changed file with 251 additions and 0 deletions.
251 changes: 251 additions & 0 deletions packages/check_plugins/single_files/check_folder
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
#!/usr/bin/env perl

use warnings;
use strict;
use Monitoring::Plugin;
use Getopt::Long;

Getopt::Long::Configure('pass_through');

my $mp = Monitoring::Plugin->new(
shortname => "FOLDER",
usage => "Usage: %s [options] <folder>\n\nThis plugin checks files in given folder for size, number of files and file age.",
version => "v0.01",
extra => "\n"
."All thresholds use monitoring plugins format, ex.: -c @10:20 .\n"
."See https://www.monitoring-plugins.org/doc/guidelines.html#THRESHOLDFORMAT for the threshold format.\n"
."\n"
."Example:\n"
."check folder to not contain more than 10 (warning) or 20 (critical) files and size must not exceed 5MB (warning) or 10GB (critical):\n"
." $0 -c 10 -C 20 /folder\n"
."\n"
."check folders file size must not exceed 5MB (warning) or 10GB (critical):\n"
." $0 -s 5M -S 10G /folder\n"
."\n"
."check only file matching glob pattern *.log:\n"
." $0 -p '*.log' /folder\n"
."\n"
."check files matching glob pattern *.log to be not older than 10minutes:\n"
." $0 -p '*.log'-a 10m /folder\n"
."\n"
."verify there are no more than 10 files and none older than 5minutes in our spool folder\n"
." $0 /omd/sites/demo/var/pnp4nagios/spool/ -C 0:10 -A 5m\n",
);

$mp->add_arg(
spec => 'pattern|p=s',
help => '-p <pattern>, use pattern instead of all files of folder.',
);
$mp->add_arg(
spec => 'recursive|r',
help => '-r recurse into subfolder.',
);
$mp->add_arg(
spec => 'maxerrors|m=i',
help => '-m <num>, maximum number of errors to show. Defaults to 20.',
default => 20,
);

$mp->add_arg(
spec => 'c=s',
help => '-c <range>, count warning threshold',
);
$mp->add_arg(
spec => 'C=s',
help => '-C <range>, count critical threshold, defaults to 1: and will alert if there are no files.',
default => '1:',
);

$mp->add_arg(
spec => 's=s',
help => '-s <range>, total size warning threshold',
);
$mp->add_arg(
spec => 'S=s',
help => '-S <range>, total size critical threshold',
);

$mp->add_arg(
spec => 'a=s',
help => '-a <range>, file age warning threshold in seconds',
);
$mp->add_arg(
spec => 'A=s',
help => '-A <range>, file age critical threshold in seconds',
);

$mp->getopts();
my @folder = @ARGV;
alarm($mp->opts->timeout);

$mp->plugin_exit(UNKNOWN, "folder argument is required. See --help for more information." ) if scalar @folder == 0;

if(@folder == 1) {
$mp->shortname($folder[0]);
}

for my $f (@folder) {
$f =~ s|/$||gmx;
if(!-d $f."/.") {
$mp->plugin_exit(UNKNOWN, $f.": ".$! );
}
my $files = _get_files($f, $mp->opts->{'pattern'}, $mp->opts->{'recursive'});
my $count = scalar @{$files};
$mp->add_perfdata(
label => $f.'::count',
value => $count,
uom => "",
threshold => $mp->set_thresholds(warning => $mp->opts->{'c'}, critical => $mp->opts->{'C'}),
);
my $code = $mp->check_threshold(
check => $count,
warning => $mp->opts->{'c'},
critical => $mp->opts->{'C'},
);
$mp->add_message($code, sprintf("number of files: %d", $count)) if($count > 1 || $count == 0);

$mp->opts->{'s'} =~ s/(\d+)([kmg])/&_expand_size($1, $2)/gemxi if $mp->opts->{'s'};
$mp->opts->{'S'} =~ s/(\d+)([kmg])/&_expand_size($1, $2)/gemxi if $mp->opts->{'S'};
$mp->opts->{'a'} =~ s/(\d+)([smhd])/&_expand_time($1, $2)/gemxi if $mp->opts->{'a'};
$mp->opts->{'A'} =~ s/(\d+)([smhd])/&_expand_time($1, $2)/gemxi if $mp->opts->{'A'};

if($mp->opts->{'s'} || $mp->opts->{'S'} || $mp->opts->{'a'} || $mp->opts->{'A'}) {
my $totalsize;
for my $f (@{$files}) {
my @stat = stat($f);
$totalsize += $stat[7];

if($mp->opts->{'a'} || $mp->opts->{'A'}) {
my $ago = time() - $stat[9];
my $code = $mp->check_threshold(
check => $ago,
warning => $mp->opts->{'a'},
critical => $mp->opts->{'A'},
);
$mp->add_message($code, sprintf("%s last modified %s ago (%s)", $f, _format_ago($ago), scalar localtime $stat[9])) if($code > 0 || $count == 1);
}
}
next unless ($mp->opts->{'s'} || $mp->opts->{'S'});
$mp->add_perfdata(
label => $f.'::size',
value => $totalsize,
uom => "B",
threshold => $mp->set_thresholds(warning => $mp->opts->{'s'}, critical => $mp->opts->{'S'}),
);
my $code = $mp->check_threshold(
check => $totalsize,
warning => $mp->opts->{'s'},
critical => $mp->opts->{'S'},
);
my $prefix = "";
my $totalsizenum = $totalsize;
if($totalsizenum > 1e9) {
$totalsizenum = $totalsizenum / 1024 ** 3;
$prefix = "Gi";
}
elsif($totalsizenum > 1e6) {
$totalsizenum = $totalsizenum / 1024 ** 2;
$prefix = "Mi";
}
elsif($totalsizenum > 1e3) {
$totalsizenum = $totalsizenum / 1024;
$prefix = "Ki";
}
$mp->add_message($code, sprintf("total size of files: %d%sB", $totalsizenum, $prefix));
}

if($mp->opts->{'a'} || $mp->opts->{'A'}) {
for my $f (@{$files}) {
my @stat = stat($f);
}
}
}

my($code, $msg) = $mp->check_messages(join => "\n - ");
my @lines = split/\n/mx, $msg;
my $maxerrors = $mp->opts->{'maxerrors'} // 20;
if(scalar @lines > $maxerrors) {
my $num = scalar @lines;
@lines = splice(@lines, 0, $maxerrors);
$msg = join("\n", @lines);
$msg .= sprintf("\n... %d errors in total.", $num);
}
$mp->plugin_exit($code, $msg);


########################################################################################################################
sub _get_files {
my($dir, $pattern, $recursive) = @_;

my @files;
if($pattern) {
for my $file (glob($dir.'/'.$pattern)) {
push @files, $file;
}
return(\@files) unless $recursive;
}

opendir(my $dh, $dir) || $mp->plugin_die(sprintf("cannot open directory %s: %s", $dir, $!));
while(readdir $dh) {
my $file = $_;
next if $file eq '.' || $file eq '..';
if(-d "$dir/$file") {
if($recursive) {
my $subfiles = _get_files("$dir/$file", $pattern, $recursive);
push @files, @{$subfiles};
}
next;
}
next if $pattern;
push @files, "$dir/$file";

}
closedir $dh;
return(\@files);
}

########################################################################################################################
sub _expand_size {
my($num, $unit) = @_;
$unit = lc($unit);
if($unit eq 'k') { return $num * 1024; }
if($unit eq 'm') { return $num * 1024 ** 2; }
if($unit eq 'g') { return $num * 1024 ** 3; }
$mp->plugin_die(sprintf("unknown unit %s", $unit));
}

########################################################################################################################
sub _expand_time {
my($num, $unit) = @_;
$unit = lc($unit);
if($unit eq 's') { return $num; }
if($unit eq 'm') { return $num * 60; }
if($unit eq 'h') { return $num * 3600; }
if($unit eq 'd') { return $num * 86400; }
$mp->plugin_die(sprintf("unknown unit %s", $unit));
}

########################################################################################################################
sub _format_ago {
my($seconds) = @_;
if($seconds > 86400*7) {
my $days = int($seconds / 86400);
return($days."d");
}
if($seconds > 86400) {
my $days = int($seconds / 86400);
my $hours = int($seconds%86400 / 3600);
return($days."d".$hours."h");
}
if($seconds > 3600) {
my $hours = int($seconds / 3600);
my $min = int($seconds%3600 / 60);
return($hours."h".$min."m");
}
if($seconds > 60) {
my $min = int($seconds / 60);
my $sec = int($seconds%60);
return($min."m".$sec."s");
}
return($seconds."s");
}

0 comments on commit 29a324e

Please sign in to comment.