ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/JSOC/proj/util/scripts/sumstapestat.pl
Revision: 1.21
Committed: Mon Feb 3 22:58:11 2014 UTC (9 years, 7 months ago) by arta
Content type: text/plain
Branch: MAIN
CVS Tags: Ver_9-1, Ver_LATEST, Ver_9-3, Ver_9-41, Ver_9-2, Ver_8-8, Ver_8-3, Ver_8-6, Ver_8-7, Ver_8-4, Ver_8-5, Ver_9-5, Ver_9-4, Ver_8-10, Ver_8-11, Ver_8-12, Ver_9-0, HEAD
Changes since 1.20: +50 -19 lines
Log Message:
Add a new parameter that allows callers to specify a single tape group on which to collect usage statistics.

File Contents

# Content
1 #!/home/jsoc/bin/linux_x86_64/activeperl -w
2
3 use DBI;
4 use DBD::Pg;
5 use Time::localtime;
6
7 use constant kDEBUG => 0;
8
9 use constant kStatDADP => "2";
10 use constant kStatDAAP => "4"; # archive pending
11 use constant kStatDAAEDDP => "32"; # archive pending too I guess
12 use constant kSubStatDAADP => "128"; # after archive completes, mark delete pending
13 use constant kGig => 1073741824;
14
15 use constant kTypeQueryAgg => "agg";
16 use constant kTypeQueryRaw => "raw";
17 use constant kTypeOrderSeries => "series";
18 use constant kTypeOrderGroup => "group";
19
20 use constant kMetricAll => "all";
21 use constant kMetricDPS => "dps"; # delete pending now (short)
22 use constant kMetricDPM => "dpm"; # delete pending in 100 days (medium)
23 use constant kMetricDPL => "dpl"; # delete pending >= 100 days (long)
24 use constant kMetricAP => "ap"; # archive pending
25
26 use constant kTempTable => "sumsstat";
27
28 # In raw mode, you cannot collect data on dpshort, dpmid, dplong, ap all at the same time.
29 # This will exhaust machine memory. Need to provide yet another flag to select which ONE
30 # of these metrics to obtain - only collect data on a single metric.
31
32 my($err);
33
34 my($dbname); # name of the db instance to connect to
35 my($dbhost); # name of the db host on which the db instance resides
36 my($dbport); # port on $dbhost through which connections are made
37 my($dbuser); # database user name (to connect with)
38 my($typequery); # type of query to perform (aggregate bytes over series, groups, or
39 # don't aggregate)
40 my($order); # series - order by series, then group, or group, order by group, then series
41 my($metric); # while column of data to produce (delete pending short, delete pending medium, delete pending long,
42 # archive pending)
43 my($delim); # separator between output columns (fixed-width columns if not supplied)
44 my(@forceGroup); # produce results for these groups only (a comma-separated list of groups)
45
46 my($dsn); # database connection arguments
47 my($dbh); # database handle
48 my($stmnt);
49 my($row);
50 my($rowb);
51 my($rrows);
52 my($rrowsb);
53
54 my($queryfunc);
55
56 my($now);
57 my($nowplus100d);
58
59 my(%delnow);
60 my(%delwi100d);
61 my(%dellater);
62 my(%archivepend);
63
64 if ($#ARGV < 3)
65 {
66 print "Improper argument list.\n";
67 exit(1);
68 }
69
70 $dbname = $ARGV[0];
71 $dbhost = $ARGV[1];
72 $dbport = $ARGV[2];
73 $dbuser = $ARGV[3];
74
75 if ($#ARGV >= 4)
76 {
77 if (lc($ARGV[4]) eq kTypeQueryAgg)
78 {
79 $typequery = kTypeQueryAgg; $queryfunc = \&GenQueryA;
80 }
81 elsif (lc($ARGV[4]) eq kTypeQueryRaw)
82 {
83 $typequery = kTypeQueryRaw; $queryfunc = \&GenQueryB;
84 }
85 else
86 {
87 print "Invalid query type $ARGV[4].\n"; exit(1);
88 }
89 }
90 else
91 {
92 $typequery = kTypeQueryAgg;
93 $queryfunc = \&GenQueryA;
94 $order = kTypeOrderSeries;
95 }
96
97 if ($#ARGV >= 5)
98 {
99 if (lc($ARGV[5]) eq kTypeOrderSeries)
100 {
101 $order = kTypeOrderSeries;
102 }
103 elsif (lc($ARGV[5]) eq kTypeOrderGroup)
104 {
105 $order = kTypeOrderGroup;
106 }
107 else
108 {
109 print "Invalid order specified $ARGV[5].\n"; exit(1);
110 }
111 }
112 else
113 {
114 $order = kTypeOrderSeries;
115 }
116
117 if ($#ARGV >= 6)
118 {
119 if (lc($ARGV[6]) eq kMetricAll)
120 {
121 if ($typequery eq kTypeQueryRaw)
122 {
123 print "Metric all cannot be used with an un-aggregated query.\n";
124 exit(1);
125 }
126
127 $metric = kMetricAll;
128 }
129 elsif (lc($ARGV[6]) eq kMetricDPS)
130 {
131 $metric = kMetricDPS;
132 }
133 elsif (lc($ARGV[6]) eq kMetricDPM)
134 {
135 $metric = kMetricDPM;
136 }
137 elsif (lc($ARGV[6]) eq kMetricDPL)
138 {
139 $metric = kMetricDPL;
140 }
141 elsif (lc($ARGV[6]) eq kMetricAP)
142 {
143 $metric = kMetricAP;
144 }
145 else
146 {
147 print "Invalid metric specified $ARGV[6].\n"; exit(1);
148 }
149 }
150 else
151 {
152 if ($typequery eq kTypeQueryRaw)
153 {
154 # For non-aggregated queries, do not attempt to perform multiple queries for multiple metrics
155 $metric = kMetricAP;
156 }
157 else
158 {
159 $metric = kMetricAll;
160 }
161 }
162
163 if ($#ARGV >= 7)
164 {
165 $delim = substr($ARGV[7], 0, 1);
166 }
167
168 @forceGroup = ();
169 if ($#ARGV >= 8)
170 {
171 @forceGroup = split(qr(,), $ARGV[8]);
172 }
173
174 $err = 0;
175
176 # connect to the database
177 $dsn = "dbi:Pg:dbname=$dbname;host=$dbhost;port=$dbport";
178 print "Connection to database with '$dsn' as user '$dbuser' ... ";
179
180 # Despite ALL documentation saying otherwise, it looks like the error codes/string
181 # provided by DBI are all UNDEFINED, unless there is some kind of failure. So,
182 # never try to look at $dbh->err or $dbh->errstr if the call succeeded.
183 $dbh = DBI->connect($dsn, $dbuser, ''); # will need to put pass in .pg_pass
184
185 if (defined($dbh))
186 {
187 my(@allGroups);
188
189 print "success!\n";
190
191 # Loop over storage groups
192
193 # If the forceGroup option is specified, then generate results for only the tape groups listed in @forceGroup. Otherwise
194 # query the db to obtain a list of all groups. It is possible that the caller will specify a group that doesn't exist.
195 if (@forceGroup > 0)
196 {
197 push(@allGroups, @forceGroup);
198 }
199 else
200 {
201 # db query to fetch a list of all groups
202 $stmnt = "SELECT group_id FROM sum_partn_alloc GROUP BY group_id ORDER BY group_id";
203 $rrows = $dbh->selectall_arrayref($stmnt, undef);
204 $err = !(NoErr($rrows, \$dbh, $stmnt));
205
206 if (!$err)
207 {
208 foreach $row (@$rrows)
209 {
210 push(@allGroups, $row->[0]);
211 }
212 }
213 else
214 {
215 print "failure!!!!\n";
216 $err = 1;
217 }
218 }
219
220 if (!$err)
221 {
222 my($timenow) = time();
223 my($timeo) = localtime($timenow);
224 my($timeltro) = localtime($timenow + 100 * 24 * 60 * 60);
225
226 $now = sprintf("%04d%02d%02d%02d%02d", $timeo->year() + 1900, $timeo->mon() + 1, $timeo->mday(), $timeo->hour(), $timeo->min());
227 $nowplus100d = sprintf("%04d%02d%02d%02d%02d", $timeltro->year() + 1900, $timeltro->mon() + 1, $timeltro->mday(), $timeltro->hour(), $timeltro->min());
228
229
230 if ($typequery)
231 {
232 # Create a temporary table to hold pre-sorted results.
233 $stmnt = "CREATE TEMPORARY TABLE " . kTempTable . "(tgroup integer not null, series varchar(64) not null, metric varchar(8), aggbytes bigint default 0)";
234 ExecStatement(\$dbh, $stmnt, 1, "Unable to create temporary table " . "'kTempTable'" . ".\n");
235
236 $stmnt = "CREATE INDEX " . kTempTable . "_group_idx on " . kTempTable . "(tgroup, lower(series))";
237 ExecStatement(\$dbh, $stmnt, 1, "Unable to create index on temporary table " . "'kTempTable'" . ".\n");
238
239 $stmnt = "CREATE INDEX " . kTempTable . "_series_idx on " . kTempTable . "(lower(series), tgroup)";
240 ExecStatement(\$dbh, $stmnt, 1, "Unable to create index on temporary table " . "'kTempTable'" . ".\n");
241 }
242
243 # $rrows is a reference to an array; the array is an array of refereces to an array, so $row
244 # is a reference to an array that has just one element (since the SELECT statement has just
245 # one column). This element is the namespace name.
246 foreach my $group (@allGroups)
247 {
248 if (kDEBUG)
249 {
250 $group = 1;
251 }
252
253 # Delete now
254 if ($metric eq kMetricAll || $metric eq kMetricDPS)
255 {
256 $err = !$queryfunc->(\$dbh, $group, kStatDAAP . " AND archive_substatus = " . kStatDAAEDDP . " OR status = " . kStatDADP, "effective_date < '$now'", $typequery, $order, \%delnow, kMetricDPS);
257 }
258
259 # Delete <= 100 days AND > now
260 if ($metric eq kMetricAll || $metric eq kMetricDPM)
261 {
262 if (!$err)
263 {
264 $err = !$queryfunc->(\$dbh, $group, kStatDAAP . " AND archive_substatus = " . kStatDAAEDDP . " OR status = " . kStatDADP, "effective_date <= '$nowplus100d' AND effective_date >= '$now'", $typequery, $order, \%delwi100d, kMetricDPM);
265 }
266 }
267
268 if ($metric eq kMetricAll || $metric eq kMetricDPL)
269 {
270 if (!$err)
271 {
272 $err = !$queryfunc->(\$dbh, $group, kStatDAAP . " AND archive_substatus = " . kStatDAAEDDP . " OR status = " . kStatDADP, "effective_date > '$nowplus100d'", $typequery, $order, \%dellater, kMetricDPL);
273 }
274 }
275
276 # Archive Pending
277 if ($metric eq kMetricAll || $metric eq kMetricAP)
278 {
279 if (!$err)
280 {
281 $err = !$queryfunc->(\$dbh, $group, kStatDAAP . " AND archive_substatus = " . kSubStatDAADP, "", $typequery, $order, \%archivepend, kMetricAP);
282 }
283 }
284
285 if (kDEBUG)
286 {
287 last;
288 }
289 } # loop over storage groups
290
291 SortAndPrintResults(\%delnow, \%delwi100d, \%dellater, \%archivepend, $typequery, $order, $metric, $delim, $dbh);
292 }
293 }
294 else
295 {
296 print "failure!!!!\n";
297 $err = 1;
298 }
299
300 # AL FINAL
301 exit($err);
302
303 # Aggregate
304 sub GenQueryA
305 {
306 my($dbh) = $_[0]; # reference to a reference
307 my($group) = $_[1];
308 my($status) = $_[2];
309 my($datewhere) = $_[3];
310 my($typequery) = $_[4];
311 my($order) = $_[5];
312 my($container) = $_[6]; # reference
313 my($metric) = $_[7];
314
315 my($ok) = 1;
316
317 my($stmnt);
318
319 if (length($datewhere) > 0)
320 {
321 $datewhere = " AND $datewhere";
322 }
323
324 $stmnt = "INSERT INTO " . kTempTable . " (tgroup, series, metric, aggbytes) (SELECT '$group', main.owning_series, '$metric', sum(bytes) FROM (SELECT ds_index, group_id, bytes FROM sum_partn_alloc WHERE (status = $status) AND group_id = $group$datewhere) AS partn, (SELECT ds_index, owning_series FROM sum_main) AS main WHERE partn.ds_index = main.ds_index GROUP BY partn.group_id, main.owning_series)";
325
326 if (kDEBUG)
327 {
328 print "Query is:\n$stmnt\n";
329 }
330
331 ExecStatement($dbh, $stmnt, 1, "Unable to insert data into temporary table.\n");
332
333 return $ok;
334 }
335
336 # Don't aggregate
337 sub GenQueryB
338 {
339 my($dbh) = $_[0]; # reference to a reference
340 my($group) = $_[1];
341 my($status) = $_[2];
342 my($datewhere) = $_[3];
343 my($typequery) = $_[4];
344 my($order) = $_[5];
345 my($container) = $_[6]; # reference
346 my($metric) = $_[7];
347
348 my($ok) = 1;
349
350 my($stmnt);
351 my($rrows);
352
353 if (length($datewhere) > 0)
354 {
355 $datewhere = " AND $datewhere";
356 }
357
358 $stmnt = "SELECT main.owning_series, main.ds_index, main.online_loc, partn.bytes FROM (SELECT ds_index, group_id, bytes FROM sum_partn_alloc WHERE (status = $status) AND group_id = $group$datewhere) AS partn, (SELECT ds_index, owning_series, online_loc FROM sum_main) AS main WHERE partn.ds_index = main.ds_index ORDER BY lower(main.owning_series), main.ds_index";
359
360 if (kDEBUG)
361 {
362 print "Query is:\n$stmnt\n";
363 }
364
365 $rrows = $$dbh->selectall_arrayref($stmnt, undef);
366 $ok = NoErr($rrows, $$dbh, $stmnt);
367
368 if ($ok)
369 {
370 # save results
371 $ok = SaveResults($rrows, $group, $typequery, $order, $container);
372 }
373
374 return $ok;
375 }
376
377 sub SaveResults
378 {
379 my($rrows) = $_[0]; # reference to array
380 my($group) = $_[1]; # scalar
381 my($typequery) = $_[2]; # scalar
382 my($order) = $_[3]; # scalar
383 my($container) = $_[4]; # reference to hash
384
385 my($row);
386 my($ok) = 1;
387
388 if ($typequery eq kTypeQueryAgg)
389 {
390 # Changed to use a temporary table to hold results. No need to use hash arrays
391 # to hold the data.
392 }
393 elsif ($typequery eq kTypeQueryRaw)
394 {
395 if ($order eq kTypeOrderSeries)
396 {
397 foreach $row (@$rrows)
398 {
399 if (defined($container->{lc($row->[0])}))
400 {
401 push(@{$container->{lc($row->[0])}->{$group}}, [$row->[1], $row->[2], $row->[3]])
402 }
403 else
404 {
405 $container->{lc($row->[0])} = {$group => [[$row->[1], $row->[2], $row->[3]]]};
406 }
407 }
408 }
409 elsif ($order eq kTypeOrderGroup)
410 {
411 $container->{$group} = [];
412
413 foreach $row (@$rrows)
414 {
415 push(@{$container->{$group}}, [lc($row->[0]), $row->[1], $row->[2], $row->[3]]);
416 }
417 }
418 else
419 {
420 print "Invalid column $order by which to order.\n";
421 $ok = 0;
422 }
423 }
424 else
425 {
426 print "Invalid query type $typequery.\n";
427 $ok = 0;
428 }
429
430 return $ok;
431 }
432
433 sub NoErr
434 {
435 my($rv) = $_[0];
436 my($dbh) = $_[1];
437 my($stmnt) = $_[2];
438 my($ok) = 1;
439
440 if (!defined($rv) || !$rv)
441 {
442 if (defined($$dbh) && defined($$dbh->err))
443 {
444 print STDERR "Error " . $$dbh->errstr . ": Statement '$stmnt' failed.\n";
445 }
446
447 $ok = 0;
448 }
449
450 return $ok;
451 }
452
453 sub ExecStatement
454 {
455 my($dbh, $stmnt, $doit, $msg) = @_;
456 my($res);
457
458 print "executing db statement ==> $stmnt\n";
459
460 if ($doit)
461 {
462 $res = $$dbh->do($stmnt);
463 NoErr($res, $dbh, $stmnt) || die $msg;
464 }
465 }
466
467 use constant kTypeSortNumrcAsc => 1;
468 use constant kTypeSortAlphaAsc => 2;
469
470 sub CombineHashKeys
471 {
472 my($typesort) = $_[0];
473 my($out) = $_[1]; # reference
474 my(@hashes) = @_[2..$#_]; # array of hash references
475 my($ahash);
476 my(@superduper);
477 my(@sorted);
478 my(%seen);
479 my($elem);
480
481 my($ok) = 1;
482
483 foreach $ahash (@hashes)
484 {
485 if (defined($ahash))
486 {
487 push(@superduper, keys(%$ahash));
488 }
489 }
490
491 # sort
492 if ($typesort eq kTypeSortNumrcAsc)
493 {
494 @sorted = sort {$a <=> $b} @superduper;
495 }
496 elsif ($typesort eq kTypeSortAlphaAsc)
497 {
498 @sorted = sort {$a cmp $b} @superduper;
499 }
500 else
501 {
502 print "Unsupported sort operation '$typesort'.\n";
503 $ok = 0;
504 }
505
506 # eliminate duplicates
507 foreach $elem (@sorted)
508 {
509 push(@$out, $elem) unless $seen{$elem}++;
510 }
511
512 return $ok;
513 }
514
515 sub PrintRow
516 {
517 my($delim) = $_[0];
518 my($firstarg) = $_[1];
519 my($secondarg) = $_[2];
520 my($metric) = $_[3];
521 my($hbytes) = $_[4]; # reference
522 my($dformat) = $_[5]; # reference to delimted string format
523 my($fformat) = $_[6]; # reference to fixed-width string format
524
525 my($line);
526 my($actualformat);
527
528 $actualformat = defined($delim) ? $dformat : $fformat;
529
530 if ($metric eq kMetricAll)
531 {
532 $line = sprintf($$actualformat,
533 $firstarg,
534 $secondarg,
535 defined($hbytes->{+kMetricDPS}) ? $hbytes->{+kMetricDPS} / kGig : 0,
536 defined($hbytes->{+kMetricDPM}) ? $hbytes->{+kMetricDPM} / kGig : 0,
537 defined($hbytes->{+kMetricDPL}) ? $hbytes->{+kMetricDPL} / kGig : 0,
538 defined($hbytes->{+kMetricAP}) ? $hbytes->{+kMetricAP} / kGig : 0);
539 }
540 else
541 {
542 $line = sprintf($$actualformat,
543 $firstarg,
544 $secondarg,
545 defined($hbytes->{$metric}) ? $hbytes->{$metric} / kGig : 0);
546 }
547
548 print "$line\n";
549 }
550
551 # Orders by series, group first. If caller requests ordering by group, series, the
552 # rows are re-ordered.
553 sub SortAndPrintResults
554 {
555 # Each of the elements in each of these hash arrays is a reference to a hash array.
556 # The parent hash array is keyed by series name. Each child hash array is
557 # keyed by group with byte count values. The parent hash arrays do not necessarily
558 # have the same set of series.
559 my($delnow) = $_[0];
560 my($delwi100d) = $_[1];
561 my($dellater) = $_[2];
562 my($archivepend) = $_[3];
563 my($typequery) = $_[4];
564 my($order) = $_[5];
565 my($metric) = $_[6];
566 my($delim) = $_[7];
567 my($dbh) = $_[8];
568
569 my(@serieslist);
570 my(@grouplist);
571 my($elem);
572 my($series);
573 my($group);
574 my($line);
575
576 my(@sorted);
577 my($dnow);
578 my($d100);
579 my($dlater);
580 my($ap);
581 my($metricval);
582
583 my(%metricheaders);
584 my(%containers);
585 my(@contkeys);
586 my($contkey);
587
588 my($stmnt);
589 my($rrows);
590 my($row);
591
592 my($ok);
593
594 $ok = 1;
595
596 %containers = (kMetricDPS, $delnow, kMetricDPM, $delwi100d, kMetricDPL, $dellater, kMetricAP, $archivepend);
597 @contkeys = keys(%containers);
598
599 print "__DATA__\n";
600
601 if ($typequery eq kTypeQueryAgg)
602 {
603 my(%hbytes); # sum(bytes) of the 4 containers for current series.
604
605 %metricheaders = (kMetricDPS, "DP Now (GB)", kMetricDPM, "DP <= 100d (GB)", kMetricDPL, "DP > 100d (GB)", kMetricAP, "AP (GB)");
606
607 if ($order eq kTypeOrderSeries)
608 {
609 # type - agg; order - series
610 if (defined($delim))
611 {
612 if ($metric eq kMetricAll)
613 {
614 $line = sprintf("series${delim}group${delim}$metricheaders{+kMetricDPS}${delim}$metricheaders{+kMetricDPM}${delim}$metricheaders{+kMetricDPL}${delim}$metricheaders{+kMetricAP}");
615 }
616 else
617 {
618 $line = sprintf("series${delim}group${delim}$metricheaders{$metric}");
619 }
620 }
621 else
622 {
623 if ($metric eq kMetricAll)
624 {
625 $line = sprintf("%-48s%-8s%-24s%-24s%-24s%-24s", "series", "group", $metricheaders{+kMetricDPS}, $metricheaders{+kMetricDPM}, $metricheaders{+kMetricDPL}, $metricheaders{+kMetricAP});
626 }
627 else
628 {
629 $line = sprintf("%-48s%-8s%-24s", "series", "group", $metricheaders{$metric});
630 }
631 }
632
633 print "$line\n";
634
635 # Just use the db to do the sorting on the temporary table containing the data.
636 $stmnt = "SELECT series, tgroup, metric, aggbytes FROM " . kTempTable . " ORDER BY lower(series), tgroup";
637
638 if ($ok)
639 {
640 $rrows = $dbh->selectall_arrayref($stmnt, undef);
641 $ok = NoErr($rrows, \$dbh, $stmnt);
642 }
643
644 $group = "";
645 $series = "";
646
647 if ($ok)
648 {
649 %hbytes = ();
650
651 if ($metric eq kMetricAll)
652 {
653 if (defined($delim))
654 {
655 $dformat = "%s${delim}%s${delim}%f${delim}%f${delim}%f${delim}%f";
656 }
657 else
658 {
659 $fformat = "%-48s%-8d%-24f%-24f%-24f%-24f";
660 }
661 }
662 else
663 {
664 if (defined($delim))
665 {
666 $dformat = "%s${delim}%s${delim}%f";
667 }
668 else
669 {
670 $fformat = "%-48s%-8d%-24f";
671 }
672 }
673
674 foreach $row (@$rrows)
675 {
676 if ((length($series) > 0 && $series ne $row->[0]) ||
677 (length($group) > 0 && $group ne $row->[1]))
678 {
679 PrintRow($delim, $series, $group, $metric, \%hbytes, \$dformat, \$fformat);
680 %hbytes = ();
681 }
682
683 $series = $row->[0];
684 $group = $row->[1];
685 $hbytes{$row->[2]} = $row->[3];
686 }
687
688 # Must print last row since only the previous row is printed in the loop above
689 PrintRow($delim, $series, $group, $metric, \%hbytes, \$dformat, \$fformat);
690 }
691 }
692 elsif ($order eq kTypeOrderGroup)
693 {
694 # type - agg; order - group
695 if (defined($delim))
696 {
697 if ($metric eq kMetricAll)
698 {
699 $line = sprintf("group${delim}series${delim}$metricheaders{+kMetricDPS}${delim}$metricheaders{+kMetricDPM}${delim}$metricheaders{+kMetricDPL}${delim}$metricheaders{+kMetricAP}");
700 }
701 else
702 {
703 $line = sprintf("group${delim}series${delim}$metricheaders{$metric}");
704 }
705 }
706 else
707 {
708 if ($metric eq kMetricAll)
709 {
710 $line = sprintf("%-8s%-48s%-24s%-24s%-24s%-24s", "group", "series", $metricheaders{+kMetricDPS}, $metricheaders{+kMetricDPM}, $metricheaders{+kMetricDPL}, $metricheaders{+kMetricAP});
711 }
712 else
713 {
714 $line = sprintf("%-8s%-48s%-24s", "group", "series", $metricheaders{$metric});
715 }
716 }
717
718 print "$line\n";
719
720 # Just use the db to do the sorting on the temporary table containing the data.
721 $stmnt = "SELECT tgroup, series, metric, aggbytes FROM " . kTempTable . " ORDER BY tgroup, lower(series)";
722
723 if ($ok)
724 {
725 $rrows = $dbh->selectall_arrayref($stmnt, undef);
726 $ok = NoErr($rrows, \$dbh, $stmnt);
727 }
728
729 $group = "";
730 $series = "";
731
732 if ($ok)
733 {
734 %hbytes = ();
735
736 if ($metric eq kMetricAll)
737 {
738 if (defined($delim))
739 {
740 $dformat = "%s${delim}%s${delim}%f${delim}%f${delim}%f${delim}%f";
741 }
742 else
743 {
744 $fformat = "%-8d%-48s%-24f%-24f%-24f%-24f";
745 }
746 }
747 else
748 {
749 if (defined($delim))
750 {
751 $dformat = "%s${delim}%s${delim}%f";
752 }
753 else
754 {
755 $fformat = "%-8d%-48s%-24f";
756 }
757 }
758
759 foreach $row (@$rrows)
760 {
761 if ((length($group) > 0 && $group ne $row->[0]) ||
762 (length($series) > 0 && $series ne $row->[1]))
763 {
764 PrintRow($delim, $group, $series, $metric, \%hbytes, \$dformat, \$fformat);
765 %hbytes = ();
766 }
767
768 $group = $row->[0];
769 $series = $row->[1];
770 $hbytes{$row->[2]} = $row->[3];
771 }
772
773 # Must print last row since only the previous row is printed in the loop above
774 PrintRow($delim, $group, $series, $metric, \%hbytes, \$dformat, \$fformat);
775 }
776 }
777 else
778 {
779 print "Invalid column $order by which to order.\n";
780
781 }
782 }
783 elsif ($typequery eq kTypeQueryRaw)
784 {
785 # **** Can only work with a single container at a time when the query type is raw!! Each container uses up a
786 # huge amount of memory, so this script must be modified to handle a single one specified on the cmd-line.
787 # row is series, ds_index, sudir, bytes
788 my(%topheaders);
789
790 # Only one of the containers should be non-empty - if that is not the case, that is an error
791 if ($metric eq kMetricAll)
792 {
793 print "Cannot generate non-aggregate report for more than one metric.\n";
794 $ok = 0;
795 }
796 else
797 {
798 %metricheaders = (kMetricDPS, "DP Now (bytes)", kMetricDPM, "DP <= 100d (bytes)", kMetricDPL, "DP > 100d (bytes)", kMetricAP, "AP (bytes)");
799 %topheaders = (kMetricDPS, "*** DP Now ***", kMetricDPM, "*** DP <= 100d ***", kMetricDPL, "*** DP > 100d ***", kMetricAP, "*** AP ***");
800
801 my($sunum);
802 my($sudir);
803 my($rowdata);
804
805 if ($order eq kTypeOrderSeries)
806 {
807 # type - raw; order - series
808 print "$topheaders{$metric}\n";
809 if (defined($delim))
810 {
811 $line = "series${delim}group${delim}sunum${delim}sudir${delim}$metricheaders{$metric}";
812 }
813 else
814 {
815 $line = sprintf("%-32s%-8s%-16s%-24s%-24s", "series", "group", "sunum", "sudir", $metricheaders{$metric});
816 }
817
818 print "$line\n";
819
820 if (CombineHashKeys(kTypeSortAlphaAsc, \@serieslist, $containers{$metric}))
821 {
822 foreach $elem (@serieslist)
823 {
824 $series = $elem;
825 @grouplist = ();
826
827 if (CombineHashKeys(kTypeSortNumrcAsc, \@grouplist, $containers{$metric}->{$series}))
828 {
829 foreach $group (@grouplist)
830 {
831 if (defined($containers{$metric}->{$series}->{$group}))
832 {
833 # $containers{$metric}->{$series}->{$group} is reference to an array with array references
834 # as elements. The child arrays have sunum, sudir, and bytes
835 # as elements.
836 foreach $rowdata (@{$containers{$metric}->{$series}->{$group}})
837 {
838 # $rowdata is a reference to an array containing sunum, sudir, and bytes
839 # as elements.
840 $sunum = $rowdata->[0];
841 $sudir = $rowdata->[1];
842 $metricval = $rowdata->[2];
843
844 if (defined($delim))
845 {
846 $line = sprintf("$series${delim}$group${delim}$sunum${delim}$sudir${delim}%d", $metricval);
847 }
848 else
849 {
850 $line = sprintf("%-32s%-8d%-16s%-24s%-24d", $series, $group, $sunum, $sudir, $metricval);
851 }
852
853 print "$line\n";
854 }
855 }
856 }
857 }
858 else
859 {
860 print "Problem creating group list - continuing.\n";
861 }
862 }
863 }
864 else
865 {
866 print "Problem creating series list - bailing.\n";
867 }
868 }
869 elsif ($order eq kTypeOrderGroup)
870 {
871 my($sunum);
872 my($sudir);
873 my($rowdata);
874
875 print "$topheaders{$metric}\n";
876 if (defined($delim))
877 {
878 $line = "group${delim}series${delim}sunum${delim}sudir${delim}$metricheaders{$metric}";
879 }
880 else
881 {
882 $line = sprintf("%-8s%-32s%-16s%-24s%-24s", "group", "series", "sunum", "sudir", $metricheaders{$metric});
883 }
884
885 print "$line\n";
886
887 # The data in the containers are ordered by group, series. The tuples are
888 # (series, ds_index, sudir, bytes). So there is very little work to do here.
889 @grouplist = ();
890
891 if (CombineHashKeys(kTypeSortNumrcAsc, \@grouplist, $containers{$metric}))
892 {
893 foreach $group (@grouplist)
894 {
895 foreach $rowdata (@{$containers{$metric}->{$group}})
896 {
897 $series = $rowdata->[0];
898 $sunum = $rowdata->[1];
899 $sudir = $rowdata->[2];
900 $metricval = $rowdata->[3];
901
902 if (defined($delim))
903 {
904 $line = sprintf("$group${delim}$series${delim}$sunum${delim}$sudir${delim}%d", $metricval);
905 }
906 else
907 {
908 $line = sprintf("%-8d%-32s%-16s%-24s%-24d", $group, $series, $sunum, $sudir, $metricval);
909 }
910
911 print "$line\n";
912 }
913 }
914 }
915 }
916 else
917 {
918 print "Invalid column $order by which to order.\n";
919 $ok = 0;
920 }
921 }
922 }
923 else
924 {
925 print "Invalid query type $typequery.\n";
926 }
927
928 print "__END__\n";
929
930 # TODO - print out totals by group
931 }