File Coverage

blib/lib/Log/Handler/Output.pm
Criterion Covered Total %
statement 60 96 62.5
branch 19 40 47.5
condition 8 13 61.5
subroutine 8 12 66.6
pod 5 5 100.0
total 100 166 60.2


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Log::Handler::Output - The output builder class.
4              
5             =head1 DESCRIPTION
6              
7             Just for internal usage!
8              
9             =head1 METHODS
10              
11             =head2 new()
12              
13             =head2 log()
14              
15             =head2 reload()
16              
17             =head2 flush()
18              
19             =head2 errstr()
20              
21             =head1 PREREQUISITES
22              
23             Carp
24             UNIVERSAL
25              
26             =head1 AUTHOR
27              
28             Jonny Schulz .
29              
30             =head1 COPYRIGHT
31              
32             Copyright (C) 2007-2009 by Jonny Schulz. All rights reserved.
33              
34             This program is free software; you can redistribute it and/or
35             modify it under the same terms as Perl itself.
36              
37             =cut
38              
39             package Log::Handler::Output;
40              
41 15     15   108 use strict;
  15         56  
  15         466  
42 15     15   84 use warnings;
  15         37  
  15         386  
43 15     15   81 use Carp;
  15         25  
  15         775  
44 15     15   8286 use UNIVERSAL;
  15         203  
  15         72  
45              
46             our $VERSION = "0.10";
47             our $ERRSTR = "";
48              
49             sub new {
50 32     32 1 104 my ($class, $options, $output) = @_;
51 32         81 my $self = bless $options, $class;
52 32         106 $self->{output} = $output;
53 32         91 return $self;
54             }
55              
56             sub log {
57 79     79 1 145 my $self = shift;
58 79         123 my $level = shift;
59 79         136 my $output = $self->{output};
60 79         149 my $message = { };
61 79         351 my $wanted = { message => join(" ", grep defined, @_) };
62              
63             # The patterns must be generated for each output. The reason
64             # is that each output can have their own time/date format
65             # and the code which is executed can return another value.
66 79         129 foreach my $r (@{$self->{wanted_pattern}}) {
  79         175  
67 134         266 $wanted->{$r->{name}} = &{$r->{code}}($self, $level);
  134         366  
68             }
69              
70 79 100       245 if ($self->{message_pattern}) {
71 2         5 &{$self->{message_pattern_code}}($wanted, $message);
  2         56  
72             }
73              
74 79 100       181 if ($self->{message_layout}) {
75 78         109 &{$self->{message_layout_code}}($wanted, $message);
  78         1964  
76             } else {
77 1         4 $message->{message} = $wanted->{message};
78             }
79              
80 79 100       249 if ($self->{message_pattern}) {
81 2 50       14 if ($message->{message}) {
82 2         7 $wanted->{message} = $message->{message};
83             }
84 2         4 &{$self->{message_pattern_code}}($wanted, $message);
  2         46  
85             }
86              
87 79 50 33     341 if ($self->{debug_trace} || $Log::Handler::TRACE) {
88 0         0 $self->_add_trace($message);
89             }
90              
91 79 50 33     219 if ($self->{skip_message} && $message->{message} =~ /$self->{skip_message}/) {
92 0         0 return 1;
93             }
94              
95 79 100       173 if ($self->{filter_message}) {
96 24 100       52 $self->_filter_msg($message) or return 1;
97             }
98              
99 59 50       131 if ($self->{prepare_message}) {
100 0         0 eval { &{$self->{prepare_message}}($message) };
  0         0  
  0         0  
101 0 0       0 if ($@) {
102 0         0 return $self->_raise_error("prepare_message failed - $@");
103             }
104             }
105              
106 59 100 66     329 if ($self->{newline} && $message->{message} !~ /(?:\015|\012)\z/) {
107 58         152 $message->{message} .= "\n";
108             }
109              
110             # The substr solution to determine if a newline exists
111             # at the end of the message is ~60% faster than the regex.
112             # Maybe it will be released in the future.
113             #if ($self->{newline}) {
114             # my $last = substr $message->{message}, -1, 1;
115             # if ($last eq "\015" || $last eq "\012" || $last eq "\015\012" || $last eq "\012\015") {
116             # $message->{message} .= "\n";
117             # }
118             #}
119              
120 59 50       204 $output->log($message)
121             or return $self->_raise_error($output->errstr);
122              
123 59         275 return 1;
124             }
125              
126             sub flush {
127 0     0 1 0 my $self = shift;
128 0         0 my $output = $self->{output};
129              
130 0 0       0 if ( UNIVERSAL::can($output, "flush") ) {
131 0 0       0 $output->flush
132             or return $self->_raise_error($output->errstr);
133             }
134              
135 0         0 return 1;
136             }
137              
138             sub reload {
139 3     3 1 9 my ($self, $opts) = @_;
140              
141 3         16 foreach my $key (keys %$opts) {
142 51         118 $self->{$key} = $opts->{$key};
143             }
144             }
145              
146             sub errstr {
147 0     0 1 0 return $ERRSTR;
148             }
149              
150             #
151             # private stuff
152             #
153              
154             sub _add_trace {
155 0     0   0 my ($self, $message) = @_;
156 0         0 my @caller = ();
157 0         0 my $skip = $self->{debug_skip};
158              
159 0 0       0 if ( $message->{message} =~ /.\z/ ) {
160 0         0 $message->{message} .= "\n";
161             }
162              
163 0         0 for (my $i=0; my @c = caller($i); $i++) {
164 0         0 my %frame;
165 0         0 @frame{qw/package filename line subroutine hasargs wantarray evaltext is_require/} = @c[0..7];
166 0         0 push @caller, \%frame;
167             }
168              
169 0         0 foreach my $i (reverse $skip..$#caller) {
170 0         0 $message->{message} .= " " x 3 . "CALL($i):";
171 0         0 my $frame = $caller[$i];
172 0         0 foreach my $key (qw/package filename line subroutine hasargs wantarray evaltext is_require/) {
173 0 0       0 next unless defined $frame->{$key};
174 0 0       0 if ($self->{debug_mode} == 1) { # line mode
    0          
175 0         0 $message->{message} .= " $key($frame->{$key})";
176             } elsif ($self->{debug_mode} == 2) { # block mode
177 0         0 $message->{message} .= "\n" . " " x 6 . sprintf("%-12s", $key) . $frame->{$key};
178             }
179             }
180 0         0 $message->{message} .= "\n";
181             }
182             }
183              
184             sub _filter_msg {
185 24     24   42 my ($self, $message) = @_;
186 24         34 my $filter = $self->{filter_message};
187 24         36 my $result = $filter->{result};
188 24         35 my $code = $filter->{code};
189 24         34 my $return = ();
190              
191 24 100       47 if (!$filter->{condition}) {
192 16   100     36 $return = &$code($message) || 0;
193             } else {
194 8         25 foreach my $match ( keys %$result ) {
195             $result->{$match} =
196 24   100     131 $message->{message} =~ /$filter->{$match}/ || 0;
197             }
198 8         156 $return = &$code($result);
199             }
200              
201 24         161 return $return;
202             }
203              
204             sub _raise_error {
205 0     0     my $self = shift;
206 0           $ERRSTR = shift;
207 0 0         return undef unless $self->{die_on_errors};
208 0           my $class = ref($self);
209 0           Carp::croak "$class: $ERRSTR";
210             }
211              
212             1;