File Coverage

blib/lib/Log/Agent/Logger.pm
Criterion Covered Total %
statement 129 163 79.1
branch 39 68 57.3
condition 4 9 44.4
subroutine 17 25 68.0
pod 11 12 91.6
total 200 277 72.2


line stmt bran cond sub pod time code
1             #
2             # $Id: Logger.pm,v 0.1.1.1 2001/04/11 16:13:53 ram Exp $
3             #
4             # Copyright (c) 2000, Raphael Manfredi
5             #
6             # You may redistribute only under the terms of the Artistic License,
7             # as specified in the README file that comes with the distribution.
8             #
9             # HISTORY
10             # $Log: Logger.pm,v $
11             # Revision 0.1.1.1 2001/04/11 16:13:53 ram
12             # patch1: now relies on Getargs::Long for argument parsing
13             # patch1: new -caller argument to customize caller tracing
14             # patch1: new -priority argument to customize priority tracing
15             # patch1: new -tags argument to add user-defined tags in the logs
16             # patch1: updated version number
17             #
18             # Revision 0.1 2000/11/06 20:14:13 ram
19             # Baseline for first Alpha release.
20             #
21             # $EndLog$
22             #
23              
24 4     4   37960 use strict;
  4         10  
  4         172  
25              
26             ########################################################################
27             package Log::Agent::Logger;
28              
29 4     4   22 use vars qw($VERSION);
  4         7  
  4         200  
30              
31             $VERSION = '0.101';
32              
33 4     4   3386 use Log::Agent;
  4         43464  
  4         449  
34 4     4   27 use Log::Agent::Formatting qw(tag_format_args);
  4         7  
  4         157  
35 4     4   19 use Log::Agent::Priorities qw(:LEVELS level_from_prio prio_from_level);
  4         8  
  4         664  
36 4     4   3845 use Getargs::Long qw(ignorecase);
  4         43589  
  4         28  
