[project @ peter@palfrader.org-20080414150120-wai760gfd2v4gr3o]
[mirror/dsa-nagios.git] / dsa-nagios-nrpe-config / dsa-check-dabackup
1 #!/usr/bin/perl -w
2
3 # Check the status of da-backup backups
4 # Copyright 2007 Stephen Gran <sgran@debian.org>
5 # Copyright 2008 Peter Palfrader
6 #
7 # Permission is hereby granted, free of charge, to any person obtaining
8 # a copy of this software and associated documentation files (the
9 # "Software"), to deal in the Software without restriction, including
10 # without limitation the rights to use, copy, modify, merge, publish,
11 # distribute, sublicense, and/or sell copies of the Software, and to
12 # permit persons to whom the Software is furnished to do so, subject to
13 # the following conditions:
14 #
15 # The above copyright notice and this permission notice shall be
16 # included in all copies or substantial portions of the Software.
17 #
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 use strict;
27 use warnings;
28 use English;
29 use Getopt::Long;
30 use Fcntl qw(:seek);
31
32 my $DABACKUP_CONF = '/etc/da-backup.conf';
33 my $MAX_AGE = 24*60*60;
34 my %CODE = (
35         'UNDEF'         => -1,
36         'OK'            => 0,
37         'WARNING'       => 1,
38         'CRITICAL'      => 2,
39         'UNKNOWN'       => 3
40 );
41 $SIG{__DIE__ } = sub() {
42         print shift;
43         exit $CODE{'UNKNOWN'};
44 };
45
46
47 my $EXITCODE = 'UNDEF';
48 my @MESSAGE = ();
49
50 sub problem($$) {
51         my ($code, $msg) = @_;
52         push @MESSAGE, $msg;
53         $EXITCODE = ($CODE{$code} > $CODE{$EXITCODE}) ? $code : $EXITCODE;
54 };
55
56
57 sub help($$) {
58         my ($exitcode, $fd) = @_;
59         version ($fd, 0);
60         print $fd "Usage: $PROGRAM_NAME --help\n";
61         print $fd "Usage: $PROGRAM_NAME";
62         exit $exitcode
63 };
64
65 my $params = {};
66
67 Getopt::Long::config('bundling');
68 if (!GetOptions (
69         'h|help'        =>  \$params->{'help'},
70         )) {
71         die ("$PROGRAM_NAME: Usage: $PROGRAM_NAME [-fwhv]\n");
72 };
73
74 help(0, *STDOUT) if $params->{'help'};
75 help(1, *STDERR) if scalar @ARGV > 0;
76
77
78 unless (-e $DABACKUP_CONF) {
79         if (-e '/etc/da-backup') {
80                 print "WARNING: No $DABACKUP_CONF, but we have /etc/da-backup/\n";
81                 exit $CODE{'WARNING'};
82         };
83         if (-e '/var/log/da-backup') {
84                 print "WARNING: No $DABACKUP_CONF, but we have /var/log/da-backup/\n";
85                 exit $CODE{'WARNING'};
86         };
87         print "OK: no backup configured\n";
88         exit $CODE{'OK'};
89 };
90
91 my $confdir;
92 my $logdir;
93
94 open (FH, "< $DABACKUP_CONF") or die ("Cannot open $DABACKUP_CONF: $!\n");
95 while (<FH>) {
96         if (/confdir=(.*)/) {
97                 $confdir = $1;
98         } elsif (/logdir=(.*)/) {
99                 $logdir = $1;
100         };
101 };
102
103 die ("No confdir found in $DABACKUP_CONF") unless defined $confdir;
104 die ("No logdir found in $DABACKUP_CONF") unless defined $logdir;
105
106 opendir(DIR, $confdir) or die ("Cannot opendir $confdir: $!\n");
107 my %conffiles = map {$_ => 1} grep { !/^\./ } readdir(DIR);
108 closedir(DIR);
109
110 opendir(DIR, $logdir) or die ("Cannot opendir $logdir: $!\n");
111 my %logfiles = map {$_ => 1} grep { !/^\./ && !/\.[0-9]+(\.gz)?$/} readdir(DIR);
112 closedir(DIR);
113
114 for my $f (keys %conffiles) {
115         unless (exists $logfiles{$f}) {
116                 problem('WARNING', "$f has no log");
117         }
118 }
119 for my $f (keys %logfiles) {
120         unless (exists $conffiles{$f}) {
121                 problem('WARNING', "log $f has no config");
122         }
123 }
124
125 FILE:
126 for my $f (keys %logfiles) {
127         my @stat = stat("$logdir/$f") or die ("Cannot stat $logdir/$f: $!\n");
128         my $age = time - $stat[10];
129         if ($age < 0) {
130                 problem('WARNING', "%f is from the future");
131                 next;
132         } elsif ($age > $MAX_AGE) {
133                 my $hage;
134
135                 if ($age > 48 * 3600) {
136                         $hage = sprintf("%d days", $age / 24 / 3600);
137                 } else {
138                         $hage = sprintf("%d hours", $age /  3600);
139                 };
140                 problem('WARNING', "$f is $hage old");
141                 next;
142         };
143
144         open(FH, "< $logdir/$f") or die ("Cannot open $logdir/$f: $!\n");
145         sysseek(FH, -1024, SEEK_END); # just try it - doesn't matter if it fails
146         my $last2 = '';
147         my $last = '';
148         while (<FH>) {
149                 chomp;
150                 if (/^sent\s+\d+\s+bytes\s+received\s+\d+\s+bytes\s+[\d\.]+\s+bytes\/sec$/) {
151                         problem('OK', "$f probably ok");
152                         close(FH);
153                         next FILE;
154                 };
155                 $last2 = $last;
156                 $last = $_;
157         };
158         problem('CRITICAL', "$f failed ($last2 $last)");
159 };
160
161 print $EXITCODE,": ", join(";  ", @MESSAGE), "\n";
162 exit $CODE{$EXITCODE};