File Coverage

blib/lib/Log/Any/Plugin/ContextStack.pm
Criterion Covered Total %
statement 48 51 94.1
branch 6 10 60.0
condition n/a
subroutine 14 14 100.0
pod 1 1 100.0
total 69 76 90.7


line stmt bran cond sub pod time code
1             package Log::Any::Plugin::ContextStack;
2             # ABSTRACT: Stack of context items that get prepended to each log message
3             $Log::Any::Plugin::ContextStack::VERSION = '0.012';
4 1     1   1012 use strict;
  1         2  
  1         32  
5 1     1   5 use warnings;
  1         2  
  1         34  
6 1     1   5 use Carp qw( confess );
  1         1  
  1         65  
7 1     1   5 use Log::Any;
  1         2  
  1         5  
8 1     1   451 use Scope::Guard qw( guard );
  1         449  
  1         53  
9              
10 1     1   8 use Log::Any::Plugin::Util qw( get_old_method set_new_method );
  1         1  
  1         44  
11 1     1   5 use Log::Any::Adapter::Util qw( logging_methods );
  1         2  
  1         392  
12              
13             my @context_stack;
14             my $stringify_context = \&_default_stringify_context;
15              
16             sub install {
17 1     1 1 3 my ($class, $adapter_class, %args) = @_;
18              
19 1 50       5 if ($args{stringify}) {
20 0         0 $stringify_context = delete $args{stringify};
21             }
22              
23 1 50       5 if (%args) {
24 0         0 my $keys = join(', ', sort keys %args);
25 0         0 confess("Unexpected arguments $keys");
26             }
27              
28             # Create the $log->push method
29             set_new_method($adapter_class, push_context => sub {
30 2     2   2262 my $self = shift;
31 2         6 push(@context_stack, @_);
32 2         5 return $self;
33 1         7 });
34              
35             # Create the $log->pop method
36             set_new_method($adapter_class, pop_context => sub {
37 2     2   600 my $self = shift;
38 2         6 return pop(@context_stack);
39 1         5 });
40              
41             # Create the $log->context method
42             set_new_method($adapter_class, push_scoped_context => sub {
43 1     1   557 my $self = shift;
44 1 50       5 return unless @_;
45 1         3 my $count = scalar @_;
46 1         3 push(@context_stack, @_);
47 1     1   12 return guard { splice(@context_stack, -$count) };
  1         319  
48 1         4 });
49              
50             # Augment the main $log->debug methods (not the aliases)
51 1         5 for my $method_name ( logging_methods() ) {
52 9         20 my $old_method = get_old_method($adapter_class, $method_name);
53             set_new_method($adapter_class, $method_name, sub {
54 6     6   40 my $self = shift;
55 6 100       15 if (@context_stack) {
56 4         10 unshift(@_, $stringify_context->(\@context_stack));
57             }
58 6         22 $old_method->($self, @_);
59 9         30 });
60             }
61             }
62              
63             sub _default_stringify_context {
64 4     4   5 my ($context) = @_;
65 4 50       10 return '' unless @$context;
66 4         14 return '[' . join(':', @$context) . ']';
67             }
68              
69             1;
70              
71             __END__