ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/JSOC/proj/util/scripts/archprobe.pl
Revision: 1.2
Committed: Wed Jul 31 23:42:10 2013 UTC (10 years, 1 month ago) by arta
Content type: text/plain
Branch: MAIN
CVS Tags: Ver_9-1, Ver_9-3, Ver_9-2, Ver_8-8, Ver_8-2, Ver_8-3, Ver_8-1, Ver_8-6, Ver_8-7, Ver_8-4, Ver_8-5, Ver_9-4, Ver_8-10, Ver_8-11, Ver_8-12, Ver_9-0
Changes since 1.1: +2 -0 lines
Log Message:
Update the exe path for ActiveState updates.

File Contents

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