5 check_bacula.pl -- check for bacula status
10 -C|--Client=ss List of clients
11 -g|--group=ss List of groups
13 -a|--age=i Age in hours (default 10h)
14 -w|--warning=i warning threshold (jobs)
15 -c|--critical=i critical threshold (jobs)
17 -S|--Storage=ss List of SDs to test
19 -s|--scratch=i threshold scratch number
20 -m|--mediatype=ss Media type to check for scratch
26 - if more than 10 jobs are running for client c1 and c2 for 1 hour
28 check_bacula.pl -C c1 -C c2 -w 10 -c 15 -a 1
30 - if more than 10 jobs are running for group g1 for 2 hours
32 check_bacula.pl -g g1 -w 10 -c 15 -a 2
34 - if S1_LTO1 and S1_LTO2 storage deamon are responding to status cmd
36 check_bacula.pl -S S1_LTO1 -S S1_LTO2
38 - if the scratch pool contains 5 volumes with mediatype Tape% at minimum
40 check_bacula.pl -s 2 -m Tape%
43 You can mix all options
45 check_bacula.pl -g g1 -w 10 -c 15 -S S1_LTO1 -s 2 -m Tape%
49 Bweb - A Bacula web interface
50 Bacula® - The Network Backup Solution
52 Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
54 The main author of Bweb is Eric Bollengier.
55 The main author of Bacula is Kern Sibbald, with contributions from
56 many others, a complete list can be found in the file AUTHORS.
58 This program is Free Software; you can redistribute it and/or
59 modify it under the terms of version two of the GNU General Public
60 License as published by the Free Software Foundation plus additions
61 that are listed in the file LICENSE.
63 This program is distributed in the hope that it will be useful, but
64 WITHOUT ANY WARRANTY; without even the implied warranty of
65 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
66 General Public License for more details.
68 You should have received a copy of the GNU General Public License
69 along with this program; if not, write to the Free Software
70 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
73 Bacula® is a registered trademark of John Walker.
74 The licensor of Bacula is the Free Software Foundation Europe
75 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zurich,
76 Switzerland, email:ftf@fsfeurope.org.
84 use POSIX qw/strftime/;
85 use Getopt::Long qw/:config no_ignore_case/;
88 my $config_file = $Bweb::config_file;
89 my (@client, @group, $help, $query, $verbose, @msg, @storage);
91 my $mediatype='%'; # check for all mediatype
92 my $nb_scratch=5; # check for more than 5 scratch media
98 my $timeout=50; # timeout for storage status command
100 GetOptions("Client=s@" => \@client,
101 "group=s@" => \@group,
103 "scratch=i" => \$nb_scratch,
104 "warning=i" => \$warn,
105 "critical=i"=> \$crit,
106 "verbose" => \$verbose,
107 "timeout=i" => \$timeout,
108 "Storage=s@"=> \@storage,
109 "mediatype=s"=> \$mediatype,
111 || Pod::Usage::pod2usage(-exitval => 2, -verbose => 1) ;
113 Pod::Usage::pod2usage(-verbose => 1) if ( $help ) ;
121 my $since = time - $age;
122 my $trig = time - 2*60*60;
124 my $conf = new Bweb::Config(config_file => $config_file);
126 my $bweb = new Bweb(info => $conf);
128 my $b = $bweb->get_bconsole();
129 $b->{timeout} = $timeout;
131 CGI::param(-name=> 'client',-value => \@client);
132 CGI::param(-name=> 'client_group', -value => \@group);
134 my ($where, undef) = $bweb->get_param(qw/clients client_groups/);
140 $c_filter = " JOIN Client USING (ClientId) ";
144 $g_filter = " JOIN client_group_member USING (ClientId) " .
145 " JOIN client_group USING (client_group_id) ";
148 ################################################################
149 # check if more than X jobs are running for too long (more than
150 # 2 hours) since Y ago
153 SELECT count(1) AS nb
154 FROM Job $c_filter $g_filter
156 WHERE JobStatus = 'R'
158 AND JobTDate > $since
163 $res = $bweb->dbh_selectrow_hashref($query);
167 push @msg, "$nb jobs are running";
169 } elsif ($nb > $warn) {
170 push @msg, "$nb jobs are running";
171 $ret = ($ret>1)?$ret:1;
175 ################################################################
176 # check failed jobs (more than X) since x time ago
179 SELECT count(1) AS nb
180 FROM Job $c_filter $g_filter
182 WHERE JobStatus IN ('E','e','f','A')
184 AND JobTDate > $since
188 $res = $bweb->dbh_selectrow_hashref($query);
192 push @msg, "$nb jobs are in error";
194 } elsif ($nb > $warn) {
195 push @msg, "$nb jobs are in error";
196 $ret = ($ret>1)?$ret:1;
200 ################################################################
201 # check storage status command
203 foreach my $st (@storage) {
205 my $out = $b->send_cmd("status storage=\"$st\"");
206 if (!$out || $out !~ /Attr spooling/) {
207 push @msg, "timeout ($timeout s) on status storage $st";
212 ################################################################
213 # check for Scratch volume
216 SELECT MediaType AS mediatype, count(MediaId) AS nb
217 FROM Media JOIN Pool USING (PoolId)
218 WHERE Pool.Name = 'Scratch'
219 AND Media.MediaType LIKE '$mediatype'
224 $res = $bweb->dbh_selectall_hashref($query, 'mediatype');
226 foreach my $k (keys %$res) {
227 if ($res->{$k}->{nb} < $nb_scratch) {
228 push @msg, "no more scratch for $k ($res->{$k}->{nb})";
234 ################################################################
238 print "OK - All checks ok\n";
239 } elsif ($ret == 1) {
240 print "WARNING - ", join(", ", @msg), "\n";
242 print "CRITICAL - ", join(", ", @msg), "\n";