File: ReqTimer.pm

package info (click to toggle)
movabletype-opensource 4.2.3-1%2Blenny3
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 21,268 kB
  • ctags: 15,862
  • sloc: perl: 178,892; php: 26,178; sh: 161; makefile: 82
file content (160 lines) | stat: -rw-r--r-- 4,183 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
=head1 NAME

MT::Util::ReqTimer

=head1 DESCRIPTION

This is a simple class to let us get custom and granular
and log parts of the request cycle.

Note that the timerlogger has got some custom stuff in
it to handle the data we're passing into it, so that
it can log pretty in some placess and machine-readable
in other places.

Requires installation of Time::HiRes and List::Util
(Time::HiRes is core to Perl 5.8.0 and later).

=cut

package MT::Util::ReqTimer;

use strict;
use List::Util qw( sum );
use Time::HiRes;

our $Timer;
sub instance {
    return $Timer ||= shift->new;
}

sub new {
    my $class = shift;
    $class = ref $class || $class;
    my $self = bless {}, $class;
    $self->start( @_ );
    return $self;
}

sub start {
    my $self = shift;
    $self->{uri} = shift || '';
    $self->{prev} = $self->{first} = Time::HiRes::time();
    $self->{paused} = [];
    $self->{elapsed} = 0;
    $self->{dur} = [];
}

sub mark {
    my ($self, $mark_str) = @_;
    $mark_str = (caller(1))[3] unless $mark_str;
    my $now = Time::HiRes::time();
    my $dur = $now - $self->{prev};
    $self->{elapsed} += $dur;
    push @{$self->{dur}}, [ $dur, $mark_str, $self->{elapsed} ];
    if (@{$self->{paused}}) {
        my $paused = pop @{$self->{paused}};
        if (ref $paused ne 'ARRAY') {
            $paused = [];
        }
        my ($start, $end) = @$paused;

        #back up enough to account for the time spent doing other things
        $self->{prev} = $start - ($end - $now);
    } else {
        $self->{prev} = $now;
    }
}

sub log {
    my $self = shift;
    #my $timerlogger = Log::Log4perl::get_logger('TypeCore::Util::ReqTimer');
    #$timerlogger->info($self->{uri}, $self->{dur});
}

sub dump_line {
    my $self = shift;
    my (@more) = @_;
    my @lines;
    push @lines, "pid=$$";
    push @lines, "uri=[" . $self->{uri} . ']' if $self->{uri};
    push @lines, @more if @more;
    my $total = 0;
    my $threshold = MT->config->PerformanceLoggingThreshold;
    foreach ( @{$self->{dur}} ) {
        my $dur = $_->[0];
        if ($_->[1] =~ m/^total\b/) {
            $dur = $_->[2];
        }
        if ($dur >= $threshold) {
            push @lines, sprintf("%s=%.5f", $_->[1], $dur);
        }
        $total += $_->[0];
    }
    push @lines, sprintf("Total=%.5f", $total);
    my @times = localtime(time);
    my $mon = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')[$times[4]];
    my $day = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat')[$times[6]];
    my $mday = $times[3];
    my $year = $times[5]+1900;
    my ($hr, $mn, $sc) = ($times[2], $times[1], $times[0]);
    my $ts = sprintf("%s %s %s %02d:%02d:%02d %04d", $day, $mon, $mday, $hr, $mn, $sc, $year);

    require Sys::Hostname; # available in core as of Perl 5.6.0
    my $hostname = Sys::Hostname::hostname();

    return "[$ts] $hostname pt-times: " . join(", ", @lines) . "\n";
}

sub dump {
    my $self = shift;
    my $lines = '';
    my $total = 0;
    my $threshold = MT->config->PerformanceLoggingThreshold;
    foreach ( @{$self->{dur}} ) {
        my $dur = $_->[0];
        if ($_->[1] =~ m/^total\b/) {
            $dur = $_->[2];
        }
        if ($dur >= $threshold) {
            $lines .= sprintf("%s - %.5f %s\n", $$, $dur, $_->[1]);
        }
        $total += $_->[0];
    }
    $lines .= sprintf("%s - %.5f --Total-- %s\n", $$, $total, $self->{uri});
    return $lines;
}

sub pause_partial {
    my $self = shift;
    my $now = Time::HiRes::time();
    push @{$self->{paused}}, [$self->{prev}, $now];

    $self->{prev} = $now;
}

sub unpause {
    my ($self) = @_;
    my $now = Time::HiRes::time();
    my $dur = $now - $self->{prev};
    $self->{elapsed} += $dur;
    if (@{$self->{paused}}) {
        my $paused = pop @{$self->{paused}};
        if (ref $paused ne 'ARRAY') {
            $paused = [];
        }
        my ($start, $end) = @$paused;

        #back up enough to account for the time spent doing other things
        $self->{prev} = $start - ($end - $now);
    } else {
        $self->{prev} = $now;
    }
}

sub total_elapsed {
    my $timer = shift;
    return Time::HiRes::time() - $timer->{first};
}

1;