added in file, line, and method info for log invocation
[scpubgit/Object-Remote.git] / lib / Object / Remote / Logging / Logger.pm
1 package Object::Remote::Logging::Logger;
2
3 use Moo;
4 use Scalar::Util qw(weaken);
5
6 has format => ( is => 'ro', required => 1, default => sub { '[%l %r] %f:%i %p::%m %s' } );
7 has level_names => ( is => 'ro', required => 1 );
8 has min_level => ( is => 'ro', required => 1 );
9 has max_level => ( is => 'ro' );
10 has _level_active => ( is => 'lazy' );
11
12 sub BUILD {
13   my ($self) = @_;
14   our $METHODS_INSTALLED; 
15   $self->_install_methods unless $METHODS_INSTALLED;
16 }
17
18 sub _build__level_active {
19   my ($self) = @_; 
20   my $should_log = 0;
21   my $min_level = $self->min_level;
22   my $max_level = $self->max_level;
23   my %active;
24     
25   foreach my $level (@{$self->level_names}) {
26     if($level eq $min_level) {
27       $should_log = 1; 
28     }
29
30     $active{$level} = $should_log;
31         
32     if (defined $max_level && $level eq $max_level) {
33       $should_log = 0;
34     }
35   }
36
37   return \%active;
38 }
39
40 sub _install_methods {
41   my ($self) = @_;
42   my $should_log = 0;
43   our $METHODS_INSTALLED = 1;
44
45   no strict 'refs';
46
47   foreach my $level (@{$self->level_names}) {
48     *{"is_$level"} = sub { shift(@_)->_level_active->{$level} };
49     *{$level} = sub { shift(@_)->_log($level, @_) };
50   }
51 }
52
53 sub _log {
54   my ($self, $level, $content, $metadata_in) = @_;
55   my %metadata = %$metadata_in;
56   my $rendered = $self->_render($level, \%metadata, @$content);
57   $self->_output($rendered);
58 }
59
60 sub _create_format_lookup {
61   my ($self, $level, $metadata, $content) = @_;
62   return { 
63     '%' => '%', t => $self->_render_time($metadata->{timestamp}),
64     r => $self->_render_remote($metadata->{object_remote}),
65     s => $self->_render_log(@$content), l => $level, 
66     p => $metadata->{package}, m => $metadata->{method},
67     f => $metadata->{filename}, i => $metadata->{line},
68     
69   };
70 }
71
72 sub _get_format_var_value {
73   my ($self, $name, $data) = @_;
74   my $val = $data->{$name};
75   return $val if defined $val;
76   return '';
77 }
78
79 sub _render_time {
80   my ($self, $time) = @_;
81   return scalar(localtime($time));
82 }
83
84 sub _render_remote {
85   my ($self, $remote) = @_;
86   return 'local' if ! defined $remote || ! defined $remote->{connection_id};
87   return 'remote #' . $remote->{connection_id};
88 }
89
90 sub _render_log {
91   my ($self, @content) = @_;
92   return join('', @content);
93 }
94 sub _render {
95   my ($self, $level, $metadata, @content) = @_;
96   my $var_table = $self->_create_format_lookup($level, $metadata, [@content]);
97   my $template = $self->format;
98   
99   $template =~ s/%([\w])/$self->_get_format_var_value($1, $var_table)/ge;
100   
101   chomp($template);
102   $template =~ s/\n/\n /g;
103   $template .= "\n";
104   return $template;
105 }
106
107 sub _output {
108   my ($self, $content) = @_;
109   print STDERR $content;
110 }
111
112
113 1;
114