5 Bweb - A Bacula web interface
6 Bacula® - The Network Backup Solution
8 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
10 The main author of Bweb is Eric Bollengier.
11 The main author of Bacula is Kern Sibbald, with contributions from
12 many others, a complete list can be found in the file AUTHORS.
14 This program is Free Software; you can redistribute it and/or
15 modify it under the terms of version two of the GNU General Public
16 License as published by the Free Software Foundation plus additions
17 that are listed in the file LICENSE.
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
29 Bacula® is a registered trademark of Kern Sibbald.
30 The licensor of Bacula is the Free Software Foundation Europe
31 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zurich,
32 Switzerland, email:ftf@fsfeurope.org.
40 use Time::ParseDate qw/parsedate/;
41 use POSIX qw/strftime/;
44 my $conf = new Bweb::Config(config_file => $Bweb::config_file);
47 my $bweb = new Bweb(info => $conf);
49 print CGI::header('text/html');
50 $bweb->display_begin();
51 $bweb->can_do('r_view_stat');
53 my $arg = $bweb->get_form(qw/qnocache qiso_begin qiso_end qusage qpools
54 qpoolusage qnojob jclient_groups qbypool
55 qfullname db_client_groups qclient_groups/);
56 my ($filter1, undef) = $bweb->get_param('pool');
58 if (!$arg->{qiso_begin}) {
59 $arg->{qiso_begin} = strftime('\'%F %H:%M:00\'', localtime(time - 60*60*12));
60 $arg->{qiso_end} = strftime('\'%F %H:%M:00\'', localtime(time));
62 use Digest::MD5 qw(md5_hex);
64 my $md5_rep = md5_hex("$arg->{qiso_begin}:$arg->{qiso_end}:$arg->{qusage}:" .
65 "$arg->{jclient_groups}:$arg->{qpoolusage};$arg->{qnojob}") ;
70 && -f "$conf->{fv_write_path}/$md5_rep.png")
72 $arg->{result} = "/bweb/fv/$md5_rep.png";
73 $bweb->display($arg, 'btime.tpl');
80 debug => $conf->{debug},
89 my $sec = $bweb->{sql}->{STARTTIME_SEC};
90 $sec =~ s/Job.StartTime/Log.Time/;
91 my $reg = $bweb->{sql}->{MATCH};
95 end_job => ': Bacula',
96 start_job => ': Start Backup|: D.marrage du ',
97 data_despool_time => ': Despooling elapsed time|: Temps du tran',
98 attr_despool_time => ': Sending spooled attrs|: Transfert des attributs',
99 get_drive => ': Using Device',
100 start_spool => ': Spooling',
101 end_spool => ': User specified spool|: Taille du spool',
102 end_spool2 => ': Committing spooled data to|: Transfert des donn',
106 end_job => ': Bacula',
107 start_job => ': Start Backup',
108 data_despool_time => ': Despooling elapsed time',
109 attr_despool_time => ': Sending spooled attrs',
110 get_drive => ': Using Device',
111 start_spool => ': Spooling',
112 end_spool => ': User specified spool',
113 end_spool2 => ': Committing spooled data to',
118 end_job => ': Bacula',
119 start_job => ': D.marrage du ',
120 data_despool_time => ': Temps du tran',
121 attr_despool_time => ': Transfert des attributs',
122 get_drive => ': Using Device',
123 start_spool => ': Spooling',
124 end_spool => ': Taille du spool',
125 end_spool2 => ': Transfert des donn',
128 my $name = ($arg->{qfullname}) ? 'Job' : 'Name';
130 my $filter = join(" OR ",
131 map { "Log.LogText $bweb->{sql}->{MATCH} '$_'" } values %regs);
134 SELECT " . $bweb->dbh_strcat("Job.$name", "'_'", 'Job.Level') . ",
136 substring(Log.LogText from 8 for 70),
140 FROM Log INNER JOIN Job USING (JobId) JOIN Pool USING (PoolId)
141 " . ($arg->{jclient_groups}?
142 " JOIN Client USING (ClientId)
143 JOIN client_group_member ON (Client.ClientId = client_group_member.clientid)
144 JOIN client_group USING (client_group_id)
145 WHERE client_group_name IN ($arg->{jclient_groups})
149 Job.StartTime > $arg->{qiso_begin}
150 AND Job.StartTime < $arg->{qiso_end}
154 ORDER BY " . ($arg->{qbypool}?"Pool.Name,":""). "Job.JobId,Log.LogId,Log.Time";
157 $bweb->debug($query);
158 my $all = $bweb->dbh_selectall_arrayref($query);
170 foreach my $elt (@$all)
172 # if bypool is used, we display pool usage after each job block
173 if ($arg->{qbypool} && $last_pool ne $elt->[4]) {
174 foreach my $i (sort keys %$pool) {
175 $top->add_job(label => $i,
176 data => $pool->{$i});
180 if ($lastid && $lastid ne $elt->[3]) {
181 if (!$arg->{qnojob}) {
182 $top->add_job(label => $last_name,
189 if ($elt->[2] =~ /$regs{end_job}/) {
196 # } elsif ($elt->[2] =~ /$regs{attr_despool_time}/) {
205 } elsif ($elt->[2] =~ /(?:$regs{get_drive}) "([\w\d\s-\.]+)"/) {
208 } elsif ($elt->[2] =~ /(?:$regs{data_despool_time}).*? = (\d+):(\d+):(\d+)/) {
209 # on connait le temps de despool
210 my $t = $1*60*60+ $2*60 + $3;
212 if ($t > 3) { # en dessous de 3s on affiche pas
213 push @$data, { # temps d'attente du drive
217 end => parsedate($elt->[1]) - $t,
223 begin => parsedate($elt->[1]) - $t,
227 push @{$write->{$drive}}, { # display only write time
229 begin => parsedate($elt->[1]) - $t,
233 push @{$pool->{"$drive: $elt->[4]"}}, {
235 begin => parsedate($elt->[1]) - $t,
248 } elsif ($elt->[2] =~ /$regs{start_spool}/) {
260 } elsif ($elt->[2] =~ /($regs{end_spool}|$regs{end_spool2})/) {
268 } elsif ($elt->[2] =~ /$regs{start_job}/) {
276 $last_name = $elt->[0];
278 $last_pool = $elt->[4];
281 if (!$arg->{qnojob} && $last_name) {
282 $top->add_job(label => $last_name,
285 if ($arg->{qpoolusage} or $arg->{qbypool}) {
286 foreach my $d (sort keys %$pool) {
287 $top->add_job(label => $d,
288 data => $pool->{$d});
292 if ($arg->{qusage}) {
293 foreach my $d (sort keys %$write) {
294 $top->add_job(label => "drive $d",
295 data => $write->{$d});
302 open(FP, ">$conf->{fv_write_path}/$md5_rep.png");
304 # Convert the image to PNG and print it on standard output
305 print FP $GTime::gd->png;
308 $arg->{result} = "/bweb/fv/$md5_rep.png";
309 $bweb->display( $arg, 'btime.tpl');
310 $bweb->display_end();