Removed /usr/local from CDPATH
[clearscm.git] / clearadm / plot.cgi
1 #!/usr/local/bin/perl
2
3 =pod
4
5 =head1 NAME $RCSfile: plot.cgi,v $
6
7 Plot statistics
8
9 =head1 VERSION
10
11 =over
12
13 =item Author
14
15 Andrew DeFaria <Andrew@ClearSCM.com>
16
17 =item Revision
18
19 $Revision: 1.14 $
20
21 =item Created:
22
23 Mon Oct 25 11:10:47 PDT 2008
24
25 =item Modified:
26
27 $Date: 2011/01/28 21:30:45 $
28
29 =back
30
31 =head1 DESCRIPTION
32
33 Display a graph of either Loadavg or Filesystem data and provide controls for
34 the user to manipulate the chart.
35
36 =cut
37
38 use strict;
39 use warnings;
40
41 use FindBin;
42 use CGI qw(:standard :cgi-lib start_table end_table start_Tr end_Tr);
43 use GD::Graph::area;
44
45 use lib "$FindBin::Bin/lib", "$FindBin::Bin/../lib";
46
47 use Clearadm;
48 use ClearadmWeb;
49 use Display;
50
51 my $VERSION  = '$Revision: 1.14 $';
52   ($VERSION) = ($VERSION =~ /\$Revision: (.*) /);
53   
54 my %opts = Vars;
55
56 my $clearadm;
57
58 sub displayGraph() {
59   my $parms;
60
61   for (keys %opts) {
62     $parms .= '&' if $parms;
63     $parms .= "$_=$opts{$_}"
64   } # for
65
66   display '<center>';
67   
68   if ($opts{type} eq 'loadavg') {
69     my %system = $clearadm->GetSystem($opts{system});
70
71     # We can use the cached version only if the opts are set to default
72     if ($opts{scaling} eq 'Hour' and $opts{points} == 24) {
73       my $data = $opts{tiny} ? $system{loadavgsmall} : $system{loadavg};
74
75       display img {src => "data:image/png;base64,$data"};
76     } else {
77       unless ($opts{tiny}) {
78         display img {src => "plotloadavg.cgi?$parms", class => 'chart'};
79       } else {
80         display img {src => "plotloadavg.cgi?$parms", border => 0};
81       } # unless
82     } # if
83   } elsif ($opts{type} eq 'filesystem') {
84     my %filesystem = $clearadm->GetFilesystem($opts{system}, $opts{filesystem});
85
86     # We can use the cached version only if the opts are set to default
87     if ($opts{scaling} eq 'Day' and $opts{points} == 7) {
88       my $data = $opts{tiny} ? $filesystem{fssmall} : $filesystem{fslarge};
89
90       display img {src => "data:image/png;base64,$data"};
91     } else {
92       unless ($opts{tiny}) {
93         display img {src => "plotfs.cgi?$parms", class => 'chart'};
94       } else {
95         display img {src => "plotfs.cgi?$parms", border => 0};
96       } # unless
97     } # if
98   } elsif ($opts{type} eq 'vob' or $opts{type} eq 'view') {
99     my (%vob, %view);
100
101     %vob  = $clearadm->GetVob($opts{tag}, $opts{region})  if $opts{type} eq 'vob';
102     %view = $clearadm->GetView($opts{tag}, $opts{region}) if $opts{type} eq 'view';
103     # We can use the cached version only if the opts are set to default
104     if ($opts{scaling} eq 'Day' and $opts{points} == 7) {
105       my $storageType = $opts{tiny}          ? "$opts{storage}small" : "$opts{storage}large";
106       my $data        = $opts{type} eq 'vob' ? $vob{$storageType}    : $view{$storageType};
107
108       display img {src => "data:image/png;base64,$data"};
109     } else {
110       unless ($opts{tiny}) {
111         display img {src => "plotstorage.cgi?$parms", class => 'chart'};
112       } else {
113         display img {src => "plotstorage.cgi?$parms", border => 0};
114       } # unless
115     } # if
116   } # if
117
118   display '</center>';
119   
120   return;
121 } # displayGraph
122
123 sub displayFSInfo() {
124   if ($opts{filesystem}) {
125     display h3 {-align => 'center'}, 'Latest Filesystem Reading';
126   } else {
127     display p;
128     return;
129   } # if
130   
131   display start_table {width => '800px', cellspacing => 1};
132   
133   display start_Tr;
134     display th {class => 'labelCentered'}, 'Filesystem';
135     display th {class => 'labelCentered'}, 'Type';
136     display th {class => 'labelCentered'}, 'Mount';
137     display th {class => 'labelCentered'}, 'Size';
138     display th {class => 'labelCentered'}, 'Used';
139     display th {class => 'labelCentered'}, 'Free';
140     display th {class => 'labelCentered'}, 'Used %';
141     display th {class => 'labelCentered'}, 'History';
142     display th {class => 'labelCentered'}, 'Threshold';
143   display end_Tr;  
144   
145   my %filesystem = $clearadm->GetFilesystem (
146     $opts{system}, 
147     $opts{filesystem}
148   );
149   my %fs = $clearadm->GetLatestFS   (
150     $opts{system},
151     $opts{filesystem}
152   );
153   
154   my $size = autoScale $fs{size};
155   my $used = autoScale $fs{used};
156   my $free = autoScale $fs{free};    
157
158   display start_Tr;
159     display td {class => 'data'},         $filesystem{filesystem};
160     display td {class => 'dataCentered'}, $filesystem{fstype};
161     display td {class => 'data'},         $filesystem{mount};
162     display td {class => 'dataRight'},    $size;
163     display td {class => 'dataRight'},    $used;
164     display td {class => 'dataRight'},    $free;
165     # TODO: Note that this percentages does not agree with df output. I'm not 
166     # sure why.
167     display td {class => 'dataCentered'},
168       sprintf ('%.0f%%', (($fs{reserve} + $fs{used}) / $fs{size} * 100));
169     display td {class => 'dataCentered'}, $filesystem{filesystemHist};
170     display td {class => 'dataCentered'}, "$filesystem{threshold}%";
171   display end_Tr;
172   
173   display end_table;
174   
175   return;  
176 } # displayInfo
177
178 sub displayControls() {
179   my $class = $opts{type} =~ /loadavg/i 
180             ? 'controls'
181             : 'filesystemControls';
182   
183   display start_table {
184     align       => 'center',
185     class       => $class,
186     cellspacing => 0,
187     width       => '800px',
188   };
189   
190   my $tagsButtons;
191   my ($systemLink, $systemButtons);
192
193   if ($opts{type} =~ /(vob|view)/i) {
194     $tagsButtons = makeTagsDropdown($opts{type}, $opts{tag});
195   } else {
196     $systemLink = span {id => 'systemLink'}, a {
197       href => "systemdetails.cgi?system=$opts{system}",
198     }, 'System';
199
200     $systemButtons = makeSystemDropdown(
201       $systemLink, 
202       $opts{system}, 
203       'updateFilesystems(this.value);updateSystemLink(this.value)'
204     );
205   } # if
206
207   my $startButtons = makeTimeDropdown(
208     $opts{type},
209     'startTimestamp',
210     $opts{system},
211     $opts{filesystem},
212     'Start',
213     $opts{start},
214     $opts{scaling},
215   );
216
217   my $endButtons = makeTimeDropdown(
218     $opts{type},
219     'endTimestamp',
220     $opts{system},
221     $opts{filesystem},
222     'End',
223     $opts{end},
224     $opts{scaling},
225   );
226
227   my $update;
228
229   if ($opts{type} eq 'loadavg') {
230     $update = "updateSystem('$opts{system}')";
231   } elsif ($opts{type} eq 'filsystem') {
232     $update = "updateFilesystem('$opts{system}','$opts{filesystem}')";
233   } else {
234     $update = ''; # TODO do I need something here?
235   } # if
236              
237   my $intervalButtons = makeIntervalDropdown(
238     'Interval',
239     $opts{scaling},
240     $update
241   );
242   
243   display start_Tr;
244     display td $startButtons;
245     display td $intervalButtons;
246     display td $opts{type} =~ /(vob|view)/i ? $tagsButtons : $systemButtons;
247   display end_Tr;
248
249   display start_Tr;
250     display td $endButtons;
251     display td 'Points', 
252       input {
253         name      => 'points',
254         value     => $opts{points},
255         class     => 'inputfield',
256         size      => 7,
257         style     => 'text-align: right',
258         maxlength => 7,
259       };  
260
261   if ($opts{type} eq 'loadavg') {
262     display td input {
263       type  => 'submit',
264       value => 'Draw Graph',
265     };
266   } else {
267     if ($opts{type} eq 'filesystem') {
268       my $filesystemButtons = makeFilesystemDropdown (
269         $opts{system}, 
270         'Filesystem',
271         undef,
272         "updateFilesystem('$opts{system}',this.value)",
273       );
274         
275       display td $filesystemButtons;
276     } else {
277       my $storagePoolButtons = makeStoragePoolDropdown ($opts{type}, $opts{tag});
278
279       display td $storagePoolButtons;
280     } # if
281     
282     display end_Tr;
283     display start_Tr;
284     display td {align => 'center', colspan => 3}, 
285       input {type => 'submit', value => 'Draw Graph'};
286   } # if
287   
288   display end_Tr;
289
290   display end_table;
291   
292   return;
293 } # displayControls
294
295 $clearadm = Clearadm->new;
296
297 my $title  = ucfirst($opts{type}) . ': ';
298
299 $title .= ucfirst $opts{system}           if $opts{system};
300 $title .= ":$opts{filesystem}"            if $opts{filesystem};
301 $title .= $opts{tag}                      if $opts{tag};
302 $title .= " Storage pool: $opts{storage}" if $opts{storage};
303
304 heading $title;
305
306 display h1 {class => 'center'}, $title;
307
308 display start_form {
309   method => 'get', 
310   action => 'plot.cgi',
311 };
312
313 # Some hidden fields to pass along
314 display input {type => 'hidden', name => 'type',   value => $opts{type}};
315 display input {type => 'hidden', name => 'region', value => $opts{region}};
316
317 displayGraph;
318 displayFSInfo;
319 displayControls;
320
321 display end_form;   
322
323 footing;
324
325 =pod
326
327 =head1 CONFIGURATION AND ENVIRONMENT
328
329 DEBUG: If set then $debug is set to this level.
330
331 VERBOSE: If set then $verbose is set to this level.
332
333 TRACE: If set then $trace is set to this level.
334
335 =head1 DEPENDENCIES
336
337 =head2 Perl Modules
338
339 L<CGI>
340
341 L<CGI::Carp|CGI::Carp>
342
343 L<FindBin>
344
345 L<Getopt::Long|Getopt::Long>
346
347 =head2 ClearSCM Perl Modules
348
349 =begin man 
350
351  Clearadm
352  ClearadmWeb
353  Display
354
355 =end man
356
357 =begin html
358
359 <blockquote>
360 <a href="http://clearscm.com/php/scm_man.php?file=clearadm/lib/Clearadm.pm">Clearadm</a><br>
361 <a href="http://clearscm.com/php/scm_man.php?file=clearadm/lib/ClearadmWeb.pm">ClearadmWeb</a><br>
362 <a href="http://clearscm.com/php/scm_man.php?file=lib/Display.pm">Display</a><br>
363 </blockquote>
364
365 =end html
366
367 =head1 BUGS AND LIMITATIONS
368
369 There are no known bugs in this script
370
371 Please report problems to Andrew DeFaria <Andrew@ClearSCM.com>.
372
373 =head1 LICENSE AND COPYRIGHT
374
375 Copyright (c) 2010, ClearSCM, Inc. All rights reserved.
376
377 =cut