Filename | /opt/flows/lib/lib/perl5/Log/Any/Manager.pm |
Statements | Executed 63 statements in 1.44ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
2 | 1 | 1 | 433µs | 1.16ms | _require_dynamic | Log::Any::Manager::
2 | 1 | 1 | 40µs | 1.29ms | get_adapter | Log::Any::Manager::
2 | 1 | 1 | 34µs | 1.21ms | _choose_entry_for_category | Log::Any::Manager::
1 | 1 | 1 | 18µs | 18µs | BEGIN@1 | Log::Any::
2 | 1 | 1 | 18µs | 19µs | _get_adapter_class | Log::Any::Manager::
2 | 1 | 1 | 16µs | 38µs | _new_adapter_for_entry | Log::Any::Manager::
1 | 1 | 1 | 10µs | 21µs | BEGIN@36 | Log::Any::Manager::
1 | 1 | 1 | 8µs | 13µs | BEGIN@3 | Log::Any::
1 | 1 | 1 | 7µs | 20µs | BEGIN@2 | Log::Any::
1 | 1 | 1 | 6µs | 6µs | new | Log::Any::Manager::
2 | 1 | 1 | 2µs | 2µs | CORE:subst (opcode) | Log::Any::Manager::
0 | 0 | 0 | 0s | 0s | DESTROY | Log::Any::Manager::_Guard::
0 | 0 | 0 | 0s | 0s | new | Log::Any::Manager::_Guard::
0 | 0 | 0 | 0s | 0s | __ANON__[:103] | Log::Any::Manager::
0 | 0 | 0 | 0s | 0s | _new_entry | Log::Any::Manager::
0 | 0 | 0 | 0s | 0s | _reselect_matching_adapters | Log::Any::Manager::
0 | 0 | 0 | 0s | 0s | remove | Log::Any::Manager::
0 | 0 | 0 | 0s | 0s | set | Log::Any::Manager::
0 | 0 | 0 | 0s | 0s | set_default | Log::Any::Manager::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | 2 | 52µs | 1 | 18µs | # spent 18µs within Log::Any::BEGIN@1 which was called:
# once (18µs+0s) by Log::Any::BEGIN@10 at line 1 # spent 18µs making 1 call to Log::Any::BEGIN@1 |
2 | 2 | 26µs | 2 | 34µs | # spent 20µs (7+13) within Log::Any::BEGIN@2 which was called:
# once (7µs+13µs) by Log::Any::BEGIN@10 at line 2 # spent 20µs making 1 call to Log::Any::BEGIN@2
# spent 13µs making 1 call to strict::import |
3 | 2 | 178µs | 2 | 17µs | # spent 13µs (8+5) within Log::Any::BEGIN@3 which was called:
# once (8µs+5µs) by Log::Any::BEGIN@10 at line 3 # spent 13µs making 1 call to Log::Any::BEGIN@3
# spent 5µs making 1 call to warnings::import |
4 | |||||
5 | package Log::Any::Manager; | ||||
6 | |||||
7 | 1 | 800ns | our $VERSION = '1.040'; | ||
8 | |||||
9 | # spent 6µs within Log::Any::Manager::new which was called:
# once (6µs+0s) by Search::Elasticsearch::Logger::LogAny::BEGIN@8 at line 27 of /opt/flows/lib/lib/perl5/Log/Any.pm | ||||
10 | 1 | 500ns | my $class = shift; | ||
11 | 1 | 2µs | my $self = { | ||
12 | entries => [], | ||||
13 | category_cache => {}, | ||||
14 | default_adapter => {}, | ||||
15 | }; | ||||
16 | 1 | 1µs | bless $self, $class; | ||
17 | |||||
18 | 1 | 6µs | return $self; | ||
19 | } | ||||
20 | |||||
21 | # spent 1.29ms (40µs+1.25) within Log::Any::Manager::get_adapter which was called 2 times, avg 644µs/call:
# 2 times (40µs+1.25ms) by Log::Any::get_logger at line 82 of /opt/flows/lib/lib/perl5/Log/Any.pm, avg 644µs/call | ||||
22 | 2 | 1µs | my ( $self, $category ) = @_; | ||
23 | |||||
24 | # Create a new adapter for this category if it is not already in cache | ||||
25 | # | ||||
26 | 2 | 9µs | my $category_cache = $self->{category_cache}; | ||
27 | 2 | 3µs | if ( !defined( $category_cache->{$category} ) ) { | ||
28 | 2 | 6µs | 2 | 1.21ms | my $entry = $self->_choose_entry_for_category($category); # spent 1.21ms making 2 calls to Log::Any::Manager::_choose_entry_for_category, avg 605µs/call |
29 | 2 | 6µs | 2 | 38µs | my $adapter = $self->_new_adapter_for_entry( $entry, $category ); # spent 38µs making 2 calls to Log::Any::Manager::_new_adapter_for_entry, avg 19µs/call |
30 | 2 | 5µs | $category_cache->{$category} = { entry => $entry, adapter => $adapter }; | ||
31 | } | ||||
32 | 2 | 7µs | return $category_cache->{$category}->{adapter}; | ||
33 | } | ||||
34 | |||||
35 | { | ||||
36 | 3 | 961µs | 2 | 32µs | # spent 21µs (10+11) within Log::Any::Manager::BEGIN@36 which was called:
# once (10µs+11µs) by Log::Any::BEGIN@10 at line 36 # spent 21µs making 1 call to Log::Any::Manager::BEGIN@36
# spent 11µs making 1 call to warnings::unimport |
37 | 1 | 2µs | *get_logger = \&get_adapter; # backwards compatibility | ||
38 | } | ||||
39 | |||||
40 | # spent 1.21ms (34µs+1.18) within Log::Any::Manager::_choose_entry_for_category which was called 2 times, avg 605µs/call:
# 2 times (34µs+1.18ms) by Log::Any::Manager::get_adapter at line 28, avg 605µs/call | ||||
41 | 2 | 1µs | my ( $self, $category ) = @_; | ||
42 | |||||
43 | 2 | 4µs | foreach my $entry ( @{ $self->{entries} } ) { | ||
44 | if ( $category =~ $entry->{pattern} ) { | ||||
45 | return $entry; | ||||
46 | } | ||||
47 | } | ||||
48 | # nothing requested so fallback to default | ||||
49 | 2 | 7µs | 2 | 19µs | my $default = $self->{default_adapter}{$category} # spent 19µs making 2 calls to Log::Any::Manager::_get_adapter_class, avg 10µs/call |
50 | || [ $self->_get_adapter_class("Null"), [] ]; | ||||
51 | 2 | 2µs | my ($adapter_class, $adapter_params) = @$default; | ||
52 | 2 | 5µs | 2 | 1.16ms | _require_dynamic($adapter_class); # spent 1.16ms making 2 calls to Log::Any::Manager::_require_dynamic, avg 579µs/call |
53 | return { | ||||
54 | 2 | 11µs | adapter_class => $adapter_class, | ||
55 | adapter_params => $adapter_params, | ||||
56 | }; | ||||
57 | } | ||||
58 | |||||
59 | # spent 38µs (16+22) within Log::Any::Manager::_new_adapter_for_entry which was called 2 times, avg 19µs/call:
# 2 times (16µs+22µs) by Log::Any::Manager::get_adapter at line 29, avg 19µs/call | ||||
60 | 2 | 2µs | my ( $self, $entry, $category ) = @_; | ||
61 | |||||
62 | return $entry->{adapter_class} | ||||
63 | 2 | 14µs | 2 | 22µs | ->new( @{ $entry->{adapter_params} }, category => $category ); # spent 22µs making 2 calls to Log::Any::Adapter::Base::new, avg 11µs/call |
64 | } | ||||
65 | |||||
66 | sub set_default { | ||||
67 | my ( $self, $category, $adapter_name, @adapter_params ) = @_; | ||||
68 | my $adapter_class = $self->_get_adapter_class($adapter_name); | ||||
69 | $self->{default_adapter}{$category} = [$adapter_class, \@adapter_params]; | ||||
70 | } | ||||
71 | |||||
72 | sub set { | ||||
73 | my $self = shift; | ||||
74 | my $options; | ||||
75 | if ( ref( $_[0] ) eq 'HASH' ) { | ||||
76 | $options = shift(@_); | ||||
77 | } | ||||
78 | my ( $adapter_name, @adapter_params ) = @_; | ||||
79 | |||||
80 | unless ( defined($adapter_name) && $adapter_name =~ /\S/ ) { | ||||
81 | require Carp; | ||||
82 | Carp::croak("expected adapter name"); | ||||
83 | } | ||||
84 | |||||
85 | my $pattern = $options->{category}; | ||||
86 | if ( !defined($pattern) ) { | ||||
87 | $pattern = qr/.*/; | ||||
88 | } | ||||
89 | elsif ( !ref($pattern) ) { | ||||
90 | $pattern = qr/^\Q$pattern\E$/; | ||||
91 | } | ||||
92 | |||||
93 | my $adapter_class = $self->_get_adapter_class($adapter_name); | ||||
94 | _require_dynamic($adapter_class); | ||||
95 | |||||
96 | my $entry = $self->_new_entry( $pattern, $adapter_class, \@adapter_params ); | ||||
97 | unshift( @{ $self->{entries} }, $entry ); | ||||
98 | |||||
99 | $self->_reselect_matching_adapters($pattern); | ||||
100 | |||||
101 | if ( my $lex_ref = $options->{lexically} ) { | ||||
102 | $$lex_ref = Log::Any::Manager::_Guard->new( | ||||
103 | sub { $self->remove($entry) unless _in_global_destruction() } ); | ||||
104 | } | ||||
105 | |||||
106 | return $entry; | ||||
107 | } | ||||
108 | |||||
109 | sub remove { | ||||
110 | my ( $self, $entry ) = @_; | ||||
111 | |||||
112 | my $pattern = $entry->{pattern}; | ||||
113 | $self->{entries} = [ grep { $_ ne $entry } @{ $self->{entries} } ]; | ||||
114 | $self->_reselect_matching_adapters($pattern); | ||||
115 | } | ||||
116 | |||||
117 | sub _new_entry { | ||||
118 | my ( $self, $pattern, $adapter_class, $adapter_params ) = @_; | ||||
119 | |||||
120 | return { | ||||
121 | pattern => $pattern, | ||||
122 | adapter_class => $adapter_class, | ||||
123 | adapter_params => $adapter_params, | ||||
124 | }; | ||||
125 | } | ||||
126 | |||||
127 | sub _reselect_matching_adapters { | ||||
128 | my ( $self, $pattern ) = @_; | ||||
129 | |||||
130 | return if _in_global_destruction(); | ||||
131 | |||||
132 | # Reselect adapter for each category matching $pattern | ||||
133 | # | ||||
134 | while ( my ( $category, $category_info ) = | ||||
135 | each( %{ $self->{category_cache} } ) ) | ||||
136 | { | ||||
137 | my $new_entry = $self->_choose_entry_for_category($category); | ||||
138 | if ( $new_entry ne $category_info->{entry} ) { | ||||
139 | my $new_adapter = | ||||
140 | $self->_new_adapter_for_entry( $new_entry, $category ); | ||||
141 | %{ $category_info->{adapter} } = %$new_adapter; | ||||
142 | bless( $category_info->{adapter}, ref($new_adapter) ); | ||||
143 | $category_info->{entry} = $new_entry; | ||||
144 | } | ||||
145 | } | ||||
146 | } | ||||
147 | |||||
148 | # spent 19µs (18+2) within Log::Any::Manager::_get_adapter_class which was called 2 times, avg 10µs/call:
# 2 times (18µs+2µs) by Log::Any::Manager::_choose_entry_for_category at line 49, avg 10µs/call | ||||
149 | 2 | 1µs | my ( $self, $adapter_name ) = @_; | ||
150 | 2 | 700ns | return $Log::Any::OverrideDefaultAdapterClass if $Log::Any::OverrideDefaultAdapterClass; | ||
151 | 2 | 10µs | 2 | 2µs | $adapter_name =~ s/^Log:://; # Log::Dispatch -> Dispatch, etc. # spent 2µs making 2 calls to Log::Any::Manager::CORE:subst, avg 750ns/call |
152 | 2 | 4µs | my $adapter_class = ( | ||
153 | substr( $adapter_name, 0, 1 ) eq '+' | ||||
154 | ? substr( $adapter_name, 1 ) | ||||
155 | : "Log::Any::Adapter::$adapter_name" | ||||
156 | ); | ||||
157 | 2 | 7µs | return $adapter_class; | ||
158 | } | ||||
159 | |||||
160 | # This is adapted from the pure perl parts of Devel::GlobalDestruction | ||||
161 | 1 | 4µs | if ( defined ${^GLOBAL_PHASE} ) { | ||
162 | 1 | 33µs | eval 'sub _in_global_destruction () { ${^GLOBAL_PHASE} eq q[DESTRUCT] }; 1' ## no critic # spent 2µs executing statements in string eval | ||
163 | or die $@; | ||||
164 | } | ||||
165 | else { | ||||
166 | require B; | ||||
167 | my $started = !B::main_start()->isa(q[B::NULL]); | ||||
168 | unless ($started) { | ||||
169 | eval '0 && $started; CHECK { $started = 1 }; 1' ## no critic | ||||
170 | or die $@; | ||||
171 | } | ||||
172 | eval ## no critic | ||||
173 | '0 && $started; sub _in_global_destruction () { $started && B::main_start()->isa(q[B::NULL]) }; 1' | ||||
174 | or die $@; | ||||
175 | } | ||||
176 | |||||
177 | # XXX not DRY and not a great way to do this, but oh, well. | ||||
178 | # spent 1.16ms (433µs+724µs) within Log::Any::Manager::_require_dynamic which was called 2 times, avg 579µs/call:
# 2 times (433µs+724µs) by Log::Any::Manager::_choose_entry_for_category at line 52, avg 579µs/call | ||||
179 | 2 | 1µs | my ($class) = @_; | ||
180 | |||||
181 | 2 | 26µs | 2 | 5µs | return 1 if $class->can('new'); # duck-type that class is loaded # spent 5µs making 2 calls to UNIVERSAL::can, avg 3µs/call |
182 | |||||
183 | 1 | 36µs | unless ( defined( eval "require $class; 1" ) ) # spent 77µs executing statements in string eval | ||
184 | { ## no critic (ProhibitStringyEval) | ||||
185 | die $@; | ||||
186 | } | ||||
187 | } | ||||
188 | |||||
189 | package # hide from PAUSE | ||||
190 | Log::Any::Manager::_Guard; | ||||
191 | |||||
192 | sub new { bless $_[1], $_[0] } | ||||
193 | |||||
194 | sub DESTROY { $_[0]->() } | ||||
195 | |||||
196 | 1 | 6µs | 1; | ||
# spent 2µs within Log::Any::Manager::CORE:subst which was called 2 times, avg 750ns/call:
# 2 times (2µs+0s) by Log::Any::Manager::_get_adapter_class at line 151, avg 750ns/call |