]> git.sur5r.net Git - bacula/bacula/blob - gui/bweb/script/check_bacula.pl
bweb: Update some GPL2 notice to AGPL
[bacula/bacula] / gui / bweb / script / check_bacula.pl
1 #!/usr/bin/perl -w
2
3 =head1 DESCRIPTION
4
5     check_bacula.pl -- check for bacula status
6
7 =head2 USAGE
8
9     check_bacula.pl ...
10       -C|--Client=ss       List of clients
11       -g|--group=ss        List of groups
12
13       -l|--level=F/I/D     Specify job level
14
15       -w|--warning=i       warning threshold (jobs)
16       -c|--critical=i      critical threshold (jobs)
17
18       -S|--Storage=ss      List of SDs to test
19
20       -s|--scratch=i       threshold scratch number
21       -m|--mediatype=ss    Media type to check for scratch
22
23       -R|--Running=i       Test for maximum running jobs for a period (in hours)
24       -F|--Failed=i        Test for failed jobs after a period (in mins)
25
26 =head3 EXAMPLES
27
28    Check :
29       - if more than 10 jobs are running for client c1 and c2 for 1 hour
30     check_bacula.pl -R 1 -C c1 -C c2 -w 10 -c 15
31
32       - if more than 10 jobs are running for group g1 for 2 hours
33     check_bacula.pl -R 2 -g g1 -w 10 -c 15
34
35       - if more than 10 jobs are failed of canceled for 2 hours for group g1
36     check_bacula.pl -F 120 -g g1 -w 10 -c 15
37
38       - if S1_LTO1 and S1_LTO2 storage deamon are responding to status cmd
39     check_bacula.pl -S S1_LTO1 -S S1_LTO2
40
41       - if the scratch pool contains 5 volumes with mediatype Tape% at minimum
42     check_bacula.pl -s 2 -m Tape%
43
44    You can mix all options
45
46    check_bacula.pl -g g1 -w 10 -c 15 -S S1_LTO1 -s 2 -m Tape%
47
48       - if we have more than 10 jobs in error or already running for 2 hours
49    check_bacula.pl -R 2 -F 20 -w 10 -c 15
50
51 =head1 LICENSE
52
53    Bweb - A Bacula web interface
54    Bacula® - The Network Backup Solution
55
56    Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
57
58    The main author of Bweb is Eric Bollengier.
59    The main author of Bacula is Kern Sibbald, with contributions from
60    many others, a complete list can be found in the file AUTHORS.
61
62    This program is Free Software; you can redistribute it and/or
63    modify it under the terms of version two of the GNU General Public
64    License as published by the Free Software Foundation plus additions
65    that are listed in the file LICENSE.
66
67    This program is distributed in the hope that it will be useful, but
68    WITHOUT ANY WARRANTY; without even the implied warranty of
69    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
70    Affero General Public License for more details.
71
72    You should have received a copy of the GNU General Public License
73    along with this program; if not, write to the Free Software
74    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
75    02110-1301, USA.
76
77    Bacula® is a registered trademark of Kern Sibbald.
78    The licensor of Bacula is the Free Software Foundation Europe
79    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zurich,
80    Switzerland, email:ftf@fsfeurope.org.
81
82 =cut
83
84 use strict ;
85 use Getopt::Long ;
86 use Bweb;
87 use CGI;
88 use POSIX qw/strftime/;
89 use Getopt::Long qw/:config no_ignore_case/;
90 use Pod::Usage;
91
92 my $config_file = $Bweb::config_file;
93 my (@client, @group, $help, $query, $verbose, @msg, @storage);
94
95 my $max_run;
96 my $test_failed;
97 my $mediatype='%';              # check for all mediatype
98 my $nb_scratch;                 # check for scratch media
99 my $crit = 10;
100 my $warn = 5;
101 my $res;
102 my $ret=0;
103 my $level;
104 my $timeout=50;                 # timeout for storage status command
105
106 GetOptions("Client=s@"  => \@client,
107            "group=s@"   => \@group,
108            "scratch=i" => \$nb_scratch,
109            "warning=i" => \$warn,
110            "critical=i"=> \$crit,
111            "verbose"   => \$verbose,
112            "timeout=i" => \$timeout,
113            "Storage=s@"=> \@storage,
114            "mediatype=s"=> \$mediatype,
115            "Runing:45"  => \$max_run,
116            "Failed:12"  => \$test_failed,
117            "level=s"   => \$level,
118            "help"      => \$help) 
119     || Pod::Usage::pod2usage(-exitval => 2, -verbose => 1) ;
120
121 Pod::Usage::pod2usage(-verbose => 1) if ( $help ) ;
122
123 my $conf = new Bweb::Config(config_file => $config_file);
124 $conf->load();
125 my $bweb = new Bweb(info => $conf);
126
127 my $b = $bweb->get_bconsole();
128 $b->{timeout} = $timeout;
129
130 CGI::param(-name=> 'client',-value => \@client);
131 CGI::param(-name=> 'client_group', -value => \@group);
132 CGI::param(-name=> 'level', -value => $level);
133
134 my ($where, undef) = $bweb->get_param(qw/clients client_groups level/);
135
136 my $c_filter ="";
137 my $g_filter = "";
138
139 if (@client) {
140     $c_filter = " JOIN Client USING (ClientId) ";
141 }
142
143 if (@group) {
144     $g_filter = " JOIN client_group_member USING (ClientId) " .
145                 " JOIN client_group USING (client_group_id) ";
146 }
147
148 ################################################################
149 # check if more than X jobs are running or just created
150 # for too long (more than 2 hours) since Y ago
151
152 if ($max_run) {
153     my $trig = time - $max_run*60;
154
155     $query = "
156 SELECT count(1) AS nb
157   FROM Job $c_filter $g_filter
158
159  WHERE JobStatus IN ('R', 'C')
160    AND Type = 'B'
161    AND JobTDate < $trig
162  $where
163 ";
164     $res = $bweb->dbh_selectrow_hashref($query);
165     if ($res) {
166         my $nb = $res->{nb};
167         if ($nb >= $crit) {
168             push @msg, "$nb jobs are running (${max_run}m)";
169             $ret = 2;
170         } elsif ($nb >= $warn) {
171             push @msg, "$nb jobs are running (${max_run}m)";
172             $ret = ($ret>1)?$ret:1;
173         }
174     }
175 }
176
177 ################################################################
178 # check failed jobs (more than X) since x time ago
179
180 if ($test_failed) {
181     my $since = time - $test_failed*60*60;
182
183     $query = "
184 SELECT count(1) AS nb
185   FROM Job $c_filter $g_filter
186
187  WHERE JobStatus IN ('E','e','f','A')
188    AND Type = 'B'
189    AND JobTDate > $since
190  $where
191 ";
192     $res = $bweb->dbh_selectrow_hashref($query);
193     if ($res) {
194         my $nb = $res->{nb};
195         if ($nb >= $crit) {
196             push @msg, "$nb jobs are in error (${test_failed}h)";
197             $ret = 2;
198         } elsif ($nb >= $warn) {
199             push @msg, "$nb jobs are in error (${test_failed}h)";
200             $ret = ($ret>1)?$ret:1;
201         }
202     }
203 }
204
205 ################################################################
206 # check storage status command
207
208 foreach my $st (@storage) {
209
210     my $out = $b->send_cmd("status storage=\"$st\"");
211     if (!$out || $out !~ /Attr spooling|JobId/) {
212         push @msg, "timeout ($timeout s) or bad response on status storage $st";
213         $ret = 2;
214     }
215 }
216
217 ################################################################
218 # check for Scratch volume
219
220 if ($nb_scratch) {
221     $query = "
222   SELECT MediaType AS mediatype, count(MediaId) AS nb
223     FROM Media JOIN Pool USING (PoolId)
224    WHERE Pool.Name = 'Scratch'
225      AND Media.MediaType LIKE '$mediatype'
226          
227   GROUP BY MediaType
228 ";
229
230     $res = $bweb->dbh_selectall_hashref($query, 'mediatype');
231     if ($res && keys %$res) {
232         foreach my $k (keys %$res) {
233             if ($res->{$k}->{nb} < $nb_scratch) {
234                 push @msg, "no more scratch for $k ($res->{$k}->{nb})";
235                 $ret = 2;
236             }
237         }
238     } else { # query doesn't report anything...
239         push @msg, "no more scratch for $mediatype";
240         $ret = 2;
241     }
242 }
243
244 ################################################################
245 # print result
246
247 if (!$ret) {
248     print "OK - All checks ok\n";
249 } elsif ($ret == 1) {
250     print "WARNING - ", join(", ", @msg), "\n";
251 } else {
252     print "CRITICAL - ", join(", ", @msg), "\n";
253 }
254 exit $ret;
255