37              
38             BEGIN {
39 4     4   12208 no strict 'refs';
  4         11  
  4         531  
40 4     4   11 my %fn;
41 4 50       60 %fn = (
42             'emerg' => q/['emerg', EMERG]/,
43             'emergency' => q/['emerg', EMERG]/,
44             'alert' => q/['alert', ALERT]/,
45             'crit' => q/['crit', CRIT]/,
46             'critical' => q/['crit', CRIT]/,
47             'err' => q/['err', ERROR]/,
48             'error' => q/['err', ERROR]/,
49             'warning', => q/['warning', WARN]/,
50             'warn', => q/['warning', WARN]/,
51             'notice' => q/['notice', NOTICE]/,
52             'info' => q/['info', INFO]/,
53             'debug' => q/['debug', DEBUG]/,
54             ) unless defined &emergency;
55 4         21 for my $sub (keys %fn) {
56 48         82 my $prilvl = $fn{$sub};
57 48 100   2   5508 *$sub = eval qq{
  2 100       62  
  2 50       11  
  1 0       5  
  1 50       5  
  2 50       7  
  6 50       1033  
  6 50       20  
  3 50       14  
  3 50       15  
  6 0       20  
  1 0       34  
  1         6  
  0         0  
  1         6  
  1         5  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  1         33  
  1         6  
  0         0  
  1         6  
  1         4  
  3         73  
  3         38  
  0         0  
  3         19  
  3         12  
  1         30  
  1         5  
  0         0  
  1         7  
  1         4  
  2         72  
  2         9  
  0         0  
  2         14  
  2         9  
  4         108  
  4         12  
  0         0  
  4         18  
  4         13  
  3         66  
  3         7  
  0         0  
  3         11  
  3         9  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
58             sub {
59             my \$self = shift;
60             if (ref \$_[0] eq 'CODE') {
61             \$self->_log_fn($prilvl, \\\@_);
62             } else {
63             \$self->_log($prilvl, \\\@_);
64             }
65             return;
66             }
67             };
68             }
69             }
70              
71             #
72             # ->make
73             #
74             # Creation routine.
75             #
76             # Attributes (and switches that set them):
77             #
78             # -channel logging channel
79             # -max_prio maximum priority logged (included)
80             # -min_prio minimum priority logged (included)
81             # -caller customizes the caller information to be inserted
82             # -priority customizes the priority information to be inserted
83             # -tags list of user-defined tags to add to messages
84             #
85             sub make {
86 4     4 0 5490 my $self = bless {}, shift;
87 4         10 my ($caller, $priority, $tags);
88              
89             (
90 4         48 $self->{channel}, $self->{max_prio}, $self->{min_prio},
91             $caller, $priority, $tags
92             ) = xgetargs(@_,
93             -channel => 'Log::Agent::Channel',
94             -max_prio => ['s', DEBUG],
95             -min_prio => ['s', EMERG],
96             -caller => ['ARRAY'],
97             -priority => ['ARRAY'],
98             -tags => ['ARRAY'],
99             );
100              
101             #
102             # Always use numeric priorities internally
103             #
104              
105 4 50       2732 $self->{max_prio} = level_from_prio($self->{max_prio})
106             if $self->{max_prio} =~ /^\D+$/;
107              
108 4 50       57 $self->{min_prio} = level_from_prio($self->{min_prio})
109             if $self->{min_prio} =~ /^\D+$/;
110              
111 4 100       17 $self->set_priority_info(@$priority) if defined $priority;
112 4 100       14 $self->set_caller_info(@$caller) if defined $caller;
113              
114             #
115             # Handle -tags => [ ]
116             #
117              
118 4 100       15 if (defined $tags) {
119 1         1 my $type = "Log::Agent::Tag";
120 1 50 33     4 if (grep { !ref $_ || !$_->isa($type) } @$tags) {
  1         20  
121 0         0 require Carp;
122 0         0 Carp::croak("Argument -tags must supply list of $type objects");
123             }
124 1 50       4 if (@$tags) {
125 1         933 require Log::Agent::Tag_List;
126 1         2922 $self->{tags} = Log::Agent::Tag_List->make(@$tags);
127             }
128             }
129              
130 4         32 return $self;
131             }
132              
133             #
134             # Attribute access
135             #
136              
137 0     0 1 0 sub channel { $_[0]->{channel} }
138 0     0 1 0 sub max_prio { $_[0]->{max_prio} }
139 0     0 1 0 sub min_prio { $_[0]->{min_prio} }
140 1 50   1 1 13 sub tags { $_[0]->{tags} || $_[0]->_init_tags }
141              
142 0     0 1 0 sub max_prio_str { prio_from_level $_[0]->{max_prio} }
143 0     0 1 0 sub min_prio_str { prio_from_level $_[0]->{min_prio} }
144              
145             sub set_max_prio
146 0 0   0 1 0 { $_[0]->{max_prio} = $_[1] =~ /^\D+$/ ? level_from_prio($_[1]) : $_[1] }
147             sub set_min_prio
148 0 0   0 1 0 { $_[0]->{min_prio} = $_[1] =~ /^\D+$/ ? level_from_prio($_[1]) : $_[1] }
149              
150             #
151             # ->close
152             #
153             # Close underlying channel, and detach from it.
154             #
155             sub close {
156 3     3 1 287 my $self = shift;
157 3         7 my $channel = $self->{channel};
158 3 50       11 return unless defined $channel; # Already closed
159 3         5 $self->{channel} = undef;
160 3         15 $channel->close;
161             }
162              
163             #
164             # ->set_caller_info
165             #
166             # Change settings of caller tag information.
167             # Giving an empty list removes caller tagging.
168             #
169             sub set_caller_info {
170 3     3 1 10 my $self = shift;
171              
172 3 100       8 unless (@_) {
173 1         4 delete $self->{caller};
174 1         3 return;
175             }
176              
177 2         978 require Log::Agent::Tag::Caller;
178 2         1972 $self->{caller} = Log::Agent::Tag::Caller->make(-offset => 4, @_);
179 2         115 return;
180             }
181              
182             #
183             # ->set_priority_info
184             #
185             # Change settings of caller tag information.
186             # Giving an empty list removes priority tagging.
187             #
188             sub set_priority_info {
189 3     3 1 7 my $self = shift;
190 3         6 my @info = @_;
191              
192 3 100       8 unless (@info) {
193 1         2 delete $self->{priority};
194 1         3 return;
195             }
196              
197 2         3 $self->{priority} = \@info; # For objects created in _prio_tag()
198              
199             #
200             # When settings are changes, we need to clear the cache of priority
201             # tags generated by _prio_tag().
202             #
203              
204 2         4 $self->{prio_cache} = {}; # Internal for ->_prio_tag()
205 2         13 return;
206             }
207              
208              
209             #
210             # ->_log
211             #
212             # Emit log at given priority, if within priority bounds.
213             #
214             sub _log {
215 19     19   60 my ($self, $prilvl) = splice(@_, 0, 2);
216 19         62 my $channel = $self->{channel};
217 19 100       98 return unless defined $channel; # Closed
218              
219             #
220             # Prune call if we're not within bounds.
221             # $prilvl is seomthing like ["error", ERROR].
222             #
223              
224 18         25 my $lvl = $prilvl->[1];
225 18 100 66     131 return if $lvl > $self->{max_prio} || $lvl < $self->{min_prio};
226              
227             #
228             # Issue logging.
229             #
230              
231 17 100       41 my $priority = $self->_prio_tag(@$prilvl) if defined $self->{priority};
232              
233 17         93 $channel->write($prilvl->[0],
234             tag_format_args($self->{caller}, $priority, $self->{tags}, @_));
235              
236 17         14744 return;
237             }
238              
239             #
240             # ->_log_fn
241             #
242             # Emit log at given priority, if within priority bounds.
243             # The logged string needs to be computed by calling back a routine.
244             #
245             sub _log_fn {
246 4     4   11 my ($self, $prilvl) = splice(@_, 0, 2);
247 4         8 my $channel = $self->{channel};
248 4 50       12 return unless defined $channel; # Closed
249              
250             #
251             # Prune call if we're not within bounds.
252             # $prilvl is seomthing like ["error", ERROR].
253             #
254              
255 4         6 my $lvl = $prilvl->[1];
256 4 50 33     28 return if $lvl > $self->{max_prio} || $lvl < $self->{min_prio};
257              
258             #
259             # Issue logging.
260             #
261              
262 4         5 my $fn = shift @{$_[0]};
  4         8  
263 4         7 my $msg = &$fn(@{$_[0]});
  4         12  
264 4 50       27 return unless length $msg; # Null messsage, don't log
265              
266 4 50       13 my $priority = $self->_prio_tag(@$prilvl) if defined $self->{priority};
267              
268 4         27 $channel->write($prilvl->[0],
269             tag_format_args($self->{caller}, $priority, $self->{tags}, [$msg]));
270              
271 4         746 return;
272             }
273              
274             #
275             # _prio_tag
276             #
277             # Returns Log::Agent::Tag::Priority message that is suitable for tagging
278             # at this priority/level, if configured to log priorities.
279             #
280             # Objects are cached into `prio_cache'.
281             #
282             sub _prio_tag {
283 4     4   5 my $self = shift;
284 4         6 my ($prio, $level) = @_;
285 4         8 my $ptag = $self->{prio_cache}->{$prio, $level};
286 4 50       7 return $ptag if defined $ptag;
287              
288 4         911 require Log::Agent::Tag::Priority;
289              
290             #
291             # Common attributes (formatting, postfixing, etc...) are held in
292             # the `priorities' attribute. We add the priority/level here.
293             #
294              
295 4         22 $ptag = Log::Agent::Tag::Priority->make(
296             -priority => $prio,
297             -level => $level,
298 4         2511 @{$self->{priority}}
299             );
300              
301 4         844 return $self->{prio_cache}->{$prio, $level} = $ptag;
302             }
303              
304             #
305             # ->_init_tags
306             #
307             # Initialize the `tags' attribute the first time it is requested
308             # Returns its value.
309             #
310             sub _init_tags {
311 0     0     my $self = shift;
312 0           require Log::Agent::Tag_List;
313 0           return $self->{tags} = Log::Agent::Tag_List->make();
314             }
315              
316             1; # for require
317             __END__