| 1 |
package Core::FileCount; |
|---|
| 2 |
|
|---|
| 3 |
use strict; |
|---|
| 4 |
use warnings; |
|---|
| 5 |
|
|---|
| 6 |
use base 'Resmon::Module'; |
|---|
| 7 |
|
|---|
| 8 |
use Resmon::ExtComm qw(run_command cache_command); |
|---|
| 9 |
|
|---|
| 10 |
=pod |
|---|
| 11 |
|
|---|
| 12 |
=head1 NAME |
|---|
| 13 |
|
|---|
| 14 |
Core::FileCount - count files matching specified criteria |
|---|
| 15 |
|
|---|
| 16 |
=head1 SYNOPSIS |
|---|
| 17 |
|
|---|
| 18 |
Core::FileCount { |
|---|
| 19 |
/path/to/directory: noop |
|---|
| 20 |
} |
|---|
| 21 |
|
|---|
| 22 |
Core::FileCount { |
|---|
| 23 |
/var/log : max_age => 86400, max_size => 1048576 |
|---|
| 24 |
} |
|---|
| 25 |
|
|---|
| 26 |
=head1 DESCRIPTION |
|---|
| 27 |
|
|---|
| 28 |
This module will return the number of files in a directory that match |
|---|
| 29 |
specified criteria. For example, the module can be configured to return how |
|---|
| 30 |
many files are over 1MB in size, or were modified more than 2 days ago. |
|---|
| 31 |
|
|---|
| 32 |
If no filter criteria are specified, then the module will simply return a |
|---|
| 33 |
count of all files in the directory. |
|---|
| 34 |
|
|---|
| 35 |
=head1 CONFIGURATION |
|---|
| 36 |
|
|---|
| 37 |
=over |
|---|
| 38 |
|
|---|
| 39 |
=item check_name |
|---|
| 40 |
|
|---|
| 41 |
The check name specified which directory to look for files in. |
|---|
| 42 |
|
|---|
| 43 |
=item real_files |
|---|
| 44 |
|
|---|
| 45 |
Optional. Should only real files (as determined by perl's '-f' test) be |
|---|
| 46 |
considered? 1 for yes, 0 or absent for no. |
|---|
| 47 |
|
|---|
| 48 |
=item filename |
|---|
| 49 |
|
|---|
| 50 |
Optional. A regular expression to match filenames on. A file is only included |
|---|
| 51 |
in the count if the filename (not including any pathname) matches the pattern. |
|---|
| 52 |
|
|---|
| 53 |
=item min_size, max_size |
|---|
| 54 |
|
|---|
| 55 |
Optional. Limit the file count to files that have a minimum or maximum size as |
|---|
| 56 |
specified. The size is in bytes. |
|---|
| 57 |
|
|---|
| 58 |
=item min_modified, max_modified |
|---|
| 59 |
|
|---|
| 60 |
Optional. Limit the file count to files that were modified at least |
|---|
| 61 |
(min_modified) or at most (max_modified) N seconds ago. |
|---|
| 62 |
|
|---|
| 63 |
=item min_accessed, max_accessed |
|---|
| 64 |
|
|---|
| 65 |
Optional. Limit the file count to files that were accessed at least |
|---|
| 66 |
(min_accessed) or at most (max_accessed) N seconds ago. |
|---|
| 67 |
|
|---|
| 68 |
=item min_changed, max_changed |
|---|
| 69 |
|
|---|
| 70 |
Optional. Limit the file count to files that were changed (uses a file's |
|---|
| 71 |
ctime) at least (min_changed) or at most (max_changed) N seconds ago. |
|---|
| 72 |
|
|---|
| 73 |
=item uid, gid |
|---|
| 74 |
|
|---|
| 75 |
Optional. Limit the file count to files that are owned by the specified user |
|---|
| 76 |
or group. |
|---|
| 77 |
|
|---|
| 78 |
=item not_uid, not_gid |
|---|
| 79 |
|
|---|
| 80 |
Optional. Simile to uid, gid, but only count files that are not owned by the |
|---|
| 81 |
specified user or group. |
|---|
| 82 |
|
|---|
| 83 |
=item permissions |
|---|
| 84 |
|
|---|
| 85 |
Optional. Limit the file count to files that have the specified permissions. |
|---|
| 86 |
This is a regular expression, so you can do things like "0[67][45]0" as well |
|---|
| 87 |
as a simple string: "0755". |
|---|
| 88 |
|
|---|
| 89 |
=back |
|---|
| 90 |
|
|---|
| 91 |
=head1 METRICS |
|---|
| 92 |
|
|---|
| 93 |
=over |
|---|
| 94 |
|
|---|
| 95 |
=item count |
|---|
| 96 |
|
|---|
| 97 |
The count of files matching the criteria. |
|---|
| 98 |
|
|---|
| 99 |
=back |
|---|
| 100 |
|
|---|
| 101 |
=cut |
|---|
| 102 |
|
|---|
| 103 |
sub handler { |
|---|
| 104 |
my $self = shift; |
|---|
| 105 |
my $config = $self->{config}; # All configuration is in here |
|---|
| 106 |
my $dirname = $self->{check_name}; # The check name is in here |
|---|
| 107 |
|
|---|
| 108 |
opendir(my $dir, $dirname) || die "Unable to access directory $dirname\n"; |
|---|
| 109 |
my $now = time; |
|---|
| 110 |
my $count = 0; |
|---|
| 111 |
while (my $file = readdir($dir)) { |
|---|
| 112 |
# Make sure we're actually counting files if desired |
|---|
| 113 |
next if ($config->{real_files} && ! -f "$dirname/$file"); |
|---|
| 114 |
# Ignore . and .. |
|---|
| 115 |
next if ($file =~ /^\.\.?$/); |
|---|
| 116 |
# Filename pattern |
|---|
| 117 |
next if ($config->{filename} && $file !~ /$config->{filename}/); |
|---|
| 118 |
my @fileinfo = stat "$dirname/$file"; |
|---|
| 119 |
# Access time |
|---|
| 120 |
next if ($config->{min_accessed} && |
|---|
| 121 |
($now - $fileinfo[8]) < $config->{min_accessed}); |
|---|
| 122 |
next if ($config->{max_accessed} && |
|---|
| 123 |
($now - $fileinfo[8]) > $config->{max_accessed}); |
|---|
| 124 |
# Modification time |
|---|
| 125 |
next if ($config->{min_modified} && |
|---|
| 126 |
($now - $fileinfo[9]) < $config->{min_modified}); |
|---|
| 127 |
next if ($config->{max_modified} && |
|---|
| 128 |
($now - $fileinfo[9]) > $config->{max_modified}); |
|---|
| 129 |
# Change time |
|---|
| 130 |
next if ($config->{min_changed} && |
|---|
| 131 |
($now - $fileinfo[10]) < $config->{min_changed}); |
|---|
| 132 |
next if ($config->{max_changed} && |
|---|
| 133 |
($now - $fileinfo[10]) > $config->{max_changed}); |
|---|
| 134 |
# File size |
|---|
| 135 |
next if ($config->{min_size} && $fileinfo[7] < $config->{min_size}); |
|---|
| 136 |
next if ($config->{max_size} && $fileinfo[7] > $config->{max_size}); |
|---|
| 137 |
# UID/GID |
|---|
| 138 |
next if ($config->{uid} && $fileinfo[4] ne $config->{uid}); |
|---|
| 139 |
next if ($config->{gid} && $fileinfo[5] ne $config->{gid}); |
|---|
| 140 |
# UID/GID inverse |
|---|
| 141 |
next if ($config->{not_uid} && $fileinfo[4] eq $config->{not_uid}); |
|---|
| 142 |
next if ($config->{not_gid} && $fileinfo[5] eq $config->{not_gid}); |
|---|
| 143 |
# Permissions |
|---|
| 144 |
next if ($config->{permissions} && |
|---|
| 145 |
sprintf("%04o", $fileinfo[2] & 07777) !~ /$config->{permissions}/); |
|---|
| 146 |
# We passed all filters, yay! |
|---|
| 147 |
$count++; |
|---|
| 148 |
} |
|---|
| 149 |
closedir($dir); |
|---|
| 150 |
|
|---|
| 151 |
return { |
|---|
| 152 |
"count" => [$count, "i"], |
|---|
| 153 |
}; |
|---|
| 154 |
}; |
|---|
| 155 |
|
|---|
| 156 |
1; |
|---|