X-Git-Url: https://git.gag.com/?p=debian%2Famanda;a=blobdiff_plain;f=perl%2FAmanda%2FReport%2Fhuman.pm;h=84ff5c3ebb21e3bdf619ec2ed04850583982efce;hp=2a7d6ec2ab3ab691284dcff4eb2479f38afe8011;hb=b116e9366c7b2ea2c2eb53b0a13df4090e176235;hpb=fd48f3e498442f0cbff5f3606c7c403d0566150e diff --git a/perl/Amanda/Report/human.pm b/perl/Amanda/Report/human.pm index 2a7d6ec..84ff5c3 100644 --- a/perl/Amanda/Report/human.pm +++ b/perl/Amanda/Report/human.pm @@ -45,7 +45,7 @@ use constant COLSPEC_FORMAT => 5; # sprintf format use constant COLSPEC_TITLE => 6; # column title use constant PROGRAM_ORDER => - qw(amdump planner amflush driver dumper chunker taper reporter); + qw(amdump planner amflush amvault driver dumper chunker taper reporter); ## helper functions @@ -211,72 +211,75 @@ sub calculate_stats foreach my $dle_entry (@dles) { # $dle_entry = [$hostname, $disk] - my $dle = $report->get_dle_info(@$dle_entry); - - foreach my $try ( @{ $dle->{tries} } ) { - - my $level = exists $try->{dumper} ? $try->{dumper}{'level'} : - exists $try->{taper} ? $try->{taper}{'level'} : - 0; - my $stats = ($level > 0) ? $incr_stats : $full_stats; - - # compute out size, skipping flushes (tries without a dumper run) - my $outsize = 0; - if (exists $try->{dumper} - && exists $try->{chunker} && defined $try->{chunker}->{kb} - && ( $try->{chunker}{status} eq 'success' - || $try->{chunker}{status} eq 'partial')) { - $outsize = $try->{chunker}->{kb}; - } elsif (exists $try->{dumper} - && exists $try->{taper} && defined $try->{taper}->{kb} - && ( $try->{taper}{status} eq 'done' - || $try->{taper}{status} eq 'partial')) { - $outsize = $try->{taper}->{kb}; - } + my $dle = $report->get_dle_info(@$dle_entry); + my $alldumps = $dle->{'dumps'}; + + while( my ($timestamp, $tries) = each %$alldumps ) { + foreach my $try ( @$tries ) { + + my $level = exists $try->{dumper} ? $try->{dumper}{'level'} : + exists $try->{taper} ? $try->{taper}{'level'} : + 0; + my $stats = ($level > 0) ? $incr_stats : $full_stats; + + # compute out size, skipping flushes (tries without a dumper run) + my $outsize = 0; + if (exists $try->{dumper} + && exists $try->{chunker} && defined $try->{chunker}->{kb} + && ( $try->{chunker}{status} eq 'success' + || $try->{chunker}{status} eq 'partial')) { + $outsize = $try->{chunker}->{kb}; + } elsif (exists $try->{dumper} + && exists $try->{taper} && defined $try->{taper}->{kb} + && ( $try->{taper}{status} eq 'done' + || $try->{taper}{status} eq 'partial')) { + $outsize = $try->{taper}->{kb}; + } - # compute orig size, again skipping flushes - my $origsize = 0; - if ( exists $try->{dumper} - && ( $try->{dumper}{status} eq 'success' - || $try->{dumper}{status} eq 'strange')) { - - $origsize = $try->{dumper}{orig_kb}; - $stats->{dumper_time} += $try->{dumper}{sec}; - $stats->{dumpdisk_count}++; # count this as a dumped filesystem - $dumpdisks->[$try->{dumper}{'level'}]++; #by level count - } elsif (exists $try->{dumper} - && exists $try->{taper} && defined $try->{taper}->{kb} - && ( $try->{taper}{status} eq 'done' - || $try->{taper}{status} eq 'partial')) { - # orig_kb doesn't always exist (older logfiles) - if ($try->{taper}->{orig_kb}) { - $origsize = $try->{taper}->{orig_kb}; + # compute orig size, again skipping flushes + my $origsize = 0; + if ( exists $try->{dumper} + && ( $try->{dumper}{status} eq 'success' + || $try->{dumper}{status} eq 'strange')) { + + $origsize = $try->{dumper}{orig_kb}; + $stats->{dumper_time} += $try->{dumper}{sec}; + $stats->{dumpdisk_count}++; # count this as a dumped filesystem + $dumpdisks->[$try->{dumper}{'level'}]++; #by level count + } elsif (exists $try->{dumper} + && exists $try->{taper} && defined $try->{taper}->{kb} + && ( $try->{taper}{status} eq 'done' + || $try->{taper}{status} eq 'partial')) { + # orig_kb doesn't always exist (older logfiles) + if ($try->{taper}->{orig_kb}) { + $origsize = $try->{taper}->{orig_kb}; + } } - } - if ( exists $try->{taper} - && ( $try->{taper}{status} eq 'done' - || $try->{taper}{status} eq 'partial')) { + if ( exists $try->{taper} + && ( $try->{taper}{status} eq 'done' + || $try->{taper}{status} eq 'partial')) { - $stats->{tapesize} += $try->{taper}{kb}; - $stats->{taper_time} += $try->{taper}{sec}; - $stats->{tapepart_count} += @{ $try->{taper}{parts} } - if $try->{taper}{parts}; - $stats->{tapedisk_count}++; + $stats->{tapesize} += $try->{taper}{kb}; + $stats->{taper_time} += $try->{taper}{sec}; + $stats->{tapepart_count} += @{ $try->{taper}{parts} } + if $try->{taper}{parts}; + $stats->{tapedisk_count}++; - $tapedisks->[ $try->{taper}{level} ]++; #by level count - $tapeparts->[$try->{taper}{level}] += @{ $try->{taper}{parts} } - if $try->{taper}{parts}; - } + $tapedisks->[ $try->{taper}{level} ]++; #by level count + $tapeparts->[$try->{taper}{level}] += @{ $try->{taper}{parts} } + if $try->{taper}{parts}; + } - # add those values to the stats - $stats->{'origsize'} += $origsize; - $stats->{'outsize'} += $outsize; + # add those values to the stats + $stats->{'origsize'} += $origsize; + $stats->{'outsize'} += $outsize; - # if the sizes differ, then we have a compressed dump, so also add it to - # c{out,orig}size - $stats->{'corigsize'} += $origsize; - $stats->{'coutsize'} += $outsize; + # if the sizes differ, then we have a compressed dump, so also add it to + # c{out,orig}size + $stats->{'corigsize'} += $origsize; + $stats->{'coutsize'} += $outsize; + } } } @@ -395,10 +398,12 @@ sub output_tapeinfo if (@$tape_labels > 0) { - # slightly different sentence for amflush and amdump + # slightly different sentence depending on the run type my $tapelist_str; if ($report->get_flag("amflush_run")) { $tapelist_str = "The dumps were flushed "; + } elsif ($report->get_flag("amvault_run")) { + $tapelist_str = "The dumps were vaulted "; } else { $tapelist_str = "These dumps were "; } @@ -410,14 +415,15 @@ sub output_tapeinfo if (my $tape_error = $report->get_program_info("taper", "tape_error", undef)) { - $tape_error =~ s{^no-tape }{}; - if ($tape_error =~ /^\[CONFIG:/) { - $tape_error =~ s/^\[CONFIG://; + if ($report->get_program_info("taper", "failure_from", undef) eq "config") { + # remove leading [ and trailling ] + $tape_error =~ s/^\[//; $tape_error =~ s/\]$//; print $fh "Not using all tapes because $tape_error.\n"; } else { print $fh "*** A TAPE ERROR OCCURRED: $tape_error.\n"; } + #$tape_error =~ s{^no-tape }{}; } ## if this is a historical report, do not generate holding disk @@ -466,6 +472,14 @@ sub output_tapeinfo if ( my $tape_label = Amanda::Tapelist::get_last_reusable_tape_label($i) ) { + if ($nb_new_tape) { + print $fh ", " if !$first; + print $fh "$nb_new_tape new tape" + . ( $nb_new_tape > 1 ? "s" : "" ); + $nb_new_tape = 0; + $first = 0; + } + print $fh $first ? "" : ", ", $tape_label; @@ -517,12 +531,12 @@ sub output_error_summaries foreach my $dle_entry (@dles) { my ($hostname, $disk) = @$dle_entry; - my $tries = $report->get_dle_info(@$dle_entry, "tries"); + my $alldumps = $report->get_dle_info(@$dle_entry, "dumps"); my $dle = $report->get_dle_info($hostname, $disk); my $qdisk = quote_string($disk); - my $failed = 0; - if ($report->get_flag('results_missing') and !@$tries and + if ($report->get_flag('results_missing') and + !defined($alldumps->{$report->{run_timestamp}}) and !$dle->{planner}) { push @missing_failures, "$hostname $qdisk RESULTS MISSING"; } @@ -537,53 +551,70 @@ sub output_error_summaries push @planner_failures, "$hostname $qdisk lev $dle->{planner}->{level} FAILED $dle->{planner}->{error}"; } - foreach my $try (@$tries) { - if (exists $try->{dumper} && - $try->{dumper}->{status} eq 'fail') { - push @dump_failures, "$hostname $qdisk lev $try->{dumper}->{level} FAILED $try->{dumper}->{error}"; - $failed = 1; - } - if (exists $try->{chunker} && - $try->{chunker}->{status} eq 'fail') { - push @dump_failures, "$hostname $qdisk lev $try->{chunker}->{level} FAILED $try->{chunker}->{error}"; - $failed = 1; - } - if ( exists $try->{taper} - && ( $try->{taper}->{status} eq 'fail' - || ( $try->{taper}->{status} eq 'partial'))) { - #&& defined $try->{taper}->{error} - #&& $try->{taper}->{error} ne ""))) { - my $flush = "FLUSH"; - $flush = "FAILED" if exists $try->{dumper} && !exists $try->{chunker}; - if ($flush ne "FLUSH" or $try->{taper}->{error} !~ /CONFIG:/) { - if ($try->{taper}->{status} eq 'partial') { - # if the error message is omitted, then the taper only got a partial - # dump from the dumper/chunker, rather than failing with a taper error - my $errmsg = $try->{taper}{error} || "successfully taped a partial dump"; - $flush = "partial taper: $errmsg"; - } else { - $flush .= " " . $try->{taper}{error}; + while( my ($timestamp, $tries) = each %$alldumps ) { + my $failed = 0; + foreach my $try (@$tries) { + if (exists $try->{dumper} && + $try->{dumper}->{status} && + $try->{dumper}->{status} eq 'fail') { + push @dump_failures, "$hostname $qdisk lev $try->{dumper}->{level} FAILED $try->{dumper}->{error}"; + $failed = 1; + } + if (exists $try->{chunker} && + $try->{chunker}->{status} eq 'fail') { + push @dump_failures, "$hostname $qdisk lev $try->{chunker}->{level} FAILED $try->{chunker}->{error}"; + $failed = 1; + } + if ( exists $try->{taper} + && ( $try->{taper}->{status} eq 'fail' + || ( $try->{taper}->{status} eq 'partial'))) { + my $flush = "FLUSH"; + $flush = "FAILED" if exists $try->{dumper} && !exists $try->{chunker}; + if ($flush ne "FLUSH" or !defined $try->{taper}->{failure_from} + or $try->{taper}->{failure_from} ne 'config') { + if ($try->{taper}->{status} eq 'partial') { + # if the error message is omitted, then the taper only got a partial + # dump from the dumper/chunker, rather than failing with a taper error + my $errmsg = $try->{taper}{error} || "successfully taped a partial dump"; + $flush = "partial taper: $errmsg"; + } else { + $flush .= " " . $try->{taper}{error}; + } + + push @dump_failures, "$hostname $qdisk lev $try->{taper}->{level} $flush"; + $failed = 1; } + } - push @dump_failures, "$hostname $qdisk lev $try->{taper}->{level} $flush"; - $failed = 1; + # detect retried dumps + if ( $failed + && exists $try->{dumper} + && ( $try->{dumper}->{status} eq "success" + || $try->{dumper}->{status} eq "strange") + && ( !exists $try->{chunker} + || $try->{chunker}->{status} eq "success") + && ( !exists $try->{taper} + || $try->{taper}->{status} eq "done")) { + push @dump_failures, "$hostname $qdisk lev $try->{dumper}->{level} was successfully retried"; + $failed = 0; } - } - if ( $failed - && exists $try->{dumper} - && $try->{dumper}->{status} eq "success" - && ( !exists $try->{chunker} - || $try->{chunker}->{status} eq "success") - && ( !exists $try->{taper} - || $try->{taper}->{status} eq "done")) { - push @dump_failures, "$hostname $qdisk lev $try->{dumper}->{level} was successfully retried"; - } - push @stranges, -"$hostname $qdisk lev $try->{dumper}->{level} STRANGE (see below)" - if (defined $try->{dumper} - && $try->{dumper}->{status} eq 'strange'); - } + # detect dumps re-flushed from holding + if ( $failed + && !exists $try->{dumper} + && !exists $try->{chunker} + && exists $try->{taper} + && $try->{taper}->{status} eq "done") { + push @dump_failures, "$hostname $qdisk lev $try->{taper}->{level} was successfully re-flushed"; + $failed = 0; + } + + push @stranges, + "$hostname $qdisk lev $try->{dumper}->{level} STRANGE (see below)" + if (defined $try->{dumper} + && $try->{dumper}->{status} eq 'strange'); + } + } } push @failures, @fatal_failures, @error_failures, @missing_failures, @driver_failures, @planner_failures, @dump_failures; @@ -601,9 +632,9 @@ sub by_level_count # start at level 1 - don't include fulls foreach my $i (1 .. (@$count - 1)) { - push @lc, "$i:$count->[$i]" if $count->[$i] > 0; + push @lc, "$i:$count->[$i]" if defined $count->[$i] and $count->[$i] > 0; } - return '(' . join(' ', @lc) . ')'; + return join(' ', @lc); } sub output_stats @@ -616,8 +647,8 @@ sub output_stats STATISTICS: - Total Full Incr. - -------- -------- -------- + Total Full Incr. Level:# + -------- -------- -------- -------- EOF my $st_format = <{dumper_time} ), hrmn( $full_stats->{dumper_time} ), - hrmn( $incr_stats->{dumper_time} ), "" + hrmn( $incr_stats->{dumper_time} ), + "" ); print $fh swrite( @@ -696,16 +728,16 @@ EOF $comp_size->($total_stats), $comp_size->($full_stats), $comp_size->($incr_stats), - ($self->{dumpdisks}[1] > 0 ? "(level:#disks ...)" : "") + "", ); print $fh swrite( $st_format, - "Filesystems Dumped", + "DLEs Dumped", sprintf("%4d", $total_stats->{dumpdisk_count}), sprintf("%4d", $full_stats->{dumpdisk_count}), sprintf("%4d", $incr_stats->{dumpdisk_count}), - ($self->{dumpdisks}[1] > 0 ? by_level_count($self->{dumpdisks}) : "") + (has_incrementals($self->{dumpdisks}) ? by_level_count($self->{dumpdisks}) : "") ); print $fh swrite( @@ -723,7 +755,8 @@ EOF "Tape Time (hrs:min)", hrmn( $total_stats->{taper_time} ), hrmn( $full_stats->{taper_time} ), - hrmn( $incr_stats->{taper_time} ), "" + hrmn( $incr_stats->{taper_time} ), + "" ); print $fh swrite( @@ -753,25 +786,27 @@ EOF $tape_usage->($total_stats), $tape_usage->($full_stats), $tape_usage->($incr_stats), - ($self->{tapedisks}[1] > 0 ? "(level:#disks ...)" : "") + "" ); + my $nb_incr_dle = 0; + my @incr_dle = @{$self->{tapedisks}}; + foreach my $level (1 .. $#incr_dle) { + $nb_incr_dle += $incr_dle[$level]; + } print $fh swrite( $st_format, - "Filesystems Taped", - $self->{tapedisks}[0] + $self->{tapedisks}[1], + "DLEs Taped", + $self->{tapedisks}[0] + $nb_incr_dle, $self->{tapedisks}[0], - $self->{tapedisks}[1], + $nb_incr_dle, ( - ($self->{tapedisks}[1] > 0) + (has_incrementals($self->{tapedisks})) ? by_level_count($self->{tapedisks}) : "" ) ); - print $fh swrite($st_format, "", "", "", "", "(level:#parts ...)") - if $incr_stats->{tapepart_count} > 0; - # NOTE: only print out the per-level tapeparts if there are # incremental tapeparts print $fh swrite( @@ -800,6 +835,16 @@ EOF return; } +sub has_incrementals +{ + my $array = shift; + + for ($a = 1; $a < @$array; $a+=1) { + return 1 if $array->[$a] > 0; + } + return 0; +} + sub output_tape_stats { my ($self) = @_; @@ -822,7 +867,7 @@ sub output_tape_stats . "@>>>> @>>>>>>>>>>> @>>>>> @>>>> @>>>>\n"; print $fh "USAGE BY TAPE:\n"; - print $fh swrite($ts_format, "Label", "Time", "Size", "%", "Nb", "Nc"); + print $fh swrite($ts_format, "Label", "Time", "Size", "%", "DLEs", "Parts"); my $tapetype_name = getconf($CNF_TAPETYPE); my $tapetype = lookup_tapetype($tapetype_name); @@ -842,8 +887,8 @@ sub output_tape_stats hrmn($tape->{time}), # time sprintf("%.0f", $self->tounits($tape->{kb})) . $self->{disp_unit}, # size divzero(100 * $tapeused, $tapesize), # % usage - int($tape->{dle}), # Nb of dles - int($tape->{files}) # Nb of parts + int($tape->{dle}), # # of dles + int($tape->{files}) # # of parts ); } print $fh "\n"; @@ -870,71 +915,73 @@ sub output_details foreach my $dle_entry (@dles) { my ($hostname, $disk) = @$dle_entry; - my $dle = $report->get_dle_info(@$dle_entry); - my $tries = $dle->{tries} || []; - my $qdisk = quote_string($disk); - my $outsize = undef; - - foreach my $try (@$tries) { - - # - # check for failed dumper details - # - if (defined $try->{dumper} - && $try->{dumper}->{status} eq 'fail') { - - push @failed_dump_details, -"/-- $hostname $qdisk lev $try->{dumper}->{level} FAILED $try->{dumper}->{error}", - @{ $try->{dumper}->{errors} }, - "\\--------"; - - if ($try->{dumper}->{nb_errors} > 100) { - my $nb = $try->{dumper}->{nb_errors} - 100; - - push @failed_dump_details, -"$nb lines follow, see the corresponding log.* file for the complete list", - "\\--------"; - } - } + my $dle = $report->get_dle_info(@$dle_entry); + my $alldumps = $dle->{'dumps'} || {}; + my $qdisk = quote_string($disk); + my $outsize = undef; + + while( my ($timestamp, $tries) = each %$alldumps ) { + foreach my $try (@$tries) { + + # + # check for failed dumper details + # + if (defined $try->{dumper} + && $try->{dumper}->{status} eq 'fail') { + + push @failed_dump_details, + "/-- $hostname $qdisk lev $try->{dumper}->{level} FAILED $try->{dumper}->{error}", + @{ $try->{dumper}->{errors} }, + "\\--------"; + + if ($try->{dumper}->{nb_errors} > 100) { + my $nb = $try->{dumper}->{nb_errors} - 100; + + push @failed_dump_details, + "$nb lines follow, see the corresponding log.* file for the complete list", + "\\--------"; + } + } - # - # check for strange dumper details - # - if (defined $try->{dumper} - && $try->{dumper}->{status} eq 'strange') { - - push @strange_dump_details, - "/-- $hostname $qdisk lev $try->{dumper}->{level} STRANGE", - @{ $try->{dumper}->{stranges} }, - "\\--------"; - - if ($try->{dumper}->{nb_stranges} > 100) { - my $nb = $try->{dumper}->{nb_stranges} - 100; - push @strange_dump_details, -"$nb lines follow, see the corresponding log.* file for the complete list", - "\\--------"; - } - } + # + # check for strange dumper details + # + if (defined $try->{dumper} + && $try->{dumper}->{status} eq 'strange') { + + push @strange_dump_details, + "/-- $hostname $qdisk lev $try->{dumper}->{level} STRANGE", + @{ $try->{dumper}->{stranges} }, + "\\--------"; + + if ($try->{dumper}->{nb_stranges} > 100) { + my $nb = $try->{dumper}->{nb_stranges} - 100; + push @strange_dump_details, + "$nb lines follow, see the corresponding log.* file for the complete list", + "\\--------"; + } + } - # note: copied & modified from calculate_stats. - if ( - exists $try->{dumper} - && exists $try->{taper} - && defined $try->{taper}->{kb} - && ( $try->{taper}{status} eq 'done' - || $try->{taper}{status} eq 'partial') - ) { - $outsize = $try->{taper}->{kb}; - } elsif ( - exists $try->{dumper} - && exists $try->{chunker} - && defined $try->{chunker}->{kb} - && ( $try->{chunker}{status} eq 'success' - || $try->{chunker}{status} eq 'partial') - ) { - $outsize = $try->{chunker}->{kb}; - } - } # end try loop + # note: copied & modified from calculate_stats. + if ( + exists $try->{dumper} + && exists $try->{taper} + && defined $try->{taper}->{kb} + && ( $try->{taper}{status} eq 'done' + || $try->{taper}{status} eq 'partial') + ) { + $outsize = $try->{taper}->{kb}; + } elsif ( + exists $try->{dumper} + && exists $try->{chunker} + && defined $try->{chunker}->{kb} + && ( $try->{chunker}{status} eq 'success' + || $try->{chunker}{status} eq 'partial') + ) { + $outsize = $try->{chunker}->{kb}; + } + } + } # # check for bad estimates @@ -947,7 +994,7 @@ sub output_details "big estimate: $hostname $qdisk $dle->{estimate}{level}", sprintf(' est: %.0f%s out %.0f%s', $est->{ckb}, $disp_unit, $outsize, $disp_unit) - if ( ($est->{ckb} * .9 > $outsize) + if (defined $est->{'ckb'} && ($est->{ckb} * .9 > $outsize) && ($est->{ckb} - $outsize > 1.0e5)); } } @@ -977,8 +1024,11 @@ sub output_summary my $col_spec = $self->set_col_spec(); ## collect all the output line specs (see get_summary_info) - my @summary_linespecs = - map { [ $self->get_summary_info($_, $report, $col_spec) ] } @dles; + my @summary_linespecs = (); + foreach my $dle (@dles) { + push @summary_linespecs, $self->get_summary_info($dle, $report, $col_spec); + } + # shift off the first element of each tuple my @summary_linedata = map { my @x = @$_; shift @x; [ @x ] } @summary_linespecs; @@ -994,6 +1044,7 @@ sub output_summary my $nodump_PARTIAL_format = get_summary_format($col_spec, 'nodump-PARTIAL', @summary_linedata); my $nodump_FAILED_format = get_summary_format($col_spec, 'nodump-FAILED', @summary_linedata); my $nodump_FLUSH_format = get_summary_format($col_spec, 'nodump-FLUSH', @summary_linedata); + my $skipped_format = get_summary_format($col_spec, 'skipped', @summary_linedata); ## print the header names my $hdl = @@ -1056,6 +1107,8 @@ sub output_summary print $fh sprintf($missing_format, @data[0..2]); } elsif ($type eq 'noflush') { print $fh sprintf($noflush_format, @data[0..2]); + } elsif ($type eq 'skipped') { + print $fh sprintf($skipped_format, @data[0..2]); } } @@ -1072,6 +1125,7 @@ sub output_summary ## ('noflush', host, disk, '' ..) # NO FILE TO FLUSH ------ ## ('nodump-$msg', host, disk, level, '', out, '--', '', ## '', tapetime, taperate, taperpartial) # ... {FLUSH|FAILED|PARTIAL} ... +## ('skipped', host, disk, '' ..) # SKIPPED ----- ## ## the taperpartial column is not covered by the columnspec, and "hangs off" ## the right side. It's usually empty, but set to " PARTIAL" when the taper @@ -1082,6 +1136,7 @@ sub get_summary_info my $self = shift; my ( $dle, $report, $col_spec ) = @_; my ( $hostname, $disk ) = @$dle; + my @rvs; my $dle_info = $report->get_dle_info(@$dle); @@ -1111,176 +1166,203 @@ sub get_summary_info ? quote_string($disk) : $tail_quote_trunc->($disk, $col_spec->[1]->[COLSPEC_WIDTH]); - my $last_try = $dle_info->{tries}->[-1]; - my $level = - exists $last_try->{taper} ? $last_try->{taper}{level} - : exists $last_try->{chunker} ? $last_try->{chunker}{level} - : $last_try->{dumper}{level}; - - my $orig_size = undef; - - # find the try with the successful dumper entry - my $dumper = undef; - foreach my $try ( @{ $dle_info->{tries} } ) { - if ( exists $try->{dumper} - && exists $try->{dumper}{status} - && ( $try->{dumper}{status} eq "success" - || $try->{dumper}{status} eq "strange")) { - $dumper = $try->{dumper}; - last; - } + my $alldumps = $dle_info->{'dumps'}; + if ($dle_info->{'planner'} && + $dle_info->{'planner'}->{'status'} eq 'fail') { + my @rv; + push @rv, 'nodump-FAILED'; + push @rv, $hostname; + push @rv, $disk_out; + push @rv, ("",) x 9; + push @rvs, [@rv]; + } elsif ($dle_info->{'planner'} && + $dle_info->{'planner'}->{'status'} eq 'skipped') { + my @rv; + push @rv, 'skipped'; + push @rv, $hostname; + push @rv, $disk_out; + push @rv, ("",) x 8; + push @rvs, [@rv]; + } elsif (keys %{$alldumps} == 0) { + my @rv; + push @rv, $report->get_flag("amflush_run")? 'noflush' : 'missing'; + push @rv, $hostname; + push @rv, $disk_out; + push @rv, ("",) x 8; + push @rvs, [@rv]; } - $orig_size = $dumper->{orig_kb} - if defined $dumper; - - my ( $out_size, $dump_time, $dump_rate, $tape_time, $tape_rate ) = (0) x 5; - my ($dumper_status) = ""; - my $saw_dumper = 0; # no dumper will mean this was a flush - my $taper_partial = 0; # was the last taper run partial? - - ## Use this loop to set values - foreach my $try ( @{ $dle_info->{tries} } ) { - - ## find the outsize for the output summary - - if ( - exists $try->{taper} - && ( $try->{taper}{status} eq "done" - || $try->{taper}{status} eq "part+partial" ) - ) { - $taper_partial = 0; - $orig_size = $try->{taper}{orig_kb} if !defined($orig_size); - $out_size = $try->{taper}{kb}; - $tape_time = $try->{taper}{sec}; - $tape_rate = $try->{taper}{kps}; - } elsif ( exists $try->{taper} - && ( $try->{taper}{status} eq "partial" ) ) { - - $taper_partial = 1; - $orig_size = $try->{taper}{orig_kb} if !defined($orig_size); - $out_size = $try->{taper}{kb}; - $tape_time = $try->{taper}{sec} if !$tape_time; - $tape_rate = $try->{taper}{kps} if !$tape_rate; - } elsif (exists $try->{taper} && ( $try->{taper}{status} eq "fail")) { - if ($try->{taper}{error} =~ /CONFIG:/) { - $tape_time = 0; - $tape_rate = 0; - } else { + + while( my ($timestamp, $tries) = each %$alldumps ) { + my $last_try = $tries->[-1]; + my $level = + exists $last_try->{taper} ? $last_try->{taper}{level} + : exists $last_try->{chunker} ? $last_try->{chunker}{level} + : $last_try->{dumper}{level}; + + my $orig_size = undef; + + # find the try with the successful dumper entry + my $dumper = undef; + foreach my $try (@$tries) { + if ( exists $try->{dumper} + && exists $try->{dumper}{status} + && ( $try->{dumper}{status} eq "success" + || $try->{dumper}{status} eq "strange")) { + $dumper = $try->{dumper}; + last; + } + } + $orig_size = $dumper->{orig_kb} + if defined $dumper; + + my ( $out_size, $dump_time, $dump_rate, $tape_time, $tape_rate ) = (0) x 5; + my ($dumper_status) = ""; + my $saw_dumper = 0; # no dumper will mean this was a flush + my $taper_partial = 0; # was the last taper run partial? + + ## Use this loop to set values + foreach my $try ( @$tries ) { + + ## find the outsize for the output summary + + if ( + exists $try->{taper} + && ( $try->{taper}{status} eq "done" + || $try->{taper}{status} eq "part+partial" ) + ) { + $taper_partial = 0; + $orig_size = $try->{taper}{orig_kb} if !defined($orig_size); + $out_size = $try->{taper}{kb}; + $tape_time = $try->{taper}{sec}; + $tape_rate = $try->{taper}{kps}; + } elsif ( exists $try->{taper} + && ( $try->{taper}{status} eq "partial" ) ) { + + $taper_partial = 1; + $orig_size = $try->{taper}{orig_kb} if !defined($orig_size); + $out_size = $try->{taper}{kb}; + $tape_time = $try->{taper}{sec} if !$tape_time; + $tape_rate = $try->{taper}{kps} if !$tape_rate; + } elsif (exists $try->{taper} && ( $try->{taper}{status} eq "fail")) { $tape_time = undef; $tape_rate = undef; } - } - - if (!$out_size && - exists $try->{chunker} - && ( $try->{chunker}{status} eq "success" - || $try->{chunker}{status} eq "partial" ) - ) { - $out_size = $try->{chunker}{kb}; - } - - if (!$out_size && - exists $try->{dumper}) { - $out_size = $try->{dumper}{kb}; - } - - if ( exists $try->{dumper}) { - $saw_dumper = 1; - $dumper_status = $try->{dumper}{status}; - } - - ## find the dump time - if ( exists $try->{dumper} - && exists $try->{dumper}{status} - && ( $try->{dumper}{status} eq "success" - || $try->{dumper}{status} eq "strange")) { - - $dump_time = $try->{dumper}{sec}; - $dump_rate = $try->{dumper}{kps}; - } - } - my $compression; - if (!defined $orig_size) { - $compression = 100; - } else { - $compression = - divzero_col((100 * $out_size), $orig_size, $col_spec->[5]); - } - - ## simple formatting macros + if (!$out_size && + exists $try->{chunker} + && ( $try->{chunker}{status} eq "success" + || $try->{chunker}{status} eq "partial" ) + ) { + $out_size = $try->{chunker}{kb}; + } - my $fmt_col_field = sub { - my ( $column, $data ) = @_; + if (!$out_size && + exists $try->{dumper}) { + $out_size = $try->{dumper}{kb}; + } - return sprintf( - $col_spec->[$column]->[COLSPEC_FORMAT], - $col_spec->[$column]->[COLSPEC_WIDTH], - $col_spec->[$column]->[COLSPEC_PREC], $data - ); - }; + if ( exists $try->{dumper}) { + $saw_dumper = 1; + $dumper_status = $try->{dumper}{status}; + } - my $format_space = sub { - my ( $column, $data ) = @_; + ## find the dump time + if ( exists $try->{dumper} + && exists $try->{dumper}{status} + && ( $try->{dumper}{status} eq "success" + || $try->{dumper}{status} eq "strange")) { - return sprintf("%*s",$col_spec->[$column]->[COLSPEC_WIDTH], $data); - }; + $dump_time = $try->{dumper}{sec}; + $dump_rate = $try->{dumper}{kps}; + } + } - my @rv; + # sometimes the driver logs an orig_size of -1, which makes the + # compression percent very large and negative + $orig_size = 0 if ($orig_size < 0); - if ( !$orig_size && !$out_size && (!defined($tape_time) || !$tape_time)) { - push @rv, $report->get_flag("amflush_run")? 'noflush' : 'missing'; - push @rv, $hostname; - push @rv, $disk_out; - push @rv, ("",) x 8; - return @rv; - } + # pre-format the compression column, with '--' replacing 100% (i.e., + # no compression) + my $compression; + if (!defined $orig_size || $orig_size == $out_size) { + $compression = '--'; + } else { + $compression = + divzero_col((100 * $out_size), $orig_size, $col_spec->[5]); + } - if ($saw_dumper and ($dumper_status eq 'success' or $dumper_status eq 'strange')) { - push @rv, "full"; - push @rv, $hostname; - push @rv, $disk_out; - push @rv, $fmt_col_field->(2, $level); - push @rv, $orig_size ? $fmt_col_field->(3, $self->tounits($orig_size)) : ''; - push @rv, $out_size ? $fmt_col_field->(4, $self->tounits($out_size)) : ''; - push @rv, ($compression == 100) ? '-- ' : $fmt_col_field->(5, $compression); - push @rv, $dump_time ? $fmt_col_field->(6, mnsc($dump_time)) : "PARTIAL"; - push @rv, $dump_rate ? $fmt_col_field->(7, $dump_rate) : ""; - push @rv, $fmt_col_field->(8, - (defined $tape_time) ? - $tape_time ? mnsc($tape_time) : "" - : "FAILED"); - push @rv, (defined $tape_rate) ? - $tape_rate ? - $fmt_col_field->(9, $tape_rate) - : $format_space->(9, "") - : $format_space->(9, "FAILED"); - push @rv, $taper_partial? " PARTIAL" : ""; # column 10 - } else { - my $message = $saw_dumper? - ($dumper_status eq 'failed') ? 'FAILED' : 'PARTIAL' - : 'FLUSH'; - push @rv, "nodump-$message"; - push @rv, $hostname; - push @rv, $disk_out; - push @rv, $fmt_col_field->(2, $level); - push @rv, $orig_size ? $fmt_col_field->(4, $self->tounits($orig_size)) :''; - push @rv, $out_size ? $fmt_col_field->(4, $self->tounits($out_size)) : ''; - push @rv, ($compression == 100) ? '-- ' : $fmt_col_field->(5, $compression); - push @rv, ''; - push @rv, ''; - push @rv, $fmt_col_field->(8, - (defined $tape_time) ? - $tape_time ? mnsc($tape_time) : "" - : "FAILED"); - push @rv, (defined $tape_rate) ? - $tape_rate ? - $fmt_col_field->(9, $tape_rate) - : $format_space->(9, "") - : $format_space->(9, "FAILED"); - push @rv, $taper_partial? " PARTIAL" : ""; + ## simple formatting macros + + my $fmt_col_field = sub { + my ( $column, $data ) = @_; + + return sprintf( + $col_spec->[$column]->[COLSPEC_FORMAT], + $col_spec->[$column]->[COLSPEC_WIDTH], + $col_spec->[$column]->[COLSPEC_PREC], $data + ); + }; + + my $format_space = sub { + my ( $column, $data ) = @_; + + return sprintf("%*s",$col_spec->[$column]->[COLSPEC_WIDTH], $data); + }; + + my @rv; + + if ( !$orig_size && !$out_size && (!defined($tape_time) || !$tape_time)) { + push @rv, $report->get_flag("amflush_run")? 'noflush' : 'missing'; + push @rv, $hostname; + push @rv, $disk_out; + push @rv, ("",) x 8; + } elsif ($saw_dumper and ($dumper_status eq 'success' or $dumper_status eq 'strange')) { + push @rv, "full"; + push @rv, $hostname; + push @rv, $disk_out; + push @rv, $fmt_col_field->(2, $level); + push @rv, $orig_size ? $fmt_col_field->(3, $self->tounits($orig_size)) : ''; + push @rv, $out_size ? $fmt_col_field->(4, $self->tounits($out_size)) : ''; + push @rv, $compression; + push @rv, $dump_time ? $fmt_col_field->(6, mnsc($dump_time)) : "PARTIAL"; + push @rv, $dump_rate ? $fmt_col_field->(7, $dump_rate) : ""; + push @rv, $fmt_col_field->(8, + (defined $tape_time) ? + $tape_time ? mnsc($tape_time) : "" + : "FAILED"); + push @rv, (defined $tape_rate) ? + $tape_rate ? + $fmt_col_field->(9, $tape_rate) + : $format_space->(9, "") + : $format_space->(9, "FAILED"); + push @rv, $taper_partial? " PARTIAL" : ""; # column 10 + } else { + my $message = $saw_dumper? + ($dumper_status eq 'failed') ? 'FAILED' : 'PARTIAL' + : 'FLUSH'; + push @rv, "nodump-$message"; + push @rv, $hostname; + push @rv, $disk_out; + push @rv, $fmt_col_field->(2, $level); + push @rv, $orig_size ? $fmt_col_field->(4, $self->tounits($orig_size)) :''; + push @rv, $out_size ? $fmt_col_field->(4, $self->tounits($out_size)) : ''; + push @rv, $compression; + push @rv, ''; + push @rv, ''; + push @rv, $fmt_col_field->(8, + (defined $tape_time) ? + $tape_time ? mnsc($tape_time) : "" + : "FAILED"); + push @rv, (defined $tape_rate) ? + $tape_rate ? + $fmt_col_field->(9, $tape_rate) + : $format_space->(9, "") + : $format_space->(9, "FAILED"); + push @rv, $taper_partial? " PARTIAL" : ""; + } + push @rvs, [@rv]; } - return @rv; + return @rvs; } sub get_summary_format @@ -1365,6 +1447,14 @@ sub get_summary_format get_summary_col_format( $i, $col_spec->[$i], map { $_->[$i] } @summary_lines ); } + } elsif ($type eq 'skipped') { + # add a blank level column and the space for the origkb column + push @col_format, ' ' x $col_spec->[2]->[COLSPEC_PRE_SPACE]; + push @col_format, ' ' x $col_spec->[2]->[COLSPEC_WIDTH]; + push @col_format, ' ' x $col_spec->[3]->[COLSPEC_PRE_SPACE]; + my $str = "SKIPPED "; + $str .= '-' x ($rulewidth - length($str)); + push @col_format, $str; } }