]> git.sur5r.net Git - bacula/bacula/blob - gui/bweb/cgi/bgraph.pl
ebl move /etc/bweb/config to /etc/bacula/bweb.conf
[bacula/bacula] / gui / bweb / cgi / bgraph.pl
1 #!/usr/bin/perl -w
2 use strict;
3
4 =head1 LICENSE
5
6    Bweb - A Bacula web interface
7    Bacula® - The Network Backup Solution
8
9    Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
10
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.
14
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.
19
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.
24
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
28    02110-1301, USA.
29
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.
34
35 =head1 VERSION
36
37     $Id$
38
39 =cut
40
41 use Bweb;
42
43 use Data::Dumper;
44 use CGI;
45
46 use POSIX qw/strftime/;
47
48 my $conf = new Bweb::Config(config_file => $Bweb::config_file);
49 $conf->load();
50
51 my $bweb = new Bweb(info => $conf);
52 $bweb->connect_db();
53 my $dbh = $bweb->{dbh};
54 my $debug = $bweb->{debug};
55
56 my $graph = CGI::param('graph') || 'job_size';
57 my $legend = CGI::param('legend') || 'on' ;
58 $legend = ($legend eq 'on')?1:0;
59
60 my $arg = $bweb->get_form(qw/width height limit offset age
61                              jfilesets level status jjobnames jclients/);
62
63 my ($limitq, $label) = $bweb->get_limit(age   => $arg->{age},
64                                         limit => $arg->{limit},
65                                         offset=> $arg->{offset},
66                                         order => 'Job.StartTime ASC',
67                                         );
68
69 my $statusq='';
70 if ($arg->{status} and $arg->{status} ne 'Any') {
71     $statusq = " AND Job.JobStatus = '$arg->{status}' ";
72 }
73     
74 my $levelq='';
75 if ($arg->{level} and $arg->{level} ne 'Any') {
76     $levelq = " AND Job.Level = '$arg->{level}' ";
77
78
79 my $filesetq='';
80 if ($arg->{jfilesets}) {
81     $filesetq = " AND FileSet.FileSet IN ($arg->{qfilesets}) ";
82
83
84 my $jobnameq='';
85 if ($arg->{jjobnames}) {
86     $jobnameq = " AND Job.Name IN ($arg->{jjobnames}) ";
87 } else {
88     $arg->{jjobnames} = 'all';  # skip warning
89
90
91 my $clientq='';
92 if ($arg->{jclients}) {
93     $clientq = " AND Client.Name IN ($arg->{jclients}) ";
94 } else {
95     $arg->{jclients} = 'all';   # skip warning
96 }
97
98 my $gtype = CGI::param('gtype') || 'bars';
99
100 print CGI::header('image/png');
101
102 sub get_graph
103 {
104     my (@options) = @_;
105     my $graph;
106     if ($gtype eq 'lines') {
107         use GD::Graph::lines;
108         $graph = GD::Graph::lines->new ( $arg->{width}, $arg->{height} );
109
110     } elsif ($gtype eq 'bars') {
111         use GD::Graph::bars;
112         $graph = GD::Graph::bars->new ( $arg->{width}, $arg->{height} );
113
114     } elsif ($gtype eq 'linespoints') {
115         use GD::Graph::linespoints;
116         $graph = GD::Graph::linespoints->new ( $arg->{width}, $arg->{height} );
117
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} );
122
123     } else {
124         return undef;
125     }
126
127     $graph->set('x_label' => 'Time',
128                 'x_number_format' => sub { strftime('%D', localtime($_[0])) },
129                 'x_tick_number' => 1,
130                 @options,
131                 );
132
133     return $graph;
134 }
135
136 sub make_tab
137 {
138     my ($all_row) = @_;
139
140     my $i=0;
141     my $last_date=0;
142
143     my $ret = {};
144     
145     foreach my $row (@$all_row) {
146         my $label = $row->[1] . "/" . $row->[2] ; # client/backup name
147
148         $ret->{date}->[$i]   = $row->[0];       
149         $ret->{$label}->[$i] = $row->[3];
150         $i++;
151         $last_date = $row->[0];
152     }
153
154     # insert a fake element
155     foreach my $elt ( keys %{$ret}) {
156         $ret->{$elt}->[$i] =  undef;
157     }
158
159     $ret->{date}->[$i] = $last_date + 1;
160
161     my $date = $ret->{date} ;
162     delete $ret->{date};
163
164     return ($date, $ret);
165 }
166
167 sub make_tab_sum
168 {
169     my ($all_row) = @_;
170
171     my $i=0;
172     my $last_date=0;
173
174     my $ret = {};
175     
176     foreach my $row (@$all_row) {
177         $ret->{date}->[$i]   = $row->[0];       
178         $ret->{nb}->[$i] = $row->[1];
179         $i++;
180     }
181
182     return ($ret);
183 }
184
185 if ($graph eq 'job_size') {
186
187     my $query = "
188 SELECT 
189        UNIX_TIMESTAMP(Job.StartTime)    AS starttime,
190        Client.Name                      AS clientname,
191        Job.Name                         AS jobname,
192        Job.JobBytes                     AS jobbytes
193 FROM Job, Client, FileSet
194 WHERE Job.ClientId = Client.ClientId
195   AND Job.FileSetId = FileSet.FileSetId
196   AND Job.Type = 'B'
197   $clientq
198   $statusq
199   $filesetq
200   $levelq
201   $jobnameq
202 $limitq
203 ";
204
205     print STDERR $query if ($debug);
206
207     my $obj = get_graph('title' => "Job Size : $arg->{jclients}/$arg->{jjobnames}",
208                         'y_label' => 'Size',
209                         'y_min_value' => 0,
210                         'y_number_format' => \&Bweb::human_size,
211                         );
212
213     my $all = $dbh->selectall_arrayref($query) ;
214
215     my ($d, $ret) = make_tab($all);
216     if ($legend) {
217         $obj->set_legend(keys %$ret);
218     }
219     print $obj->plot([$d, values %$ret])->png;
220 }
221
222 if ($graph eq 'job_file') {
223
224     my $query = "
225 SELECT 
226        UNIX_TIMESTAMP(Job.StartTime)    AS starttime,
227        Client.Name                      AS clientname,
228        Job.Name                         AS jobname,
229        Job.JobFiles                     AS jobfiles
230 FROM Job, Client, FileSet
231 WHERE Job.ClientId = Client.ClientId
232   AND Job.FileSetId = FileSet.FileSetId
233   AND Job.Type = 'B'
234   $clientq
235   $statusq
236   $filesetq
237   $levelq
238   $jobnameq
239 $limitq
240 ";
241
242     print STDERR $query if ($debug);
243
244     my $obj = get_graph('title' => "Job Files : $arg->{jclients}/$arg->{jjobnames}",
245                         'y_label' => 'Number Files',
246                         'y_min_value' => 0,
247                         );
248
249     my $all = $dbh->selectall_arrayref($query) ;
250
251     my ($d, $ret) = make_tab($all);
252     if ($legend) {
253         $obj->set_legend(keys %$ret);
254     }
255     print $obj->plot([$d, values %$ret])->png;
256 }
257
258 elsif ($graph eq 'job_rate') {
259
260     my $query = "
261 SELECT 
262        UNIX_TIMESTAMP(Job.StartTime)                          AS starttime,
263        Client.Name                      AS clientname,
264        Job.Name                         AS jobname,
265        Job.JobBytes /
266        ($bweb->{sql}->{SEC_TO_INT}(
267                           $bweb->{sql}->{UNIX_TIMESTAMP}(EndTime)  
268                         - $bweb->{sql}->{UNIX_TIMESTAMP}(StartTime)) + 0.01) 
269          AS rate
270
271 FROM Job, Client, FileSet
272 WHERE Job.ClientId = Client.ClientId
273   AND Job.FileSetId = FileSet.FileSetId
274   AND Job.Type = 'B'
275   $clientq
276   $statusq
277   $filesetq
278   $levelq
279   $jobnameq
280 $limitq
281 ";
282
283     print STDERR $query if ($debug);
284
285     my $obj = get_graph('title' => "Job Rate : $arg->{jclients}/$arg->{jjobnames}",
286                         'y_label' => 'Rate b/s',
287                         'y_min_value' => 0,
288                         'y_number_format' => \&Bweb::human_size,
289                         );
290
291     my $all = $dbh->selectall_arrayref($query) ;
292
293     my ($d, $ret) = make_tab($all);    
294     if ($legend) {
295         $obj->set_legend(keys %$ret);
296     }
297     print $obj->plot([$d, values %$ret])->png;
298 }
299
300
301
302 elsif ($graph eq 'job_duration') {
303
304     my $query = "
305 SELECT 
306        UNIX_TIMESTAMP(Job.StartTime)                           AS starttime,
307        Client.Name                                             AS clientname,
308        Job.Name                                                AS jobname,
309   $bweb->{sql}->{SEC_TO_INT}(  $bweb->{sql}->{UNIX_TIMESTAMP}(EndTime)  
310                              - $bweb->{sql}->{UNIX_TIMESTAMP}(StartTime)) 
311          AS duration
312 FROM Job, Client, FileSet
313 WHERE Job.ClientId = Client.ClientId
314   AND Job.FileSetId = FileSet.FileSetId
315   AND Job.Type = 'B'
316   $clientq
317   $statusq
318   $filesetq
319   $levelq
320   $jobnameq
321 $limitq
322 ";
323
324     print STDERR $query if ($debug);
325
326     my $obj = get_graph('title' => "Job Duration : $arg->{jclients}/$arg->{jjobnames}",
327                         'y_label' => 'Duration',
328                         'y_min_value' => 0,
329                         'y_number_format' => \&Bweb::human_sec,
330                         );
331     my $all = $dbh->selectall_arrayref($query) ;
332
333     my ($d, $ret) = make_tab($all);
334     if ($legend) {
335         $obj->set_legend(keys %$ret);
336     }
337     print $obj->plot([$d, values %$ret])->png;
338
339
340 # number of job per day/hour
341 } elsif ($graph =~ /^job_(count|sum|avg)_((p?)(day|hour|month))$/) {
342     my $t = $1;
343     my $d = uc($2);
344     my $per_t = $3;
345     my ($limit, $label) = $bweb->get_limit(age   => $arg->{age},
346                                            limit => $arg->{limit},
347                                            offset=> $arg->{offset},
348                                            groupby => "A",
349                                            );
350     my @arg;                    # arg for plotting
351
352     if (!$per_t) {              # much better aspect
353         #$gtype = 'lines';
354     } else {
355         push @arg, ("x_number_format" => undef,
356                     "x_min_value" => 0,
357                     );
358     }
359
360     if ($t eq 'sum' or $t eq 'avg') {
361         push @arg, ('y_number_format' => \&Bweb::human_size);
362     }
363
364     my $query = "
365 SELECT
366      " . ($per_t?"":"UNIX_TIMESTAMP") . "(" . $bweb->{sql}->{"STARTTIME_$d"} . ") AS A,
367      $t(JobBytes)                  AS nb
368 FROM Job, Client, FileSet
369 WHERE Job.ClientId = Client.ClientId
370   AND Job.FileSetId = FileSet.FileSetId
371   AND Job.Type = 'B'
372   $clientq
373   $statusq
374   $filesetq
375   $levelq
376   $jobnameq
377 $limit
378 ";
379
380     print STDERR $query  if ($debug);
381
382     my $obj = get_graph('title' => "Job $t : $arg->{jclients}/$arg->{jjobnames}",
383                         'y_label' => $t,
384                         'y_min_value' => 0,
385                         @arg,
386                         );
387
388     my $all = $dbh->selectall_arrayref($query) ;
389     my ($ret) = make_tab_sum($all);
390
391     print $obj->plot([$ret->{date}, $ret->{nb}])->png;    
392 }
393