File Coverage

blib/lib/Object/Remote/Logging/Logger.pm
Criterion Covered Total %
statement 70 75 93.3
branch 14 18 77.7
condition 2 3 66.6
subroutine 16 18 88.8
pod 0 1 0.0
total 102 115 88.7


line stmt bran cond sub pod time code
1             package Object::Remote::Logging::Logger;
2              
3 18     18   2865 use Moo;
  18         21  
  18         76  
4 18     18   4086 use Carp qw(croak);
  18         24  
  18         3047  
5              
6             #TODO sigh invoking a logger with a log level name the same
7             #as an attribute could happen - restrict attributes to _ prefix
8             #and restrict log levels to not start with out that prefix?
9             has format => ( is => 'ro', required => 1, default => sub { '%l: %s' } );
10             has level_names => ( is => 'ro', required => 1 );
11             has min_level => ( is => 'ro', required => 1, default => sub { 'info' } );
12             has max_level => ( is => 'lazy', required => 1 );
13             has _level_active => ( is => 'lazy' );
14              
15             #just a stub so it doesn't get to AUTOLOAD
16       18 0   sub BUILD { }
17       0     sub DESTROY { }
18              
19             sub AUTOLOAD {
20 8     8   11 my $self = shift;
21 8         55 (my $method) = (our $AUTOLOAD =~ /([^:]+)$/);
22              
23 18     18   79 no strict 'refs';
  18         21  
  18         12801  
24              
25 8 50       24 if ($method =~ m/^_/) {
26 0         0 croak "invalid method name $method for " . ref($self);
27             }
28              
29 8 100       25 if ($method =~ m/^is_(.+)/) {
30 4         10 my $level_name = $1;
31 4         12 my $is_method = "is_$level_name";
32 4     60   15 *{$is_method} = sub { shift(@_)->_level_active->{$level_name} };
  4         24  
  60         1031  
33 4         14 return $self->$is_method;
34             }
35              
36 4         17 my $level_name = $method;
37 4         26 *{$level_name} = sub {
38 60     60   53 my $self = shift;
39 60 50       1161 unless(exists($self->_level_active->{$level_name})) {
40 0         0 croak "$level_name is not a valid log level name";
41             }
42              
43 60         436 $self->_log($level_name, @_);
44 4         24 };
45              
46 4         24 return $self->$level_name(@_);
47             }
48              
49             sub _build_max_level {
50 18     18   1674 my ($self) = @_;
51 18         72 return $self->level_names->[-1];
52             }
53              
54             sub _build__level_active {
55 18     18   1213 my ($self) = @_;
56 18         19 my $should_log = 0;
57 18         38 my $min_level = $self->min_level;
58 18         282 my $max_level = $self->max_level;
59 18         28 my %active;
60              
61 18         19 foreach my $level (@{$self->level_names}) {
  18         38  
62 117 100       182 if($level eq $min_level) {
63 18         22 $should_log = 1;
64             }
65              
66 117         258 $active{$level} = $should_log;
67              
68 117 100 66     381 if (defined $max_level && $level eq $max_level) {
69 18         27 $should_log = 0;
70             }
71             }
72              
73 18         93 return \%active;
74             }
75              
76             sub _log {
77 60     60   332 my ($self, $level, $content, $metadata_in) = @_;
78 60         279 my %metadata = %$metadata_in;
79 60         141 my $rendered = $self->_render($level, \%metadata, @$content);
80 60         128 $self->_output($rendered);
81             }
82              
83             sub _create_format_lookup {
84 60     60   60 my ($self, $level, $metadata, $content) = @_;
85 60         68 my $method = $metadata->{method};
86              
87 60 100       93 $method = '(none)' unless defined $method;
88              
89             return {
90             '%' => '%', 'n' => "\n",
91             t => $self->_render_time($metadata->{timestamp}),
92             r => $self->_render_remote($metadata->{object_remote}),
93             s => $self->_render_log(@$content), l => $level,
94             c => $metadata->{exporter}, p => $metadata->{caller_package}, m => $method,
95             f => $metadata->{filename}, i => $metadata->{line},
96             h => $metadata->{hostname}, P => $metadata->{pid},
97 60         113 };
98             }
99              
100             sub _get_format_var_value {
101 64     64   99 my ($self, $name, $data) = @_;
102 64         71 my $val = $data->{$name};
103 64 50       275 return $val if defined $val;
104 0         0 return '(undefined)';
105             }
106              
107             sub _render_time {
108 60     60   54 my ($self, $time) = @_;
109 60         2944 return scalar(localtime($time));
110             }
111              
112             sub _render_remote {
113 60     60   64 my ($self, $remote) = @_;
114 60 100       197 return 'local' unless defined $remote;
115 2         3 my $conn_id = $remote->{connection_id};
116 2 50       4 $conn_id = '(uninit)' unless defined $conn_id;
117 2         8 return "remote #$conn_id";
118             }
119              
120             sub _render_log {
121 60     60   104 my ($self, @content) = @_;
122 60         471 return join('', @content);
123             }
124             sub _render {
125 60     60   77 my ($self, $level, $metadata, @content) = @_;
126 60         106 my $var_table = $self->_create_format_lookup($level, $metadata, [@content]);
127 60         128 my $template = $self->format;
128              
129 60         242 $template =~ s/%([\w%])/$self->_get_format_var_value($1, $var_table)/ge;
  64         150  
130              
131 60         74 chomp($template);
132 60         62 $template =~ s/\n/\n /g;
133 60         59 $template .= "\n";
134 60         200 return $template;
135             }
136              
137             sub _output {
138 0     0     my ($self, $content) = @_;
139 0           print STDERR $content;
140             }
141              
142             1;
143              
144             __END__