check_rsnapshot.pl
changeset 39 2bc5b5bc8130
parent 38 e4301bf7ebf5
equal deleted inserted replaced
38:e4301bf7ebf5 39:2bc5b5bc8130
     1 #! /usr/bin/perl -w
       
     2 
       
     3 #    Copyright (C) 2011-2013  Christian Arnold
       
     4 #    Copyright (C) 2013-2018  Matthias Förste
       
     5 #
       
     6 #    This program is free software: you can redistribute it and/or modify
       
     7 #    it under the terms of the GNU General Public License as published by
       
     8 #    the Free Software Foundation, either version 3 of the License, or
       
     9 #    (at your option) any later version.
       
    10 #
       
    11 #    This program is distributed in the hope that it will be useful,
       
    12 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    13 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    14 #    GNU General Public License for more details.
       
    15 #
       
    16 #    You should have received a copy of the GNU General Public License
       
    17 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
       
    18 #
       
    19 #    Christian Arnold <arnold@schlittermann.de>, Matthias Förste <foerste@schlittermann.de>
       
    20 
       
    21 =encoding utf8
       
    22 =cut
       
    23 
       
    24 use strict;
       
    25 use File::Basename;
       
    26 use Getopt::Long;
       
    27 use Compress::Zlib;
       
    28 use Date::Manip;
       
    29 use Pod::Usage;
       
    30 use if $ENV{DEBUG} => "Smart::Comments";
       
    31 
       
    32 my %ERRORS = (
       
    33     OK        => 0,
       
    34     WARNING   => 1,
       
    35     CRITICAL  => 2,
       
    36     UNKNOWN   => 3,
       
    37     DEPENDENT => 4
       
    38 );
       
    39 
       
    40 sub get_status($$$);
       
    41 sub report($);
       
    42 sub version($$);
       
    43 
       
    44 my $ME      = basename $0;
       
    45 my $VERSION = "2.10.1";
       
    46 
       
    47 my %opt = (
       
    48     binary => "/usr/bin/rsnapshot",
       
    49     maxage => undef,
       
    50     date   => "today"
       
    51 );
       
    52 
       
    53 MAIN: {
       
    54     Getopt::Long::Configure('bundling');
       
    55     GetOptions(
       
    56         "b|binary=s" => \$opt{binary},
       
    57         "s|maxage=i" => \$opt{maxage},
       
    58         "d|date=s"   => \$opt{date},
       
    59         "h|help" => sub { pod2usage(-verbose => 1, -exitval => $ERRORS{OK}) },
       
    60         "m|man" => sub { pod2usage(-verbose => 2, -exitval => $ERRORS{OK}) },
       
    61         "V|version" => sub { version($ME, $VERSION); exit $ERRORS{OK}; }
       
    62     ) or pod2usage(-verbose => 1, -exitval => $ERRORS{CRITICAL});
       
    63 
       
    64     my @logfiles = @ARGV ? @ARGV : glob '/var/log/rsnapshot.log{,.1.gz}';
       
    65 
       
    66     # older versions log the date as %d/%b/%Y
       
    67     my $date = UnixDate(ParseDate($opt{date}), "(%d/%b/%Y|%Y-%m-%d)");
       
    68     unless ($date) {
       
    69         print "RSNAPSHOT CRITICAL: can't parse date [$opt{date}]\n";
       
    70         exit $ERRORS{CRITICAL};
       
    71     }
       
    72 
       
    73     my $maxage =
       
    74       defined $opt{maxage}
       
    75       ? time - $opt{maxage}
       
    76       : UnixDate(ParseDate($opt{date}), "%s");
       
    77 
       
    78     unless (defined $maxage) {
       
    79         print
       
    80           "RSNAPSHOT CRITICAL: undefined log file max age; this should not happen\n";
       
    81         exit $ERRORS{CRITICAL};
       
    82     }
       
    83 
       
    84     unless (-x $opt{binary}) {
       
    85         print
       
    86           "RSNAPSHOT CRITICAL: binary '$opt{binary}' - not found or not executable\n";
       
    87         exit $ERRORS{CRITICAL};
       
    88     }
       
    89 
       
    90     my $status = get_status([@logfiles], $date, $maxage);
       
    91     report($status);
       
    92 }
       
    93 
       
    94 sub get_status($$$) {
       
    95 
       
    96     my ($logfiles, $date, $maxage) = @_;
       
    97     my ($error, $found_in_file);
       
    98 
       
    99     for my $logfile (@{$logfiles}) {
       
   100 
       
   101         unless (-e $logfile) {
       
   102             print "RSNAPSHOT CRITICAL: logfile '$logfile' - don't exists\n";
       
   103             exit $ERRORS{CRITICAL};
       
   104         }
       
   105 
       
   106         next if (stat $logfile)[9] < $maxage;
       
   107 
       
   108         if ($logfile =~ /\.gz$/) {
       
   109             my $gz = gzopen($logfile, "rb")
       
   110               or print "RSNAPSHOT CRITICAL: Cannot open $logfile: $gzerrno\n"
       
   111               and exit $ERRORS{CRITICAL};
       
   112             while ($gz->gzreadline($_) > 0) {
       
   113                 next unless (/^\[$date/);
       
   114                 $found_in_file = $logfile;
       
   115                 if (/^\[$date:.*ERROR/) {
       
   116                     $error = $_;
       
   117                     last;
       
   118                 }
       
   119             }
       
   120             print "RSNAPSHOT CRITICAL: Error reading from $logfile: $gzerrno\n"
       
   121               and exit $ERRORS{CRITICAL}
       
   122               if $gzerrno != Z_STREAM_END;
       
   123             $gz->gzclose();
       
   124         } else {
       
   125             open(FH, $logfile)
       
   126               or print "RSNAPSHOT CRITICAL: $logfile - $!\n"
       
   127               and exit $ERRORS{CRITICAL};
       
   128             while (<FH>) {
       
   129                 next unless (/^\[$date/);
       
   130                 $found_in_file = $logfile;
       
   131                 if (/^\[$date:.*ERROR/) {
       
   132                     $error = $_;
       
   133                     last;
       
   134                 }
       
   135             }
       
   136             close(FH);
       
   137         }
       
   138 
       
   139         last if $found_in_file;
       
   140 
       
   141     }
       
   142 
       
   143     $error |= "can't find rsnapshot run from [$date]\n" unless ($found_in_file); 
       
   144 
       
   145     if ($error) {
       
   146         print "RSNAPSHOT CRITICAL: $error";
       
   147         exit $ERRORS{CRITICAL};
       
   148     } else {
       
   149         print "RSNAPSHOT OK: no errors in $found_in_file\n";
       
   150         exit $ERRORS{OK};
       
   151     }
       
   152 }
       
   153 
       
   154 sub version($$) {
       
   155     my $progname = shift;
       
   156     my $version  = shift;
       
   157 
       
   158     print <<_VERSION;
       
   159 $progname version $version
       
   160 Copyright (C) 2011-2013 by Christian Arnold and Schlittermann internet & unix
       
   161 support.
       
   162 
       
   163 Copyright (C) 2013-2018 by Matthias Förste and Schlittermann internet & unix support.
       
   164 
       
   165 $ME comes with ABSOLUTELY NO WARRANTY. This is free software,
       
   166 and you are welcome to redistribute it under certain conditions.
       
   167 See the GNU General Public Licence for details.
       
   168 _VERSION
       
   169 }
       
   170 
       
   171 =head1 NAME
       
   172 
       
   173 check_rsnapshot - nagios plugin to check for errors on rsnapshot logfile
       
   174 
       
   175 =head1 SYNOPSIS
       
   176 
       
   177 check_release [-b|--binary string]
       
   178               [-s|--maxage integer]
       
   179               [-d|--date string]
       
   180               [-h|--help]
       
   181               [-m|--man]
       
   182               [-V|--version]
       
   183               [logfile1 logfile2 ..]
       
   184 
       
   185 =head1 OPTIONS
       
   186 
       
   187 =over
       
   188 
       
   189 =item B<-b>|B<--binary> I<string>
       
   190 
       
   191 rsnapshot binary (default: /usr/bin/rsnapshot)
       
   192 
       
   193 =item B<-s>|B<--maxage> I<integer>
       
   194 
       
   195 Files modified more than B<--maxage> seconds ago will be silently ignored.
       
   196 (default: same as B<--date>)
       
   197 
       
   198 =item B<-d>|B<--date> I<string>
       
   199 
       
   200 Parse date for rsnapshot logfile. (default: today)
       
   201 
       
   202 Note: this defaulted to 'yesterday' earlier to avoid the situation that the
       
   203 check goes critical while rsnapshot is still running. I think the nagios check
       
   204 should either be scheduled later or the check should indeed check for the run
       
   205 from yesterday if a later schedule is not desirable for some reason in that
       
   206 case. But that should B<not> be the default. 
       
   207 
       
   208 =item B<-h>|B<--help>
       
   209 
       
   210 Print detailed help screen.
       
   211 
       
   212 =item B<-m>|B<--man>
       
   213 
       
   214 Print manual page.
       
   215 
       
   216 =item B<-V>|B<--version>
       
   217 
       
   218 Print version information.
       
   219 
       
   220 =back
       
   221 
       
   222 =head1 DESCRIPTION
       
   223 
       
   224 This plugin checks rsnapshot logfile for errors.
       
   225 
       
   226 =head1 EXAMPLES
       
   227 
       
   228 check_rsnapshot -s 172800 -d "2 days ago" /var/log/rsnapshot/rsnapshot.log
       
   229 
       
   230 =head1 VERSION
       
   231 
       
   232 This man page is current for version 2.8 of check_rsnapshot.
       
   233 
       
   234 =head1 AUTHORS
       
   235 
       
   236 2011-2013 Originally written by Christian Arnold L<arnold@schlittermann.de>.
       
   237 
       
   238 2013-2018 Maintained by Matthias Förste L<foerste@schlittermann.de>.
       
   239 
       
   240 =head1 COPYRIGHT
       
   241 
       
   242 Copyright (C) 2011-2013 by Christian Arnold and Schlittermann internet & unix
       
   243 support. Copyright (C) 2013-2018 by Matthias Förste and Schlittermann internet
       
   244 & unix support. This is free software, and you are welcome to redistribute it
       
   245 under certain conditions. See the GNU General Public Licence for details.
       
   246 
       
   247 =cut