File Coverage

blib/lib/Log/Any/Proxy.pm
Criterion Covered Total %
statement 72 78 92.3
branch 37 44 84.0
condition 19 26 73.0
subroutine 17 17 100.0
pod 0 3 0.0
total 145 168 86.3


line stmt bran cond sub pod time code
1 40     40   145346 use 5.008001;
  40         154  
2 40     40   170 use strict;
  40         105  
  40         958  
3 40     40   142 use warnings;
  40         82  
  40         2751  
4              
5             package Log::Any::Proxy;
6              
7             # ABSTRACT: Log::Any generator proxy object
8             our $VERSION = '1.718';
9              
10 40     40   1056 use Log::Any::Adapter::Util ();
  40         73  
  40         959  
11 40     40   12593 use overload;
  40         34556  
  40         258  
12              
13             sub _stringify_params {
14 54     54   128 my @params = @_;
15              
16             return map {
17 54 100       100 !defined($_)
  38 100       227  
    100          
18             ? ''
19             : ref($_) ? (
20             overload::OverloadedStringify($_)
21             ? "$_"
22             : Log::Any::Adapter::Util::dump_one_line($_)
23             )
24             : $_
25             } @params;
26             }
27              
28             sub _default_formatter {
29 42     42   107 my ( $cat, $lvl, $format, @params ) = @_;
30 42 100       121 return $format->() if ref($format) eq 'CODE';
31              
32 41         114 my @new_params = _stringify_params(@params);
33              
34             # Perl 5.22 adds a 'redundant' warning if the number parameters exceeds
35             # the number of sprintf placeholders. If a user does this, the warning
36             # is issued from here, which isn't very helpful. Doing something
37             # clever would be expensive, so instead we just disable warnings for
38             # the final line of this subroutine.
39 40     40   7004 no warnings;
  40         69  
  40         10531  
40 41         532 return sprintf( $format, @new_params );
41             }
42              
43             sub new {
44 69     69 0 177 my $class = shift;
45 69         289 my $self = { formatter => \&_default_formatter, @_ };
46 69 50       266 unless ( $self->{adapter} ) {
47 0         0 require Carp;
48 0         0 Carp::croak("$class requires an 'adapter' parameter");
49             }
50 69 50       195 unless ( defined $self->{category} ) {
51 0         0 require Carp;
52 0         0 Carp::croak("$class requires a 'category' parameter");
53             }
54 69 50       179 unless ( $self->{context} ) {
55 0         0 require Carp;
56 0         0 Carp::croak("$class requires a 'context' parameter");
57             }
58 69         127 bless $self, $class;
59 69         242 $self->init(@_);
60 69         215 return $self;
61             }
62              
63             sub clone {
64 1     1 0 11 my $self = shift;
65 1         3 return (ref $self)->new( %{ $self }, @_ );
  1         5  
66             }
67              
68       69 0   sub init { }
69              
70             for my $attr (qw/adapter category filter formatter prefix context/) {
71 40     40   254 no strict 'refs';
  40         69  
  40         5888  
72 54     54   355044 *{$attr} = sub { return $_[0]->{$attr} };
73             }
74              
75             my %aliases = Log::Any::Adapter::Util::log_level_aliases();
76              
77             # Set up methods/aliases and detection methods/aliases
78             foreach my $name ( Log::Any::Adapter::Util::logging_methods(), keys(%aliases) )
79             {
80             my $realname = $aliases{$name} || $name;
81             my $namef = $name . "f";
82             my $is_name = "is_$name";
83             my $is_realname = "is_$realname";
84             my $numeric = Log::Any::Adapter::Util::numeric_level($realname);
85 40     40   212 no strict 'refs';
  40         58  
  40         21290  
86             *{$is_name} = sub {
87 89     89   519196 my ($self) = @_;
88 89         582 return $self->{adapter}->$is_realname;
89             };
90             *{$name} = sub {
91 134     134   408146 my ( $self, @parts ) = @_;
92 134 100 100     807 return if !$self->{adapter}->$is_realname && !defined wantarray;
93              
94             my $structured_logging =
95 129   66     811 $self->{adapter}->can('structured') && !$self->{filter};
96              
97 129 100 100     831 my $data_from_parts = pop @parts
      66        
98             if ( @parts && ( ( ref $parts[-1] || '' ) eq ref {} ) );
99 129         286 my $data_from_context = $self->{context};
100             my $data =
101 129 100       260 { map {%$_} grep {$_ && %$_} $data_from_context, $data_from_parts };
  30         96  
  258         812  
102              
103 129 100       339 if ($structured_logging) {
104 34 50       74 unshift @parts, $self->{prefix} if $self->{prefix};
105             $self->{adapter}
106 34         63 ->structured( $realname, $self->{category}, @parts, grep {%$_} $data );
  34         110  
107 34 100       2394 return unless defined wantarray;
108             }
109              
110 107 50       181 @parts = grep { defined($_) && length($_) } @parts;
  117         490  
111 107 100       234 push @parts, _stringify_params($data) if %$data;
112              
113 107         774 my $message = join( " ", @parts );
114 107 100 100     367 if ( length $message && !$structured_logging ) {
115             $message =
116             $self->{filter}->( $self->{category}, $numeric, $message )
117 68 100       157 if defined $self->{filter};
118 68 50 33     227 if ( defined $message and length $message ) {
119             $message = "$self->{prefix}$message"
120 68 100 66     195 if defined $self->{prefix} && length $self->{prefix};
121 68         249 $self->{adapter}->$realname($message);
122             }
123             }
124 107 100       518 return $message if defined wantarray;
125             };
126             *{$namef} = sub {
127 46     46   176278 my ( $self, @args ) = @_;
128 46 50 66     207 return if !$self->{adapter}->$is_realname && !defined wantarray;
129             my $message =
130 46         175 $self->{formatter}->( $self->{category}, $numeric, @args );
131 46 100 66     261 return unless defined $message and length $message;
132 19         85 return $self->$name($message);
133             };
134             }
135              
136             1;
137              
138              
139             # vim: ts=4 sts=4 sw=4 et tw=75:
140              
141             __END__