6 Bweb - A Bacula web interface
7 Bacula® - The Network Backup Solution
9 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
11 The main author of Bweb is Eric Bollengier.
12 The main author of Bacula is Kern Sibbald, with contributions from
13 many others, a complete list can be found in the file AUTHORS.
15 This program is Free Software; you can redistribute it and/or
16 modify it under the terms of version two of the GNU General Public
17 License as published by the Free Software Foundation plus additions
18 that are listed in the file LICENSE.
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
30 Bacula® is a registered trademark of John Walker.
31 The licensor of Bacula is the Free Software Foundation Europe
32 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zurich,
33 Switzerland, email:ftf@fsfeurope.org.
46 use POSIX qw/strftime/;
48 my $conf = new Bweb::Config(config_file => $Bweb::config_file);
51 my $bweb = new Bweb(info => $conf);
53 my $dbh = $bweb->{dbh};
54 my $debug = $bweb->{debug};
56 my $graph = CGI::param('graph') || 'job_size';
57 my $legend = CGI::param('legend') || 'on' ;
58 $legend = ($legend eq 'on')?1:0;
60 my $arg = $bweb->get_form(qw/width height limit offset age
61 jfilesets level status jjobnames jclients/);
63 my ($limitq, $label) = $bweb->get_limit(age => $arg->{age},
64 limit => $arg->{limit},
65 offset=> $arg->{offset},
66 order => 'Job.StartTime ASC',
70 if ($arg->{status} and $arg->{status} ne 'Any') {
71 $statusq = " AND Job.JobStatus = '$arg->{status}' ";
75 if ($arg->{level} and $arg->{level} ne 'Any') {
76 $levelq = " AND Job.Level = '$arg->{level}' ";
80 if ($arg->{jfilesets}) {
81 $filesetq = " AND FileSet.FileSet IN ($arg->{qfilesets}) ";
85 if ($arg->{jjobnames}) {
86 $jobnameq = " AND Job.Name IN ($arg->{jjobnames}) ";
88 $arg->{jjobnames} = 'all'; # skip warning
92 if ($arg->{jclients}) {
93 $clientq = " AND Client.Name IN ($arg->{jclients}) ";
95 $arg->{jclients} = 'all'; # skip warning
98 my $gtype = CGI::param('gtype') || 'bars';
100 print CGI::header('image/png');
106 if ($gtype eq 'lines') {
107 use GD::Graph::lines;
108 $graph = GD::Graph::lines->new ( $arg->{width}, $arg->{height} );
110 } elsif ($gtype eq 'bars') {
112 $graph = GD::Graph::bars->new ( $arg->{width}, $arg->{height} );
114 } elsif ($gtype eq 'linespoints') {
115 use GD::Graph::linespoints;
116 $graph = GD::Graph::linespoints->new ( $arg->{width}, $arg->{height} );
118 # this doesnt works at this time
119 # } elsif ($gtype eq 'bars3d') {
120 # use GD::Graph::bars3d;
121 # $graph = GD::Graph::bars3d->new ( $arg->{width}, $arg->{height} );
127 $graph->set('x_label' => 'Time',
128 'x_number_format' => sub { strftime('%D', localtime($_[0])) },
129 'x_tick_number' => 1,
145 foreach my $row (@$all_row) {
146 my $label = $row->[1] . "/" . $row->[2] ; # client/backup name
148 $ret->{date}->[$i] = $row->[0];
149 $ret->{$label}->[$i] = $row->[3];
151 $last_date = $row->[0];
154 # insert a fake element
155 foreach my $elt ( keys %{$ret}) {
156 $ret->{$elt}->[$i] = undef;
159 $ret->{date}->[$i] = $last_date + 1;
161 my $date = $ret->{date} ;
164 return ($date, $ret);
176 foreach my $row (@$all_row) {
177 $ret->{date}->[$i] = $row->[0];
178 $ret->{nb}->[$i] = $row->[1];
185 if ($graph eq 'job_size') {
189 UNIX_TIMESTAMP(Job.StartTime) AS starttime,
190 Client.Name AS clientname,
192 Job.JobBytes AS jobbytes
193 FROM Job, Client, FileSet
194 WHERE Job.ClientId = Client.ClientId
195 AND Job.FileSetId = FileSet.FileSetId
205 print STDERR $query if ($debug);
207 my $obj = get_graph('title' => "Job Size : $arg->{jclients}/$arg->{jjobnames}",
210 'y_number_format' => \&Bweb::human_size,
213 my $all = $dbh->selectall_arrayref($query) ;
215 my ($d, $ret) = make_tab($all);
217 $obj->set_legend(keys %$ret);
219 print $obj->plot([$d, values %$ret])->png;
222 if ($graph eq 'job_file') {
226 UNIX_TIMESTAMP(Job.StartTime) AS starttime,
227 Client.Name AS clientname,
229 Job.JobFiles AS jobfiles
230 FROM Job, Client, FileSet
231 WHERE Job.ClientId = Client.ClientId
232 AND Job.FileSetId = FileSet.FileSetId
242 print STDERR $query if ($debug);
244 my $obj = get_graph('title' => "Job Files : $arg->{jclients}/$arg->{jjobnames}",
245 'y_label' => 'Number Files',
249 my $all = $dbh->selectall_arrayref($query) ;
251 my ($d, $ret) = make_tab($all);
253 $obj->set_legend(keys %$ret);
255 print $obj->plot([$d, values %$ret])->png;
258 elsif ($graph eq 'job_rate') {
262 UNIX_TIMESTAMP(Job.StartTime) AS starttime,
263 Client.Name AS clientname,
266 ($bweb->{sql}->{SEC_TO_INT}(
267 $bweb->{sql}->{UNIX_TIMESTAMP}(EndTime)
268 - $bweb->{sql}->{UNIX_TIMESTAMP}(StartTime)) + 0.01)
271 FROM Job, Client, FileSet
272 WHERE Job.ClientId = Client.ClientId
273 AND Job.FileSetId = FileSet.FileSetId
283 print STDERR $query if ($debug);
285 my $obj = get_graph('title' => "Job Rate : $arg->{jclients}/$arg->{jjobnames}",
286 'y_label' => 'Rate b/s',
288 'y_number_format' => \&Bweb::human_size,
291 my $all = $dbh->selectall_arrayref($query) ;
293 my ($d, $ret) = make_tab($all);
295 $obj->set_legend(keys %$ret);
297 print $obj->plot([$d, values %$ret])->png;
302 elsif ($graph eq 'job_duration') {
306 UNIX_TIMESTAMP(Job.StartTime) AS starttime,
307 Client.Name AS clientname,
309 $bweb->{sql}->{SEC_TO_INT}( $bweb->{sql}->{UNIX_TIMESTAMP}(EndTime)
310 - $bweb->{sql}->{UNIX_TIMESTAMP}(StartTime))
312 FROM Job, Client, FileSet
313 WHERE Job.ClientId = Client.ClientId
314 AND Job.FileSetId = FileSet.FileSetId
324 print STDERR $query if ($debug);
326 my $obj = get_graph('title' => "Job Duration : $arg->{jclients}/$arg->{jjobnames}",
327 'y_label' => 'Duration',
329 'y_number_format' => \&Bweb::human_sec,
331 my $all = $dbh->selectall_arrayref($query) ;
333 my ($d, $ret) = make_tab($all);
335 $obj->set_legend(keys %$ret);
337 print $obj->plot([$d, values %$ret])->png;
340 # number of job per day/hour
341 } elsif ($graph =~ /^job_(count|sum|avg)_((p?)(day|hour|month))$/) {
345 my ($limit, $label) = $bweb->get_limit(age => $arg->{age},
346 limit => $arg->{limit},
347 offset=> $arg->{offset},
350 my @arg; # arg for plotting
352 if (!$per_t) { # much better aspect
355 push @arg, ("x_number_format" => undef,
360 if ($t eq 'sum' or $t eq 'avg') {
361 push @arg, ('y_number_format' => \&Bweb::human_size);
366 " . ($per_t?"":"UNIX_TIMESTAMP") . "(" . $bweb->{sql}->{"STARTTIME_$d"} . ") AS A,
368 FROM Job, Client, FileSet
369 WHERE Job.ClientId = Client.ClientId
370 AND Job.FileSetId = FileSet.FileSetId
380 print STDERR $query if ($debug);
382 my $obj = get_graph('title' => "Job $t : $arg->{jclients}/$arg->{jjobnames}",
388 my $all = $dbh->selectall_arrayref($query) ;
389 my ($ret) = make_tab_sum($all);
391 print $obj->plot([$ret->{date}, $ret->{nb}])->png;