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 29 31 93.5
pod 4 8 50.0
total 158 183 86.3


line stmt bran cond sub pod time code
1             package Log::Any::Adapter::Daemontools;
2 24     24   145956 use 5.008; # need weak reference support
  24         83  
3 24     24   3237 our @ISA; BEGIN { require Log::Any::Adapter::Base; @ISA= 'Log::Any::Adapter::Base' };
  24         2861  
4 24     24   120 use strict;
  24         51  
  24         555  
5 24     24   123 use warnings;
  24         38  
  24         707  
6 24     24   122 use Log::Any::Adapter::Util 'numeric_level';
  24         45  
  24         1547  
7 24     24   127 use Log::Any 1.03;
  24         415  
  24         144  
8 24     24   18173 use Log::Any::Adapter::Daemontools::Config;
  24         61  
  24         15082  
9              
10             our $VERSION= '0.100002';
11              
12             # ABSTRACT: Logging adapter suitable for use in a Daemontools-style logging chain
13              
14              
15             our $global_config;
16             sub global_config {
17 27   66 27 1 729 $global_config ||= shift->new_config;
18             }
19              
20             sub new_config {
21 26     26 1 2959 my $class= shift;
22 26   66     120 $class= ref($class) || $class;
23 26         158 my $cfg= "${class}::Config"->new(@_);
24 26         203 return $cfg;
25             }
26              
27              
28 6     6 1 79 sub category { shift->{category} }
29 117     117 1 607 sub config { shift->{config} }
30              
31              
32             # Special carp/croak that ignore Log::Any infrastructure
33 3     3 0 10 sub carp { Log::Any::Adapter::Daemontools::Config::carp(@_) }
34 0     0 0 0 sub croak { Log::Any::Adapter::Daemontools::Config::croak(@_) }
35              
36             # Log::Any::Adapter constructor, also named 'init'
37             sub init {
38 28     28 0 15753 my $self= shift;
39            
40 28   66     289 $self->{config} ||= $self->global_config;
41            
42             # Warn about unsupported/deprecated features from 0.002
43 28 100       108 carp "filter is deprecated. Use config->log_level" if exists $self->{filter};
44 28 50       99 carp "dumper is unsupported. See Log::Any::Proxy" if exists $self->{dumper};
45            
46            
47             # This constructor gets called for each Adapter instance, so we need
48             # to track whether we applied the -init to the config yet.
49 28 100 100     179 if ($self->{'-init'} && !$self->{config}{_adapter_init_applied}) {
50 17         40 ++$self->{config}{_adapter_init_applied};
51 17         83 $self->{config}->init( $self->{'-init'} );
52             }
53              
54             # Set up our lazy caching system (re-blesses current object)
55 28         143 $self->_uncache_config;
56             }
57              
58              
59 28 50   28   236 sub _squelch_base_class { ref($_[0]) || $_[0] }
60              
61             # Create per-squelch-level subclasses of a given package
62             # This is an optimization for minimizing overhead when using disabled levels
63             sub _build_squelch_subclasses {
64 24     24   48 my $class= shift;
65 24         109 my %numeric_levels= ( map { $_ => 1 } -1, map { numeric_level($_) } Log::Any->logging_methods() );
  240         650  
  216         1417  
66 24         92 my %subclass;
67 24         105 foreach my $level_num (keys %numeric_levels) {
68 240         1482 my $package= $class.'::Squelch'.($level_num+1);
69 240     16   1161 $subclass{$package}{_squelch_base_class}= sub { $class };
  16         76  
70 240         740 foreach my $method (Log::Any->logging_methods(), 'fatal') {
71 2400 100       11185 if ($level_num < numeric_level($method)) {
72 1152     1   10224 $subclass{$package}{$method}= sub {};
73 1152     19   5269 $subclass{$package}{"is_$method"}= sub { 0 };
  19         185  
74             }
75             }
76             }
77 24     39   273 $subclass{"${class}::Lazy"}{_squelch_base_class}= sub { $class };
  39         183  
78 24         124 foreach my $method (Log::Any->logging_and_detection_methods(), 'fatal', 'is_fatal') {
79             # Trampoline code that lazily re-caches an adaptor the first time it is used
80             $subclass{"${class}::Lazy"}{$method}= sub {
81 39     39   18737 $_[0]->_cache_config;
82 39         327 goto $_[0]->can($method)
83 480         2217 };
84             }
85            
86             # Create subclasses and install methods
87 24         191 for my $pkg (keys %subclass) {
88 24     24   173 no strict 'refs';
  24         47  
  24         5258  
89 264         363 @{$pkg.'::ISA'}= ( $class );
  264         3700  
90 264         393 for my $method (keys %{ $subclass{$pkg} }) {
  264         1144  
91 3048         4083 *{$pkg.'::'.$method}= $subclass{$pkg}{$method};
  3048         16017  
92             }
93             }
94 24         13449 1;
95             }
96              
97             # The set of adapters which have been "squelch-cached"
98             # (i.e. blessed into a subclass)
99             our %_squelch_cached_adapters;
100              
101             BEGIN {
102 24     24   177 foreach my $method ( Log::Any->logging_methods() ) {
103 216     31   851 my $m= sub { my $self= shift; $self->{_writer}->($self, $method, @_); };
  31         14344  
  31         1010  
104 24     24   143 no strict 'refs';
  24         38  
  24         2134  
105 216         291 *{__PACKAGE__ . "::$method"}= $m;
  216         1429  
106 216     18   583 *{__PACKAGE__ . "::is_$method"}= sub { 1 };
  216         1226  
  18         708  
107             }
108 24         165 __PACKAGE__->_build_squelch_subclasses();
109             }
110              
111             # Cache the ->config settings into this adapter, which also
112             # re-blesses it based on the current log level.
113             sub _cache_config {
114 39     39   67 my $self= shift;
115 39         160 $self->{_writer}= $self->config->compiled_writer;
116 39         360 my $lev= $self->config->log_level_num;
117             # Backward compatibility with version 0.002
118 39 100       394 if (exists $self->{filter}) {
119 3         8 $lev= Log::Any::Adapter::Util::NOTICE - _coerce_filter_level($self->{filter});
120             }
121 39         118 bless $self, $self->_squelch_base_class.'::Squelch'.($lev+1);
122 39         171 $self->config->_register_cached_adapter($self);
123             }
124              
125             # Re-bless adapter back to its "Lazy" config cacher class
126             sub _uncache_config {
127 44     44   136 bless $_[0], $_[0]->_squelch_base_class . '::Lazy';
128             }
129              
130             #-------------------------------------------------------------------
131             # Backward compatibility with version 0.002. Do not use in new code.
132              
133             sub write_msg {
134 0     0 0 0 my ($self, $level, $message)= @_;
135             # Don't bother optimizing and caching
136 0         0 $self->config->compiled_writer->($self, $level, $message);
137             }
138              
139             sub _default_dumper {
140 1     1   6 require Data::Dumper;
141 1         2 my $val= shift;
142 1         2 local $@;
143 1         3 my $dump= eval { Data::Dumper->new([$val])->Indent(0)->Terse(1)->Useqq(1)->Quotekeys(0)->Maxdepth(4)->Sortkeys(1)->Dump };
  1         9  
144 1 50       129 if (!defined $dump) {
145 0         0 my $x= "$@";
146 0         0 $x =~ s/\n//;
147 0 0       0 substr($x, 50)= '...' if length $x >= 50;
148 0         0 $dump= "";
149             };
150 1         5 return $dump;
151             }
152              
153             sub _coerce_filter_level {
154 3     3   4 my $val= shift;
155 3         15 my %level_map= (
156             trace => -2,
157             debug => -1,
158             info => 0,
159             notice => 1,
160             warning => 2,
161             error => 3,
162             critical => 4,
163             fatal => 4,
164             );
165             return (!defined $val || $val eq 'none')? $level_map{trace}-1
166             : Scalar::Util::looks_like_number($val)? $val
167             : exists $level_map{$val}? $level_map{$val}
168 3 0 66     31 : ($val =~ /^debug-(\d+)$/)? $level_map{debug} - $1
    50          
    100          
    100          
169             : croak "unknown log level '$val'";
170             }
171              
172             1;
173              
174             __END__