| 1 | #!/usr/bin/perl -w |
|---|
| 2 | |
|---|
| 3 | # Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd. |
|---|
| 4 | # This program is distributed under the terms of the |
|---|
| 5 | # GNU General Public License, version 2. |
|---|
| 6 | # |
|---|
| 7 | # $Id$ |
|---|
| 8 | |
|---|
| 9 | use strict; |
|---|
| 10 | |
|---|
| 11 | use lib "./lib"; |
|---|
| 12 | |
|---|
| 13 | use Getopt::Long qw/:config no_ignore_case/; |
|---|
| 14 | use List::Util qw( min ); |
|---|
| 15 | use Time::HiRes qw( time ); |
|---|
| 16 | use MT; |
|---|
| 17 | use MT::Util::LogProcessor; |
|---|
| 18 | use Data::Dumper; |
|---|
| 19 | |
|---|
| 20 | GetOptions( |
|---|
| 21 | 'day=s' => \my ($arg_day), |
|---|
| 22 | 'logdir=s' => \my ($arg_logdir), |
|---|
| 23 | 'sample=i' => \my ($arg_sample), |
|---|
| 24 | 'slow=i' => \my ($arg_slow), |
|---|
| 25 | 'debug' => \my ($arg_debug), |
|---|
| 26 | 'dump' => \my ($arg_dump), |
|---|
| 27 | ); |
|---|
| 28 | |
|---|
| 29 | $arg_slow ||= 2; |
|---|
| 30 | |
|---|
| 31 | my $proc = MT::Util::LogProcessor->new( |
|---|
| 32 | { |
|---|
| 33 | debug => $arg_debug, |
|---|
| 34 | logdir => $arg_logdir || '.', |
|---|
| 35 | sample => $arg_sample, |
|---|
| 36 | day => $arg_day || 'yesterday', |
|---|
| 37 | file_pattern => 'pl-\d{8}.log', |
|---|
| 38 | } |
|---|
| 39 | ); |
|---|
| 40 | |
|---|
| 41 | my %stash = ( today => $proc->day ); |
|---|
| 42 | my ( $total_records, $elapsed ) = $proc->process_log_files( |
|---|
| 43 | sub { |
|---|
| 44 | my ($rec) = @_; |
|---|
| 45 | |
|---|
| 46 | my $secs = int $rec->{time_total}; |
|---|
| 47 | |
|---|
| 48 | my $bucket = $secs > 10 ? 10 : $secs; |
|---|
| 49 | $stash{by_seconds}[$bucket]++; |
|---|
| 50 | |
|---|
| 51 | $stash{total_requests}++; |
|---|
| 52 | |
|---|
| 53 | if ( $secs > $arg_slow - 1 ) { |
|---|
| 54 | push @{ $stash{slow} }, $rec; |
|---|
| 55 | } |
|---|
| 56 | } |
|---|
| 57 | ); |
|---|
| 58 | |
|---|
| 59 | printf "Processed %d records in %.02f seconds; speed: %.02f recs/sec\n", |
|---|
| 60 | $total_records, $elapsed, $total_records / ( $elapsed || 1 ) |
|---|
| 61 | if $arg_debug; |
|---|
| 62 | |
|---|
| 63 | for my $bucket ( 0 .. $#{ $stash{by_seconds} } ) { |
|---|
| 64 | my $count = $stash{by_seconds}[$bucket] || 0; |
|---|
| 65 | $stash{restime_histogram}[$bucket] = { |
|---|
| 66 | count => $count, |
|---|
| 67 | range => $bucket == 10 |
|---|
| 68 | ? '10+ sec' |
|---|
| 69 | : $bucket . '-' . ( $bucket + 1 ) . 's', |
|---|
| 70 | percent => int( $count / $stash{total_requests} * 100 ) || 1, |
|---|
| 71 | }; |
|---|
| 72 | } |
|---|
| 73 | |
|---|
| 74 | $stash{slow} = |
|---|
| 75 | [ sort { $b->{time_total} <=> $a->{time_total} } @{ $stash{slow} || [] } ]; |
|---|
| 76 | |
|---|
| 77 | report( \%stash ); |
|---|
| 78 | |
|---|
| 79 | sub report { |
|---|
| 80 | my ($stash) = @_; |
|---|
| 81 | |
|---|
| 82 | print "Response time histogram:\n"; |
|---|
| 83 | for my $row ( @{ $stash->{restime_histogram} } ) { |
|---|
| 84 | printf "%s: %s (%s%%)\n", $row->{range}, $row->{count}, $row->{percent}; |
|---|
| 85 | } |
|---|
| 86 | |
|---|
| 87 | print "Slowest requests:\n"; |
|---|
| 88 | for my $row ( @{ $stash->{slow} } ) { |
|---|
| 89 | printf "%s\n", $row->{url}; |
|---|
| 90 | for my $key ( keys %$row ) { |
|---|
| 91 | next if $key !~ /^time_/; |
|---|
| 92 | my $secs = $row->{$key}; |
|---|
| 93 | next |
|---|
| 94 | if $key eq 'time_mem_start' |
|---|
| 95 | || $key eq 'time_mem_end' |
|---|
| 96 | || $key eq 'time_total' |
|---|
| 97 | || $secs < 0.01; |
|---|
| 98 | printf "%s: %s\n", $key, $secs; |
|---|
| 99 | } |
|---|
| 100 | } |
|---|
| 101 | } |
|---|