root/branches/release-30/lib/MT/Util/ReqTimer.pm @ 1372

Revision 1372, 4.1 kB (checked in by bchoate, 22 months ago)

Initial work for performance logging.

Line 
1=head1 NAME
2
3MT::Util::ReqTimer
4
5=head1 DESCRIPTION
6
7This is a simple class to let us get custom and granular
8and log parts of the request cycle.
9
10Note that the timerlogger has got some custom stuff in
11it to handle the data we're passing into it, so that
12it can log pretty in some placess and machine-readable
13in other places.
14
15Requires installation of Time::HiRes and List::Util
16(Time::HiRes is core to Perl 5.8.0 and later).
17
18=cut
19
20package MT::Util::ReqTimer;
21
22use strict;
23use List::Util qw( sum );
24use Time::HiRes;
25
26our $Timer;
27sub instance {
28    return $Timer ||= shift->new;
29}
30
31sub new {
32    my $class = shift;
33    $class = ref $class || $class;
34    my $self = bless {}, $class;
35    $self->start( @_ );
36    return $self;
37}
38
39sub start {
40    my $self = shift;
41    $self->{uri} = shift || '';
42    $self->{prev} = $self->{first} = Time::HiRes::time();
43    $self->{paused} = [];
44    $self->{elapsed} = 0;
45    $self->{dur} = [];
46}
47
48sub mark {
49    my ($self, $mark_str) = @_;
50    $mark_str = (caller(1))[3] unless $mark_str;
51    my $now = Time::HiRes::time();
52    my $dur = $now - $self->{prev};
53    $self->{elapsed} += $dur;
54    push @{$self->{dur}}, [ $dur, $mark_str, $self->{elapsed} ];
55    if (@{$self->{paused}}) {
56        my $paused = pop @{$self->{paused}};
57        if (ref $paused ne 'ARRAY') {
58            $paused = [];
59        }
60        my ($start, $end) = @$paused;
61
62        #back up enough to account for the time spent doing other things
63        $self->{prev} = $start - ($end - $now);
64    } else {
65        $self->{prev} = $now;
66    }
67}
68
69sub log {
70    my $self = shift;
71    #my $timerlogger = Log::Log4perl::get_logger('TypeCore::Util::ReqTimer');
72    #$timerlogger->info($self->{uri}, $self->{dur});
73}
74
75sub dump_line {
76    my $self = shift;
77    my (@more) = @_;
78    my @lines;
79    push @lines, "pid=$$";
80    push @lines, "uri=[" . $self->{uri} . ']' if $self->{uri};
81    push @lines, @more if @more;
82    my $total = 0;
83    my $threshold = MT->config->PerformanceLoggingThreshold;
84    foreach ( @{$self->{dur}} ) {
85        my $dur = $_->[0];
86        if ($_->[1] =~ m/^total\b/) {
87            $dur = $_->[2];
88        }
89        if ($dur >= $threshold) {
90            push @lines, sprintf("%s=%.5f", $_->[1], $dur);
91        }
92        $total += $_->[0];
93    }
94    push @lines, sprintf("Total=%.5f", $total);
95    my @times = localtime(time);
96    my $mon = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')[$times[4]];
97    my $day = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat')[$times[6]];
98    my $mday = $times[3];
99    my $year = $times[5]+1900;
100    my ($hr, $mn, $sc) = ($times[2], $times[1], $times[0]);
101    my $ts = sprintf("%s %s %s %02d:%02d:%02d %04d", $day, $mon, $mday, $hr, $mn, $sc, $year);
102
103    require Sys::Hostname; # available in core as of Perl 5.6.0
104    my $hostname = Sys::Hostname::hostname();
105
106    return "[$ts] $hostname pt-times: " . join(", ", @lines) . "\n";
107}
108
109sub dump {
110    my $self = shift;
111    my $lines = '';
112    my $total = 0;
113    my $threshold = MT->config->PerformanceLoggingThreshold;
114    foreach ( @{$self->{dur}} ) {
115        my $dur = $_->[0];
116        if ($_->[1] =~ m/^total\b/) {
117            $dur = $_->[2];
118        }
119        if ($dur >= $threshold) {
120            $lines .= sprintf("%s - %.5f %s\n", $$, $dur, $_->[1]);
121        }
122        $total += $_->[0];
123    }
124    $lines .= sprintf("%s - %.5f --Total-- %s\n", $$, $total, $self->{uri});
125    return $lines;
126}
127
128sub pause_partial {
129    my $self = shift;
130    my $now = Time::HiRes::time();
131    push @{$self->{paused}}, [$self->{prev}, $now];
132
133    $self->{prev} = $now;
134}
135
136sub unpause {
137    my ($self) = @_;
138    my $now = Time::HiRes::time();
139    my $dur = $now - $self->{prev};
140    $self->{elapsed} += $dur;
141    if (@{$self->{paused}}) {
142        my $paused = pop @{$self->{paused}};
143        if (ref $paused ne 'ARRAY') {
144            $paused = [];
145        }
146        my ($start, $end) = @$paused;
147
148        #back up enough to account for the time spent doing other things
149        $self->{prev} = $start - ($end - $now);
150    } else {
151        $self->{prev} = $now;
152    }
153}
154
155sub total_elapsed {
156    my $timer = shift;
157    return Time::HiRes::time() - $timer->{first};
158}
159
1601;
Note: See TracBrowser for help on using the browser.