Filename | /home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/CHI/Stats.pm |
Statements | Executed 18 statements in 758µs |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 2.12ms | 7.16ms | BEGIN@6 | CHI::Stats::
1 | 1 | 1 | 714µs | 8.55ms | BEGIN@3 | CHI::Stats::
1 | 1 | 1 | 426µs | 3.30ms | BEGIN@5 | CHI::Stats::
1 | 1 | 1 | 14µs | 19µs | BEGIN@8 | CHI::Stats::
1 | 1 | 1 | 9µs | 29µs | BEGIN@4 | CHI::Stats::
1 | 1 | 1 | 5µs | 6µs | BEGIN@7 | CHI::Stats::
0 | 0 | 0 | 0s | 0s | __ANON__[:114] | CHI::Stats::
0 | 0 | 0 | 0s | 0s | __ANON__[:11] | CHI::Stats::
0 | 0 | 0 | 0s | 0s | __ANON__[:12] | CHI::Stats::
0 | 0 | 0 | 0s | 0s | __ANON__[:131] | CHI::Stats::
0 | 0 | 0 | 0s | 0s | __ANON__[:13] | CHI::Stats::
0 | 0 | 0 | 0s | 0s | clear | CHI::Stats::
0 | 0 | 0 | 0s | 0s | disable | CHI::Stats::
0 | 0 | 0 | 0s | 0s | enable | CHI::Stats::
0 | 0 | 0 | 0s | 0s | flush | CHI::Stats::
0 | 0 | 0 | 0s | 0s | format_time | CHI::Stats::
0 | 0 | 0 | 0s | 0s | log_namespace_stats | CHI::Stats::
0 | 0 | 0 | 0s | 0s | parse_stats_logs | CHI::Stats::
0 | 0 | 0 | 0s | 0s | stats_for_driver | CHI::Stats::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package CHI::Stats; | ||||
2 | 1 | 400ns | $CHI::Stats::VERSION = '0.60'; | ||
3 | 2 | 62µs | 2 | 8.58ms | # spent 8.55ms (714µs+7.83) within CHI::Stats::BEGIN@3 which was called:
# once (714µs+7.83ms) by CHI::BEGIN@5 at line 3 # spent 8.55ms making 1 call to CHI::Stats::BEGIN@3
# spent 32µs making 1 call to Exporter::import |
4 | 2 | 19µs | 2 | 36µs | # spent 29µs (9+20) within CHI::Stats::BEGIN@4 which was called:
# once (9µs+20µs) by CHI::BEGIN@5 at line 4 # spent 29µs making 1 call to CHI::Stats::BEGIN@4
# spent 7µs making 1 call to List::Util::import |
5 | 2 | 52µs | 2 | 4.53ms | # spent 3.30ms (426µs+2.87) within CHI::Stats::BEGIN@5 which was called:
# once (426µs+2.87ms) by CHI::BEGIN@5 at line 5 # spent 3.30ms making 1 call to CHI::Stats::BEGIN@5
# spent 1.23ms making 1 call to Log::Any::import |
6 | 2 | 60µs | 2 | 8.34ms | # spent 7.16ms (2.12+5.04) within CHI::Stats::BEGIN@6 which was called:
# once (2.12ms+5.04ms) by CHI::BEGIN@5 at line 6 # spent 7.16ms making 1 call to CHI::Stats::BEGIN@6
# spent 1.18ms making 1 call to Moo::import |
7 | 2 | 12µs | 2 | 7µs | # spent 6µs (5+1) within CHI::Stats::BEGIN@7 which was called:
# once (5µs+1µs) by CHI::BEGIN@5 at line 7 # spent 6µs making 1 call to CHI::Stats::BEGIN@7
# spent 1µs making 1 call to strict::import |
8 | 2 | 536µs | 2 | 24µs | # spent 19µs (14+5) within CHI::Stats::BEGIN@8 which was called:
# once (14µs+5µs) by CHI::BEGIN@5 at line 8 # spent 19µs making 1 call to CHI::Stats::BEGIN@8
# spent 5µs making 1 call to warnings::import |
9 | |||||
10 | 1 | 2µs | 1 | 10.6ms | has 'chi_root_class' => ( is => 'ro' ); # spent 10.6ms making 1 call to Moo::has |
11 | 1 | 5µs | 1 | 97µs | has 'data' => ( is => 'ro', default => sub { {} } ); # spent 97µs making 1 call to Moo::has |
12 | 1 | 2µs | 1 | 117µs | has 'enabled' => ( is => 'rwp', default => sub { 0 } ); # spent 117µs making 1 call to Moo::has |
13 | 1 | 2µs | 1 | 75µs | has 'start_time' => ( is => 'ro', default => sub { time } ); # spent 75µs making 1 call to Moo::has |
14 | |||||
15 | sub enable { $_[0]->_set_enabled(1) } | ||||
16 | sub disable { $_[0]->_set_enabled(0) } | ||||
17 | |||||
18 | sub flush { | ||||
19 | my ($self) = @_; | ||||
20 | |||||
21 | my $data = $self->data; | ||||
22 | foreach my $label ( sort keys %$data ) { | ||||
23 | my $label_stats = $data->{$label}; | ||||
24 | foreach my $namespace ( sort keys(%$label_stats) ) { | ||||
25 | my $namespace_stats = $label_stats->{$namespace}; | ||||
26 | if (%$namespace_stats) { | ||||
27 | $self->log_namespace_stats( $label, $namespace, | ||||
28 | $namespace_stats ); | ||||
29 | } | ||||
30 | } | ||||
31 | } | ||||
32 | $self->clear(); | ||||
33 | } | ||||
34 | |||||
35 | sub log_namespace_stats { | ||||
36 | my ( $self, $label, $namespace, $namespace_stats ) = @_; | ||||
37 | |||||
38 | my %data = ( | ||||
39 | label => $label, | ||||
40 | end_time => time(), | ||||
41 | namespace => $namespace, | ||||
42 | root_class => $self->chi_root_class, | ||||
43 | %$namespace_stats | ||||
44 | ); | ||||
45 | %data = | ||||
46 | map { /_ms$/ ? ( $_, int( $data{$_} ) ) : ( $_, $data{$_} ) } | ||||
47 | keys(%data); | ||||
48 | $log->infof( 'CHI stats: %s', json_encode( \%data ) ); | ||||
49 | } | ||||
50 | |||||
51 | sub format_time { | ||||
52 | my ($time) = @_; | ||||
53 | |||||
54 | my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = | ||||
55 | localtime($time); | ||||
56 | return sprintf( | ||||
57 | "%04d%02d%02d:%02d:%02d:%02d", | ||||
58 | $year + 1900, | ||||
59 | $mon + 1, $mday, $hour, $min, $sec | ||||
60 | ); | ||||
61 | } | ||||
62 | |||||
63 | sub stats_for_driver { | ||||
64 | my ( $self, $cache ) = @_; | ||||
65 | |||||
66 | my $stats = | ||||
67 | ( $self->data->{ $cache->label }->{ $cache->namespace } ||= {} ); | ||||
68 | $stats->{start_time} ||= time; | ||||
69 | return $stats; | ||||
70 | } | ||||
71 | |||||
72 | sub parse_stats_logs { | ||||
73 | my $self = shift; | ||||
74 | my ( %results_hash, @results, %numeric_fields_seen ); | ||||
75 | foreach my $log_file (@_) { | ||||
76 | my $logfh; | ||||
77 | if ( ref($log_file) ) { | ||||
78 | $logfh = $log_file; | ||||
79 | } | ||||
80 | else { | ||||
81 | open( $logfh, '<', $log_file ) or die "cannot open $log_file: $!"; | ||||
82 | $log->infof( "processing '%s'", $log_file ); | ||||
83 | } | ||||
84 | while ( my $line = <$logfh> ) { | ||||
85 | chomp($line); | ||||
86 | if ( my ($json) = ( $line =~ /CHI stats: (\{.*\})$/ ) ) { | ||||
87 | my %hash = %{ json_decode($json) }; | ||||
88 | my $root_class = delete( $hash{root_class} ); | ||||
89 | my $namespace = delete( $hash{namespace} ); | ||||
90 | my $label = delete( $hash{label} ); | ||||
91 | my $results_set = | ||||
92 | ( $results_hash{$root_class}->{$label}->{$namespace} ||= {} ); | ||||
93 | if ( !%$results_set ) { | ||||
94 | $results_set->{root_class} = $root_class; | ||||
95 | $results_set->{namespace} = $namespace; | ||||
96 | $results_set->{label} = $label; | ||||
97 | push( @results, $results_set ); | ||||
98 | } | ||||
99 | while ( my ( $key, $value ) = each(%hash) ) { | ||||
100 | next if $key =~ /_time$/; | ||||
101 | $results_set->{$key} += $value; | ||||
102 | $numeric_fields_seen{$key}++; | ||||
103 | } | ||||
104 | } | ||||
105 | } | ||||
106 | } | ||||
107 | my @numeric_fields = sort( keys(%numeric_fields_seen) ); | ||||
108 | |||||
109 | my $sum = sub { | ||||
110 | my ( $rs, $name, @fields ) = @_; | ||||
111 | if ( grep { $rs->{$_} } @fields ) { | ||||
112 | $rs->{$name} = sum( map { $rs->{$_} || 0 } @fields ); | ||||
113 | } | ||||
114 | }; | ||||
115 | foreach my $rs (@results) { | ||||
116 | $sum->( $rs, 'misses', 'absent_misses', 'expired_misses' ); | ||||
117 | $sum->( $rs, 'gets', 'hits', 'misses' ); | ||||
118 | } | ||||
119 | |||||
120 | my %totals = map { ( $_, 'TOTALS' ) } qw(root_class namespace label); | ||||
121 | foreach my $field (@numeric_fields) { | ||||
122 | $totals{$field} = sum( map { $_->{$field} || 0 } @results ); | ||||
123 | } | ||||
124 | push( @results, \%totals ); | ||||
125 | |||||
126 | my $divide = sub { | ||||
127 | my ( $rs, $name, $top, $bottom ) = @_; | ||||
128 | if ( $rs->{$top} && $rs->{$bottom} ) { | ||||
129 | $rs->{$name} = ( $rs->{$top} / $rs->{$bottom} ); | ||||
130 | } | ||||
131 | }; | ||||
132 | |||||
133 | foreach my $rs (@results) { | ||||
134 | $divide->( $rs, 'avg_compute_time_ms', 'compute_time_ms', 'computes' ); | ||||
135 | $divide->( $rs, 'avg_get_time_ms', 'get_time_ms', 'gets' ); | ||||
136 | $divide->( $rs, 'avg_set_time_ms', 'set_time_ms', 'sets' ); | ||||
137 | $divide->( $rs, 'avg_set_key_size', 'set_key_size', 'sets' ); | ||||
138 | $divide->( $rs, 'avg_set_value_size', 'set_value_size', 'sets' ); | ||||
139 | $divide->( $rs, 'hit_rate', 'hits', 'gets' ); | ||||
140 | } | ||||
141 | return \@results; | ||||
142 | } | ||||
143 | |||||
144 | sub clear { | ||||
145 | my ($self) = @_; | ||||
146 | |||||
147 | my $data = $self->data; | ||||
148 | foreach my $key ( keys %{$data} ) { | ||||
149 | %{ $data->{$key} } = (); | ||||
150 | } | ||||
151 | $self->{start_time} = time; | ||||
152 | } | ||||
153 | |||||
154 | 1 | 6µs | 1; | ||
155 | |||||
156 | __END__ |