File Coverage

blib/lib/Log/ger/Util.pm
Criterion Covered Total %
statement 100 170 58.8
branch 36 84 42.8
condition 3 14 21.4
subroutine 17 29 58.6
pod 0 18 0.0
total 156 315 49.5


line stmt bran cond sub pod time code
1             package Log::ger::Util;
2              
3 8     8   257499 use strict;
  8         52  
  8         202  
4 8     8   34 use warnings;
  8         13  
  8         623  
5              
6             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
7             our $DATE = '2022-06-10'; # DATE
8             our $DIST = 'Log-ger'; # DIST
9             our $VERSION = '0.040'; # VERSION
10              
11             require Log::ger;
12             require Log::ger::Heavy;
13              
14             sub _dump {
15 0 0   0   0 unless ($Log::ger::_dumper) {
16 0         0 eval {
17 8     8   44 no warnings 'once';
  8         14  
  8         520  
18 0         0 require Data::Dmp;
19 0         0 $Data::Dmp::OPT_REMOVE_PRAGMAS = 1;
20 0         0 1;
21             };
22 0 0       0 if ($@) {
23 8     8   55 no warnings 'once';
  8         18  
  8         3155  
24 0         0 require Data::Dumper;
25             $Log::ger::_dumper = sub {
26 0     0   0 local $Data::Dumper::Terse = 1;
27 0         0 local $Data::Dumper::Indent = 0;
28 0         0 local $Data::Dumper::Useqq = 1;
29 0         0 local $Data::Dumper::Deparse = 1;
30 0         0 local $Data::Dumper::Quotekeys = 0;
31 0         0 local $Data::Dumper::Sortkeys = 1;
32 0         0 local $Data::Dumper::Trailingcomma = 1;
33 0         0 local $Data::Dumper::Useqq = 1; # to show "\034", possible bug in Data::Dumper
34 0         0 Data::Dumper::Dumper($_[0]);
35 0         0 };
36             } else {
37 0     0   0 $Log::ger::_dumper = sub { Data::Dmp::dmp($_[0]) };
  0         0  
38             }
39             }
40 0         0 $Log::ger::_dumper->($_[0]);
41             }
42              
43             sub numeric_level {
44 15     15 0 933 my $level = shift;
45 15 100       89 return $level if $level =~ /\A\d+\z/;
46             return $Log::ger::Levels{$level}
47 2 50       11 if defined $Log::ger::Levels{$level};
48             return $Log::ger::Level_Aliases{$level}
49 0 0       0 if defined $Log::ger::Level_Aliases{$level};
50 0         0 die "Unknown level '$level'";
51             }
52              
53             sub string_level {
54 3     3 0 2120 my $level = shift;
55 3 100       11 return $level if defined $Log::ger::Levels{$level};
56             $level = $Log::ger::Level_Aliases{$level}
57 2 100       5 if defined $Log::ger::Level_Aliases{$level};
58 2         7 for (keys %Log::ger::Levels) {
59 7         8 my $v = $Log::ger::Levels{$_};
60 7 100       17 return $_ if $v == $level;
61             }
62 0         0 die "Unknown level '$level'";
63             }
64              
65             sub set_level {
66 8     8   51 no warnings 'once';
  8         11  
  8         544  
67 11     11 0 16365 $Log::ger::Current_Level = numeric_level(shift);
68 11         27 reinit_all_targets();
69             }
70              
71             sub _action_on_hooks {
72 8     8   44 no warnings 'once';
  8         13  
  8         8365  
73              
74 23     23   80 my ($action, $target_type, $target_name, $phase) = splice @_, 0, 4;
75              
76 23 50       77 my $hooks = $Log::ger::Global_Hooks{$phase} or die "Unknown phase '$phase'";
77 23 100       111 if ($target_type eq 'package') {
    50          
    50          
78 4   50     18 $hooks = ($Log::ger::Per_Package_Hooks{$target_name}{$phase} ||= []);
79             } elsif ($target_type eq 'object') {
80 0         0 my ($addr) = $target_name =~ $Log::ger::re_addr;
81 0   0     0 $hooks = ($Log::ger::Per_Object_Hooks{$addr}{$phase} ||= []);
82             } elsif ($target_type eq 'hash') {
83 0         0 my ($addr) = $target_name =~ $Log::ger::re_addr;
84 0   0     0 $hooks = ($Log::ger::Per_Hash_Hooks{$addr}{$phase} ||= []);
85             }
86              
87 23 100       65 if ($action eq 'add') {
    50          
    50          
    0          
    0          
    0          
88 20         33 my $hook = shift;
89             # XXX remove duplicate key
90             # my $key = $hook->[0];
91 20         57 unshift @$hooks, $hook;
92             } elsif ($action eq 'remove') {
93 0         0 my $code = shift;
94 0         0 for my $i (reverse 0..$#{$hooks}) {
  0         0  
95 0 0       0 splice @$hooks, $i, 1 if $code->($hooks->[$i]);
96             }
97             } elsif ($action eq 'reset') {
98 3         9 my $saved = [@$hooks];
99             splice @$hooks, 0, scalar(@$hooks),
100 3         8 @{ $Log::ger::Default_Hooks{$phase} };
  3         14  
101 3         11 return $saved;
102             } elsif ($action eq 'empty') {
103 0         0 my $saved = [@$hooks];
104 0         0 splice @$hooks, 0;
105 0         0 return $saved;
106             } elsif ($action eq 'save') {
107 0         0 return [@$hooks];
108             } elsif ($action eq 'restore') {
109 0         0 my $saved = shift;
110 0         0 splice @$hooks, 0, scalar(@$hooks), @$saved;
111 0         0 return $saved;
112             }
113             }
114              
115             sub add_hook {
116 16     16 0 40 my ($phase, $hook) = @_;
117 16         58 _action_on_hooks('add', '', undef, $phase, $hook);
118             }
119              
120             sub add_per_target_hook {
121 4     4 0 10 my ($target_type, $target_name, $phase, $hook) = @_;
122 4         8 _action_on_hooks('add', $target_type, $target_name, $phase, $hook);
123             }
124              
125             sub remove_hook {
126 0     0 0 0 my ($phase, $code) = @_;
127 0         0 _action_on_hooks('remove', '', undef, $phase, $code);
128             }
129              
130             sub remove_per_target_hook {
131 0     0 0 0 my ($target_type, $target_name, $phase, $code) = @_;
132 0         0 _action_on_hooks('remove', $target_type, $target_name, $phase, $code);
133             }
134              
135             sub reset_hooks {
136 3     3 0 5905 my ($phase) = @_;
137 3         12 _action_on_hooks('reset', '', undef, $phase);
138             }
139              
140             sub reset_per_target_hooks {
141 0     0 0 0 my ($target_type, $target_name, $phase) = @_;
142 0         0 _action_on_hooks('reset', $target_type, $target_name, $phase);
143             }
144              
145             sub empty_hooks {
146 0     0 0 0 my ($phase) = @_;
147 0         0 _action_on_hooks('empty', '', undef, $phase);
148             }
149              
150             sub empty_per_target_hooks {
151 0     0 0 0 my ($target_type, $target_name, $phase) = @_;
152 0         0 _action_on_hooks('empty', $target_type, $target_name, $phase);
153             }
154              
155             sub save_hooks {
156 0     0 0 0 my ($phase) = @_;
157 0         0 _action_on_hooks('save', '', undef, $phase);
158             }
159              
160             sub save_per_target_hooks {
161 0     0 0 0 my ($target_type, $target_name, $phase) = @_;
162 0         0 _action_on_hooks('save', $target_type, $target_name, $phase);
163             }
164              
165             sub restore_hooks {
166 0     0 0 0 my ($phase, $saved) = @_;
167 0         0 _action_on_hooks('restore', '', undef, $phase, $saved);
168             }
169              
170             sub restore_per_target_hooks {
171 0     0 0 0 my ($target_type, $target_name, $phase, $saved) = @_;
172 0         0 _action_on_hooks('restore', $target_type, $target_name, $phase, $saved);
173             }
174              
175             sub reinit_target {
176 2     2 0 5 my ($target_type, $target_name) = @_;
177              
178             # adds target if not already exists
179 2         10 Log::ger::add_target($target_type, $target_name, {}, 0);
180              
181 2 50       5 if ($target_type eq 'package') {
    0          
    0          
182 2         4 my $per_target_conf = $Log::ger::Package_Targets{$target_name};
183 2         7 Log::ger::init_target(package => $target_name, $per_target_conf);
184             } elsif ($target_type eq 'object') {
185 0 0       0 my ($obj_addr) = $target_name =~ $Log::ger::re_addr
186             or die "Invalid object '$target_name': not a reference";
187 0 0       0 my $v = $Log::ger::Object_Targets{$obj_addr}
188             or die "Unknown object target '$target_name'";
189 0         0 Log::ger::init_target(object => $v->[0], $v->[1]);
190             } elsif ($target_type eq 'hash') {
191 0 0       0 my ($hash_addr) = $target_name =~ $Log::ger::re_addr
192             or die "Invalid hashref '$target_name': not a reference";
193 0 0       0 my $v = $Log::ger::Hash_Targets{$hash_addr}
194             or die "Unknown hash target '$target_name'";
195 0         0 Log::ger::init_target(hash => $v->[0], $v->[1]);
196             } else {
197 0         0 die "Unknown target type '$target_type'";
198             }
199             }
200              
201             sub reinit_all_targets {
202 27     27 0 76 for my $pkg (keys %Log::ger::Package_Targets) {
203             #print "D:reinit package $pkg\n";
204             Log::ger::init_target(
205 28         99 package => $pkg, $Log::ger::Package_Targets{$pkg});
206             }
207 27         79 for my $k (keys %Log::ger::Object_Targets) {
208 18         25 my ($obj, $per_target_conf) = @{ $Log::ger::Object_Targets{$k} };
  18         30  
209 18         35 Log::ger::init_target(object => $obj, $per_target_conf);
210             }
211 27         206 for my $k (keys %Log::ger::Hash_Targets) {
212 4         5 my ($hash, $per_target_conf) = @{ $Log::ger::Hash_Targets{$k} };
  4         9  
213 4         8 Log::ger::init_target(hash => $hash, $per_target_conf);
214             }
215             }
216              
217             sub set_plugin {
218 18     18 0 55 my %args = @_;
219              
220 18         70 my $hooks;
221 18 50       52 if ($args{hooks}) {
222 0         0 $hooks = $args{hooks};
223             } else {
224 8     8   61 no strict 'refs'; ## no critic: TestingAndDebugging::ProhibitNoStrict
  8         14  
  8         3845  
225 18   50     52 my $prefix = $args{prefix} || 'Log::ger::Plugin::';
226 18         38 my $mod = $args{name};
227 18 50       73 $mod = $prefix . $mod unless index($mod, $prefix) == 0;
228 18         107 (my $mod_pm = "$mod.pm") =~ s!::!/!g;
229 18         4332 require $mod_pm;
230 18 50       216 my $meta = $mod->can("meta") ? $mod->meta : {v=>1};
231 18   50     70 my $v = $meta->{v} || 1;
232              
233             # history of v bumping:
234             #
235             # - v increased from 1 to 2 in Log::ger v0.037 to force all plugins that
236             # were not compatible with Log::ger 0.032 (removed
237             # create_logml_routine phase) to be upgraded.
238              
239 18 50       53 unless ($v == 2) {
240             die "Plugin '$mod' (version ".(${"$mod\::VERSION"} || "dev").")".
241             " follows meta version $v but Log::ger (version ".
242 0   0     0 (${__PACKAGE__."::VERSION"} || "dev").
      0        
243             ") (>0.032) requires meta version 2, ".
244             "please upgrade the plugin first";
245             }
246 18 50       32 $hooks = &{"$mod\::get_hooks"}(%{ $args{conf} || {} });
  18         81  
  18         62  
247             }
248              
249             {
250 18 100       37 last unless $args{replace_package_regex};
  18         56  
251 16         37 my $all_hooks;
252 16 50       41 if (!$args{target}) {
    0          
    0          
    0          
253 16         34 $all_hooks = \%Log::ger::Global_Hooks;
254             } elsif ($args{target} eq 'package') {
255 0         0 $all_hooks = $Log::ger::Per_Package_Hooks{ $args{target_arg} };
256             } elsif ($args{target} eq 'object') {
257 0         0 my ($addr) = $args{target_arg} =~ $Log::ger::re_addr;
258 0         0 $all_hooks = $Log::ger::Per_Object_Hooks{$addr};
259             } elsif ($args{target} eq 'hash') {
260 0         0 my ($addr) = $args{target_arg} =~ $Log::ger::re_addr;
261 0         0 $all_hooks = $Log::ger::Per_Hash_Hooks{$addr};
262             }
263 16 50       39 last unless $all_hooks;
264 16         77 for my $phase (keys %$all_hooks) {
265 160         240 my $hooks = $all_hooks->{$phase};
266 160         174 for my $i (reverse 0..$#{$hooks}) {
  160         233  
267             splice @$hooks, $i, 1
268 71 100       284 if $hooks->[$i][0] =~ $args{replace_package_regex};
269             }
270             }
271             }
272              
273 18         59 for my $phase (keys %$hooks) {
274 20         37 my $hook = $hooks->{$phase};
275 20 100       46 if (defined $args{target}) {
276             add_per_target_hook(
277 4         11 $args{target}, $args{target_arg}, $phase, $hook);
278             } else {
279 16         53 add_hook($phase, $hook);
280             }
281             }
282              
283 18         83 my $reinit = $args{reinit};
284 18 50       50 $reinit = 1 unless defined $reinit;
285 18 50       42 if ($reinit) {
286 18 100       43 if (defined $args{target}) {
287 2         7 reinit_target($args{target}, $args{target_arg});
288             } else {
289 16         45 reinit_all_targets();
290             }
291             }
292             }
293              
294             1;
295             # ABSTRACT: Utility routines for Log::ger
296              
297             __END__