21 my @opt = <<'=back' =~ /B<--(\S+)>/g;
25 String can be C<reps>, nothing else. Note: the time estimation for
26 individual distros is buggy, don't trust them!
34 Defaults to 20. Show only the last logfiles
36 Misnomer since the day we reversed the result of the glob.
40 Do not parse the whole files, just report the date and perl.
46 Get some stats on a megalog file: seconds per process, total seconds,
47 number of lines, number of ticks.
49 Usually called from the cpanpm directory with
51 perl ~k/sources/CPAN/andk-cpan-tools/bin/megalog-overview.pl --tail=3
55 The option --debug=reps does not reflect the stack of activities: if
56 Job A depends on B, then we measure ABBA: A-start, B-start, B-end,
57 A-end and the running time for A includes the running time for B in
64 use lib
"$FindBin::Bin/../lib";
70 use File
::Basename
qw(dirname);
71 use File
::Path
qw(mkpath);
75 use Hash
::Util
qw(lock_keys);
76 use List
::Util
qw(max sum);
77 use Pod
::Usage
qw(pod2usage);
80 lock_keys
%Opt, map { /([^=|!]+)/ } @opt;
90 my @ml = glob("megalog-*.log");
92 shift @ml while @ml > $Opt{tail
};
94 for my $ml (reverse @ml) {
95 my $identitylinestyle = undef; # { "CPAN.pm: Building" => "cpanpm", "\e.+?\s\s" => "color" }
96 open my $fh, $ml or die "Could not open '$ml': $!";
101 my($date) = $ml =~ /megalog-(.+)\.log/;
105 $S{blines
}++ unless $Opt{terse
};
107 if (!$S{aperl
} and m
!^perl\
|->\s
+.+?
/
108 (?
: perl
| host
/([^/]+) )
114 $S{aperl
} = "$1/$2"; # the normal case
116 $S{aperl
} = "k83/$2"; # rarely true
119 } elsif (/=monitoring proc/) {
120 # ==========monitoring proc 18571 perl v5.15.6-585-gc6fb3f6/a2da secs 30001.0000=======
122 if (/=monitoring proc (\d+) perl\s+\S+\s+secs (\d+\.\d+)==/) {
125 if ($time < $prev_0time) {
128 $process_cnt = $P{$process} ||= $P++;
129 $S{sprintf "p-%02d-0time", $process_cnt} = $time;
131 } elsif (/^\s+CPAN.pm: Building .\/..\
/(\S+)/) { # CPAN.pm up to 2.xx
132 # CPAN.pm: Building S/SR/SRI/Mojolicious-3.18.tar.gz
134 $identitylinestyle ||= "cpanpm";
135 if ($identitylinestyle eq "cpanpm") {
136 $S{sprintf "p-%02d-3last", $process_cnt} = $what;
137 unless ( $seen{$what}++ ){
138 $S{sprintf "p-%02d-1reps", $process_cnt}++;
142 } elsif (m{^\e.+?\s\s([A-Z-0-9]+/\S+?)\e}) { # CPAN.pm 2.03, but also before
143 # <ansicolor> TOKUHIROM/Test-Requires-0.07.tar.gz</ansicolor>
145 $identitylinestyle ||= "color";
146 if ($identitylinestyle eq "color") {
147 $S{sprintf "p-%02d-3last", $process_cnt} = $what;
148 unless ( $seen{$what}++ ){
149 $S{sprintf "p-%02d-1reps", $process_cnt}++;
154 if ($Opt{debug
} && $Opt{debug
} eq "reps" && $reps) {
155 my $this_0time = $S{"p-$process_cnt-0time"};
156 printf "# %s %5d %5d %s\n", $process_cnt, $this_0time, $this_0time-$prev_0time, $reps;
157 $prev_0time = $this_0time; # Buggy! do not rely on it. Does not reflect the stack of activities
160 unless ($Opt{terse
}){
161 $S{totalsecs
} = sum
map { $S{$_} } grep { /^p-\d+-0time$/ } keys %S;
163 no warnings
'uninitialized';
165 map { $F{$_}=max
($F{$_},length($S{$_}));
166 sprintf("%s=%*s", $_, $F{$_}, $S{$_}) }
167 sort grep { !/^p-/ } keys %S;
168 for my $kp ( "00"..$P ) {
169 last unless exists $S{"p-$kp-0time"};
170 $S{"p-$kp-2avg"} = sprintf "%.1f", $S{"p-$kp-1reps"} ?
$S{"p-$kp-0time"}/$S{"p-$kp-1reps"} : 0;
172 for my $k (sort grep { /^p-$kp-/ } keys %S) {
173 my($kl) = $k =~ /.+-\d*(\w+)/;
176 $v = sprintf "%d", $S{$k};
180 printf(" %s=%s", $kl, $v)
184 print "" unless $Opt{terse
};
189 # cperl-indent-level: 4