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 |
} |