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   2481 use Moo;
  18         56  
  18         81  
4 18     18   4433 use Carp qw(croak);
  18         59  
  18         3419  
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   17 my $self = shift;
21 8         47 (my $method) = (our $AUTOLOAD =~ /([^:]+)$/);
22              
23 18     18   115 no strict 'refs';
  18         37  
  18         14408  
24              
25 8 50       24 if ($method =~ m/^_/) {
26 0         0 croak "invalid method name $method for " . ref($self);
27             }
28              
29 8 100       24 if ($method =~ m/^is_(.+)/) {
30 4         10 my $level_name = $1;
31 4         8 my $is_method = "is_$level_name";
32 4     60   14 *{$is_method} = sub { shift(@_)->_level_active->{$level_name} };
  4         34  
  60         911  
33 4         15 return $self->$is_method;
34             }
35              
36 4         8 my $level_name = $method;
37 4         20 *{$level_name} = sub {
38 60     60   101 my $self = shift;
39 60 50       1033 unless(exists($self->_level_active->{$level_name})) {
40 0         0 croak "$level_name is not a valid log level name";
41             }
42              
43 60         469 $self->_log($level_name, @_);
44 4         16 };
45              
46 4         18 return $self->$level_name(@_);
47             }
48              
49             sub _build_max_level {
50 18     18   612 my ($self) = @_;
51 18         85 return $self->level_names->[-1];
52             }
53              
54             sub _build__level_active {
55 18     18   167 my ($self) = @_;
56 18         35 my $should_log = 0;
57 18         41 my $min_level = $self->min_level;
58 18         251 my $max_level = $self->max_level;
59 18         37 my %active;
60              
61 18         21 foreach my $level (@{$self->level_names}) {
  18         35  
62 117 100       177 if($level eq $min_level) {
63 18         23 $should_log = 1;
64             }
65              
66 117         170 $active{$level} = $should_log;
67              
68 117 100 66     294 if (defined $max_level && $level eq $max_level) {
69 18         26 $should_log = 0;
70             }
71             }
72              
73 18         85 return \%active;
74             }
75              
76             sub _log {
77 60     60   387 my ($self, $level, $content, $metadata_in) = @_;
78 60         328 my %metadata = %$metadata_in;
79 60         161 my $rendered = $self->_render($level, \%metadata, @$content);
80 60         164 $self->_output($rendered);
81             }
82              
83             sub _create_format_lookup {
84 60     60   89 my ($self, $level, $metadata, $content) = @_;
85 60         89 my $method = $metadata->{method};
86              
87 60 100       109 $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         105 };
98             }
99              
100             sub _get_format_var_value {
101 64     64   183 my ($self, $name, $data) = @_;
102 64         115 my $val = $data->{$name};
103 64 50       213 return $val if defined $val;
104 0         0 return '(undefined)';
105             }
106              
107             sub _render_time {
108 60     60   97 my ($self, $time) = @_;
109 60         1480 return scalar(localtime($time));
110             }
111              
112             sub _render_remote {
113 60     60   154 my ($self, $remote) = @_;
114 60 100       182 return 'local' unless defined $remote;
115 2         3 my $conn_id = $remote->{connection_id};
116 2 50       16 $conn_id = '(uninit)' unless defined $conn_id;
117 2         7 return "remote #$conn_id";
118             }
119              
120             sub _render_log {
121 60     60   124 my ($self, @content) = @_;
122 60         515 return join('', @content);
123             }
124             sub _render {
125 60     60   116 my ($self, $level, $metadata, @content) = @_;
126 60         135 my $var_table = $self->_create_format_lookup($level, $metadata, [@content]);
127 60         176 my $template = $self->format;
128              
129 60         290 $template =~ s/%([\w%])/$self->_get_format_var_value($1, $var_table)/ge;
  64         115  
130              
131 60         101 chomp($template);
132 60         92 $template =~ s/\n/\n /g;
133 60         87 $template .= "\n";
134 60         203 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__