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