File Coverage

blib/lib/Log/Any/Adapter/Daemontools.pm
Criterion Covered Total %
statement 98 105 93.3
branch 16 24 66.6
condition 11 15 73.3
subroutine 28 31 90.3
pod 4 8 50.0
total 157 183 85.7


line stmt bran cond sub pod time code
1             package Log::Any::Adapter::Daemontools;
2 25     25   290339 use 5.008; # need weak reference support
  25         122  
3 25     25   1875 our @ISA; BEGIN { require Log::Any::Adapter::Base; @ISA= 'Log::Any::Adapter::Base' };
  25         3304  
4 25     25   160 use strict;
  25         48  
  25         524  
5 25     25   123 use warnings;
  25         47  
  25         739  
6 25     25   143 use Log::Any::Adapter::Util 'numeric_level';
  25         54  
  25         1382  
7 25     25   150 use Log::Any 1.03;
  25         436  
  25         141  
8 25     25   14167 use Log::Any::Adapter::Daemontools::Config;
  25         75  
  25         14175  
9              
10             # ABSTRACT: Logging adapter suitable for use in a Daemontools-style logging chain
11             our $VERSION = '0.102'; # VERSION
12              
13              
14             our $global_config;
15             sub global_config {
16 28   66 28 1 819 $global_config ||= shift->new_config;
17             }
18              
19             sub new_config {
20 27     27 1 2959 my $class= shift;
21 27   66     125 $class= ref($class) || $class;
22 27         156 my $cfg= "${class}::Config"->new(@_);
23 27         197 return $cfg;
24             }
25              
26              
27 6     6 1 63 sub category { shift->{category} }
28 120     120 1 491 sub config { shift->{config} }
29              
30              
31             # Special carp/croak that ignore Log::Any infrastructure
32 3     3 0 10 sub carp { Log::Any::Adapter::Daemontools::Config::carp(@_) }
33 0     0 0 0 sub croak { Log::Any::Adapter::Daemontools::Config::croak(@_) }
34              
35             # Log::Any::Adapter constructor, also named 'init'
36             sub init {
37 29     29 0 9793 my $self= shift;
38            
39 29   66     261 $self->{config} ||= $self->global_config;
40            
41             # Warn about unsupported/deprecated features from 0.002
42 29 100       101 carp "filter is deprecated. Use config->log_level" if exists $self->{filter};
43 29 50       102 carp "dumper is unsupported. See Log::Any::Proxy" if exists $self->{dumper};
44            
45            
46             # This constructor gets called for each Adapter instance, so we need
47             # to track whether we applied the -init to the config yet.
48 29 100 100     150 if ($self->{'-init'} && !$self->{config}{_adapter_init_applied}) {
49 18         52 ++$self->{config}{_adapter_init_applied};
50 18         63 $self->{config}->init( $self->{'-init'} );
51             }
52              
53             # Set up our lazy caching system (re-blesses current object)
54 29         111 $self->_uncache_config;
55             }
56              
57              
58 29 50   29   287 sub _squelch_base_class { ref($_[0]) || $_[0] }
59              
60             # Create per-squelch-level subclasses of a given package
61             # This is an optimization for minimizing overhead when using disabled levels
62             sub _build_squelch_subclasses {
63 25     25   70 my $class= shift;
64 25         158 my %numeric_levels= ( map { $_ => 1 } -1, map { numeric_level($_) } Log::Any->logging_methods() );
  250         818  
  225         1620  
65 25         106 my %subclass;
66 25         137 foreach my $level_num (keys %numeric_levels) {
67 250         1595 my $package= $class.'::Squelch'.($level_num+1);
68 250     16   1284 $subclass{$package}{_squelch_base_class}= sub { $class };
  16         75  
69 250         736 foreach my $method (Log::Any->logging_methods(), 'fatal') {
70 2500 100       10962 if ($level_num < numeric_level($method)) {
71 1200     0   10670 $subclass{$package}{$method}= sub {};
72 1200     21   5272 $subclass{$package}{"is_$method"}= sub { 0 };
  21         817  
73             }
74             }
75             }
76 25     40   267 $subclass{"${class}::Lazy"}{_squelch_base_class}= sub { $class };
  40         176  
77 25         164 foreach my $method (Log::Any->logging_and_detection_methods(), 'fatal', 'is_fatal') {
78             # Trampoline code that lazily re-caches an adaptor the first time it is used
79             $subclass{"${class}::Lazy"}{$method}= sub {
80 40     40   14266 $_[0]->_cache_config;
81 40         322 goto $_[0]->can($method)
82 500         2130 };
83             }
84            
85             # Create subclasses and install methods
86 25         123 for my $pkg (keys %subclass) {
87 25     25   229 no strict 'refs';
  25         98  
  25         5597  
88 275         457 @{$pkg.'::ISA'}= ( $class );
  275         4848  
89 275         683 for my $method (keys %{ $subclass{$pkg} }) {
  275         1425  
90 3175         5149 *{$pkg.'::'.$method}= $subclass{$pkg}{$method};
  3175         12325  
91             }
92             }
93 25         13756 1;
94             }
95              
96             # The set of adapters which have been "squelch-cached"
97             # (i.e. blessed into a subclass)
98             our %_squelch_cached_adapters;
99              
100             BEGIN {
101 25     25   248 foreach my $method ( Log::Any->logging_methods() ) {
102 225     31   980 my $m= sub { my $self= shift; $self->{_writer}->($self, $method, @_); };
  31         1108  
  31         837  
103 25     25   219 no strict 'refs';
  25         54  
  25         2604  
104 225         409 *{__PACKAGE__ . "::$method"}= $m;
  225         998  
105 225     50   639 *{__PACKAGE__ . "::is_$method"}= sub { 1 };
  225         1111  
  50         12034  
106             }
107 25         152 __PACKAGE__->_build_squelch_subclasses();
108             }
109              
110             # Cache the ->config settings into this adapter, which also
111             # re-blesses it based on the current log level.
112             sub _cache_config {
113 40     40   89 my $self= shift;
114 40         155 $self->{_writer}= $self->config->compiled_writer;
115 40         129 my $lev= $self->config->log_level_num;
116             # Backward compatibility with version 0.002
117 40 100       135 if (exists $self->{filter}) {
118 3         42 $lev= Log::Any::Adapter::Util::NOTICE - _coerce_filter_level($self->{filter});
119             }
120 40         108 bless $self, $self->_squelch_base_class.'::Squelch'.($lev+1);
121 40         184 $self->config->_register_cached_adapter($self);
122             }
123              
124             # Re-bless adapter back to its "Lazy" config cacher class
125             sub _uncache_config {
126 45     45   194 bless $_[0], $_[0]->_squelch_base_class . '::Lazy';
127             }
128              
129             #-------------------------------------------------------------------
130             # Backward compatibility with version 0.002. Do not use in new code.
131              
132             sub write_msg {
133 0     0 0 0 my ($self, $level, $message)= @_;
134             # Don't bother optimizing and caching
135 0         0 $self->config->compiled_writer->($self, $level, $message);
136             }
137              
138             sub _default_dumper {
139 1     1   551 require Data::Dumper;
140 1         5567 my $val= shift;
141 1         2 local $@;
142 1         3 my $dump= eval { Data::Dumper->new([$val])->Indent(0)->Terse(1)->Useqq(1)->Quotekeys(0)->Maxdepth(4)->Sortkeys(1)->Dump };
  1         7  
143 1 50       82 if (!defined $dump) {
144 0         0 my $x= "$@";
145 0         0 $x =~ s/\n//;
146 0 0       0 substr($x, 50)= '...' if length $x >= 50;
147 0         0 $dump= "";
148             };
149 1         6 return $dump;
150             }
151              
152             sub _coerce_filter_level {
153 3     3   6 my $val= shift;
154 3         13 my %level_map= (
155             trace => -2,
156             debug => -1,
157             info => 0,
158             notice => 1,
159             warning => 2,
160             error => 3,
161             critical => 4,
162             fatal => 4,
163             );
164             return (!defined $val || $val eq 'none')? $level_map{trace}-1
165             : Scalar::Util::looks_like_number($val)? $val
166             : exists $level_map{$val}? $level_map{$val}
167 3 0 66     26 : ($val =~ /^debug-(\d+)$/)? $level_map{debug} - $1
    50          
    100          
    100          
168             : croak "unknown log level '$val'";
169             }
170              
171             1;
172              
173             __END__