40 |
40 |
41 my $ME = basename $0; |
41 my $ME = basename $0; |
42 my $VERSION = "2.5"; |
42 my $VERSION = "2.5"; |
43 |
43 |
44 my %opt = ( |
44 my %opt = ( |
45 binary => "/usr/bin/rsnapshot", |
45 binary => "/usr/bin/rsnapshot", |
46 maxage => undef, |
46 maxage => undef, |
47 date => "yesterday" |
47 date => "yesterday" |
48 ); |
48 ); |
49 |
49 |
50 MAIN: { |
50 MAIN: { |
51 Getopt::Long::Configure('bundling'); |
51 Getopt::Long::Configure('bundling'); |
52 GetOptions( |
52 GetOptions( |
53 "b|binary=s" => \$opt{binary}, |
53 "b|binary=s" => \$opt{binary}, |
54 "s|maxage=i" => \$opt{maxage}, |
54 "s|maxage=i" => \$opt{maxage}, |
55 "d|date=s" => \$opt{date}, |
55 "d|date=s" => \$opt{date}, |
56 "h|help" => sub { pod2usage( -verbose => 1, -exitval => $ERRORS{OK} ) }, |
56 "h|help" => sub { pod2usage(-verbose => 1, -exitval => $ERRORS{OK}) }, |
57 "m|man" => sub { pod2usage( -verbose => 2, -exitval => $ERRORS{OK} ) }, |
57 "m|man" => sub { pod2usage(-verbose => 2, -exitval => $ERRORS{OK}) }, |
58 "V|version" => sub { version( $ME, $VERSION ); exit $ERRORS{OK}; } |
58 "V|version" => sub { version($ME, $VERSION); exit $ERRORS{OK}; } |
59 ) or pod2usage( -verbose => 1, -exitval => $ERRORS{CRITICAL} ); |
59 ) or pod2usage(-verbose => 1, -exitval => $ERRORS{CRITICAL}); |
60 |
60 |
61 my @logfiles = @ARGV ? @ARGV : glob '/var/log/rsnapshot.log{,.1.gz}'; |
61 my @logfiles = @ARGV ? @ARGV : glob '/var/log/rsnapshot.log{,.1.gz}'; |
62 |
62 |
63 my $date = UnixDate( ParseDate( $opt{date} ), "%d/%b/%Y" ); |
63 my $date = UnixDate(ParseDate($opt{date}), "%d/%b/%Y"); |
64 unless ($date) { |
64 unless ($date) { |
65 print "RSNAPSHOT CRITICAL: can't parse date [$opt{date}]\n"; |
65 print "RSNAPSHOT CRITICAL: can't parse date [$opt{date}]\n"; |
66 exit $ERRORS{CRITICAL}; |
66 exit $ERRORS{CRITICAL}; |
67 } |
67 } |
68 |
68 |
69 my $maxage = defined $opt{maxage} |
69 my $maxage = |
70 ? time - $opt{maxage} |
70 defined $opt{maxage} |
71 : UnixDate( ParseDate( $opt{date} ), "%s" ); |
71 ? time - $opt{maxage} |
|
72 : UnixDate(ParseDate($opt{date}), "%s"); |
72 |
73 |
73 unless (defined $maxage) { |
74 unless (defined $maxage) { |
74 print "RSNAPSHOT CRITICAL: undefined log file max age; this should not happen\n"; |
|
75 exit $ERRORS{CRITICAL}; |
|
76 } |
|
77 |
|
78 unless ( -x $opt{binary} ) { |
|
79 print |
75 print |
80 "RSNAPSHOT CRITICAL: binary '$opt{binary}' - not found or not executable\n"; |
76 "RSNAPSHOT CRITICAL: undefined log file max age; this should not happen\n"; |
81 exit $ERRORS{CRITICAL}; |
77 exit $ERRORS{CRITICAL}; |
82 } |
78 } |
83 |
79 |
84 my $status = get_status( [@logfiles], $date, $maxage ); |
80 unless (-x $opt{binary}) { |
|
81 print |
|
82 "RSNAPSHOT CRITICAL: binary '$opt{binary}' - not found or not executable\n"; |
|
83 exit $ERRORS{CRITICAL}; |
|
84 } |
|
85 |
|
86 my $status = get_status([@logfiles], $date, $maxage); |
85 report($status); |
87 report($status); |
86 } |
88 } |
87 |
89 |
88 sub get_status($$$) { |
90 sub get_status($$$) { |
89 |
91 |
90 my ( $logfiles, $date, $maxage) = @_; |
92 my ($logfiles, $date, $maxage) = @_; |
91 my ( $error, $found_in_file ); |
93 my ($error, $found_in_file); |
92 |
94 |
93 for my $logfile (@{$logfiles}) { |
95 for my $logfile (@{$logfiles}) { |
94 |
96 |
95 unless ( -e $logfile ) { |
97 unless (-e $logfile) { |
96 print "RSNAPSHOT CRITICAL: logfile '$logfile' - don't exists\n"; |
98 print "RSNAPSHOT CRITICAL: logfile '$logfile' - don't exists\n"; |
97 exit $ERRORS{CRITICAL}; |
99 exit $ERRORS{CRITICAL}; |
98 } |
100 } |
99 |
101 |
100 if ( -z $logfile ) { |
102 if (-z $logfile) { |
101 print "RSNAPSHOT WARNING: logfile $logfile - has zero size\n"; |
103 print "RSNAPSHOT WARNING: logfile $logfile - has zero size\n"; |
102 exit $ERRORS{WARNING}; |
104 exit $ERRORS{WARNING}; |
103 } |
105 } |
104 |
106 |
105 next if (stat $logfile)[9] < $maxage; |
107 next if (stat $logfile)[9] < $maxage; |
106 |
108 |
107 |
109 if ($logfile =~ /\.gz$/) { |
108 if ( $logfile =~ /\.gz$/ ) { |
110 my $gz = gzopen($logfile, "rb") |
109 my $gz = gzopen( $logfile, "rb" ) |
111 or print "RSNAPSHOT CRITICAL: Cannot open $logfile: $gzerrno\n" |
110 or print "RSNAPSHOT CRITICAL: Cannot open $logfile: $gzerrno\n" |
112 and exit $ERRORS{CRITICAL}; |
111 and exit $ERRORS{CRITICAL}; |
113 while ($gz->gzreadline($_) > 0) { |
112 while ( $gz->gzreadline($_) > 0 ) { |
114 next unless (/^\[$date/); |
113 next unless (/^\[$date/); |
115 if (/^\[$date:.*ERROR/) { |
114 if (/^\[$date:.*ERROR/) { |
116 $error = $_; |
115 $error = $_; |
117 last; |
116 last; |
118 } |
|
119 $found_in_file = $logfile; |
117 } |
120 } |
118 $found_in_file = $logfile; |
121 print "RSNAPSHOT CRITICAL: Error reading from $logfile: $gzerrno\n" |
|
122 and exit $ERRORS{CRITICAL} |
|
123 if $gzerrno != Z_STREAM_END; |
|
124 $gz->gzclose(); |
|
125 } else { |
|
126 open(FH, $logfile) |
|
127 or print "RSNAPSHOT CRITICAL: $logfile - $!\n" |
|
128 and exit $ERRORS{CRITICAL}; |
|
129 while (<FH>) { |
|
130 next unless (/^\[$date/); |
|
131 if (/^\[$date:.*ERROR/) { |
|
132 $error = $_; |
|
133 last; |
|
134 } |
|
135 $found_in_file = $logfile; |
|
136 } |
|
137 close(FH); |
119 } |
138 } |
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 } |
|
125 else { |
|
126 open( FH, $logfile ) |
|
127 or print "RSNAPSHOT CRITICAL: $logfile - $!\n" |
|
128 and exit $ERRORS{CRITICAL}; |
|
129 while (<FH>) { |
|
130 next unless (/^\[$date/); |
|
131 if (/^\[$date:.*ERROR/) { |
|
132 $error = $_; |
|
133 last; |
|
134 } |
|
135 $found_in_file = $logfile; |
|
136 } |
|
137 close(FH); |
|
138 } |
|
139 |
139 |
140 last if $found_in_file; |
140 last if $found_in_file; |
141 |
141 |
142 } |
142 } |
143 |
143 |