File Coverage

blib/lib/Log/Contextual/WarnLogger.pm
Criterion Covered Total %
statement 62 62 100.0
branch 23 26 88.4
condition 10 11 90.9
subroutine 12 12 100.0
pod 1 1 100.0
total 108 112 96.4


line stmt bran cond sub pod time code
1             package Log::Contextual::WarnLogger;
2 4     12   187349 use strict;
  4         8  
  4         148  
3 4     12   19 use warnings;
  4         7  
  4         268  
4              
5             our $VERSION = '0.009001';
6              
7 4     4   21 use Carp 'croak';
  4         7  
  4         522  
8              
9             my @default_levels = qw( trace debug info warn error fatal );
10              
11             # generate subs to handle the default levels
12             # anything else will have to be handled by AUTOLOAD at runtime
13             {
14             for my $level (@default_levels) {
15              
16 4     4   71 no strict 'refs';
  4         10  
  4         1506  
17              
18             my $is_name = "is_$level";
19             *{$level} = sub {
20 15     15   33 my $self = shift;
21              
22 15 50       51 $self->_log($level, @_)
23             if $self->$is_name;
24             };
25              
26             *{$is_name} = sub {
27 82     82   1073 my $self = shift;
28 82 100       401 return 1 if $ENV{$self->{env_prefix} . '_' . uc $level};
29 66         177 my $upto = $ENV{$self->{env_prefix} . '_UPTO'};
30 66 100       216 return unless $upto;
31 32         63 $upto = lc $upto;
32              
33 32         196 return $self->{level_num}{$level} >= $self->{level_num}{$upto};
34             };
35             }
36             }
37              
38             our $AUTOLOAD;
39              
40             sub AUTOLOAD {
41 9     9   5814 my $self = $_[0];
42              
43 9         59 (my $name = our $AUTOLOAD) =~ s/.*:://;
44 9 100       260 return if $name eq 'DESTROY';
45              
46             # extract the log level from the sub name
47 4         20 my ($is, $level) = $name =~ m/^(is_)?(.+)$/;
48 4         8 my $is_name = "is_$level";
49              
50 4     4   29 no strict 'refs';
  4         27  
  4         2501  
51 4         21 *{$level} = sub {
52 3     3   1190 my $self = shift;
53              
54 3 50       9 $self->_log($level, @_)
55             if $self->$is_name;
56 4         13 };
57              
58 4         8 *{$is_name} = sub {
59 20     20   1105 my $self = shift;
60              
61 20         58 my $prefix_field = $self->{env_prefix} . '_' . uc $level;
62 20 100       59 return 1 if $ENV{$prefix_field};
63              
64             # don't log if the variable specifically says not to
65 18 100 66     53 return 0 if defined $ENV{$prefix_field} and not $ENV{$prefix_field};
66              
67 16         25 my $upto_field = $self->{env_prefix} . '_UPTO';
68 16         22 my $upto = $ENV{$upto_field};
69              
70 16 100       33 if ($upto) {
71 6         15 $upto = lc $upto;
72              
73             croak "Unrecognized log level '$upto' in \$ENV{$upto_field}"
74 6 100       219 if not defined $self->{level_num}{$upto};
75              
76 4         20 return $self->{level_num}{$level} >= $self->{level_num}{$upto};
77             }
78              
79             # if we don't recognize this level and nothing says otherwise, log!
80 10 100       40 return 1 if not $self->{custom_levels};
81 4         12 };
82 4         17 goto &$AUTOLOAD;
83             }
84              
85             sub new {
86 11     11 1 629330 my ($class, $args) = @_;
87              
88 11         26 my $levels = $args->{levels};
89 11 100 100     314 croak 'invalid levels specification: must be non-empty arrayref'
      100        
90             if defined $levels and (ref $levels ne 'ARRAY' or !@$levels);
91              
92 9         17 my $custom_levels = defined $levels;
93 9   100     64 $levels ||= [@default_levels];
94              
95 9         14 my %level_num;
96 9         17 @level_num{@$levels} = (0 .. $#{$levels});
  9         59  
97              
98 9         64 my $self = bless {
99             levels => $levels,
100             level_num => \%level_num,
101             custom_levels => $custom_levels,
102             }, $class;
103              
104             $self->{env_prefix} = $args->{env_prefix}
105 9 50       64 or die 'no env_prefix passed to Log::Contextual::WarnLogger->new';
106 9         39 return $self;
107             }
108              
109             sub _log {
110 15     15   27 my $self = shift;
111 15         28 my $level = shift;
112 15         44 my $message = join("\n", @_);
113 15 100       68 $message .= "\n" unless $message =~ /\n$/;
114 15         155 warn "[$level] $message";
115             }
116              
117             1;
118              
119             __END__