File Coverage

blib/lib/Log/AndError.pm
Criterion Covered Total %
statement 79 90 87.7
branch 26 36 72.2
condition 7 12 58.3
subroutine 13 15 86.6
pod 9 10 90.0
total 134 163 82.2


line stmt bran cond sub pod time code
1             package Log::AndError;
2             #require 5.6.0;
3             require 5.005;
4             $Log::AndError::VERSION = 1.01;
5 1     1   988 use strict;
  1         1  
  1         37  
6             #use warnings;
7 1     1   451 use Log::AndError::Constants qw(:all);
  1         3  
  1         1269  
8            
9            
10             ##############################################################################
11             ## Variables
12             ##############################################################################
13            
14             my %Deflt = (
15             'LOG_LOGGER' => \&_log,
16             'LOG_SERVICE_NAME' => 'GENERIC',
17             'LOG_DEBUG_LEVEL' => DEBUG1,
18             'LOG_INFO_LEVEL' => INFO,
19             'LOG_ALWAYSLOG_LEVEL' => ALWAYSLOG,
20             'LOG_ERROR_CODE' => undef,
21             'LOG_ERROR_MSG' => undef,
22             'LOG_TEMPLATE' => "%s: LEVEL[%d]: %s",
23             );
24            
25             ##############################################################################
26             ## Documentation
27             ##############################################################################
28             =pod
29            
30             =head1 NAME
31            
32             Log::AndError - Logging module for ISA inclusion in other modules or as a standalone module.
33            
34             =head1 SYNOPSIS
35            
36             use Log::AndError;
37             @ISA = qw(Log::AndError);
38             Remember to set values with the provided methods
39             or
40             use Log::AndError;
41             use Log::AndError::Constants qw(:all);
42             my $ref_logger = Log::AndError->new(
43             'LOG_LOGGER' => \&log_sub,
44             'LOG_SERVICE_NAME' => 'GENERIC', # Use this to seperate log entries from different modules in your app.
45             'LOG_DEBUG_LEVEL' => DEBUG1, # See Log::AndError::Constants for example
46             'LOG_INFO_LEVEL' => INFO, # See Log::AndError::Constants for example
47             'LOG_ALWAYSLOG_LEVEL' => ALWAYSLOG, # See Log::AndError::Constants for example
48             );
49            
50             $self->logger(DEBUG3, 'my_sub('.join(',',@_).')');
51             # for instance logs the entry into a subroutine.
52             $self->logger(ALWAYSLOG, 'Something is wrong');
53             # logs an error when it is always wanted
54            
55             After you do this:
56             $self->error($error_code, $error_msg);
57             Your Caller does this:
58             my($err,$msg) = $obj_ref->error();
59             to retrieve the errors.
60            
61             =head1 DESCRIPTION
62            
63             This is a generic log and error class for Perl modules. There are two distinct pieces here. The error functions and the logging. The error functions are most convenient when inherited by your package although this is not needed. They are mostly here for convenience and to promote "good" behavior. The logging functions are the more complex piece and is the bulk of the code.
64            
65             To use the logging function pass in a reference to an anonymous sub routine that directs the error output to where you want it to go. There are a few sample subs located under this class. The default outputs to STDERR via C.
66            
67             The DEBUG constants are always >=0 and the ALWAYSLOG and INFO type constants always need to be <= -2 (-1 == undef on most systems). See Log::AndError::Constants for an example.
68            
69             Examples forthcoming at some point.
70            
71             Hey, it beats overwriting %SIG{__WARN__} with an anonymous sub for error string grabbing.
72            
73             =head1 METHODS
74            
75             =cut
76            
77             DESTROY {
78 0     0   0 my $self = shift;
79            
80             }
81            
82             # NO EXPORTS NEEDED
83             # We're a good little module.
84             #@Log::AndError::ISA = qw(Log::AndError::Constants);
85             ##############################################################################
86             ## constructor
87             ##############################################################################
88             # Generally ISA Dependant
89             sub new {
90 1     1 0 470 my $proto = shift;
91 1   33     9 my $class = ref($proto) || $proto;
92 1         3 my $self = {};
93 1         3 bless($self, $class);
94            
95             # This loads $self up with all of the default options.
96 1         6 foreach my $nomen (keys(%Deflt)){
97 8         21 $self->{$nomen} = $Deflt{$nomen};
98             }
99             # This overwrites any default values in $self with stuff passed in.
100 1         13 my %Cfg = @_;
101 1         4 @{$self}{keys(%Cfg)} = values(%Cfg);
  1         4  
102 1         35 return $self;
103             }
104            
105            
106             ##############################################################################
107             # Application subroutines
108             ##############################################################################
109             ##############################################################################
110             sub service_name {
111             =pod
112            
113             =head2 service_name()
114            
115             C
116            
117             =over 2
118            
119             =item Usage:
120            
121             $service_name = $obj_ref->service_name(); #From Caller's Perspective
122             or
123             $self->service_name('GENERIC');
124            
125             =item Purpose:
126            
127             Gets or sets the currently used service name. The default is in the POD above and can be retrieved at runtime from the return value.
128            
129             =item Returns:
130            
131             ($service_name) if set.
132            
133             =back
134            
135             =cut
136 1     1 1 2 my $self = shift;
137             ####$self->logger(DEBUG3, 'service_name('.join(',',@_).')'); # DO NOT DO THIS!
138 1         3 my $key = 'LOG_SERVICE_NAME';
139 1 50       4 if(!exists($self->{$key})){
140 0         0 $self->{$key} = $Deflt{$key};
141             }
142 1 50       5 if(@_){
143 0         0 $self->{$key} = $_[0];
144             }
145            
146 1         14 return($self->{$key});
147             }
148            
149             ##############################################################################
150             sub debug_level {
151             =pod
152            
153             =head2 debug_level()
154            
155             C
156            
157             =over 2
158            
159             =item Usage:
160            
161             $debug = $obj_ref->debug_level(); #From Caller's Perspective
162             or
163             $self->debug_level(1);
164            
165             =item Purpose:
166            
167             Sets or gets the debug level. Should be >= 0. If you decide against that then make sure you know what you are doing and info/alwayslog do not interfere. The default is in the POD above and can be retrieved at runtime from the return value.
168            
169             =item Returns:
170            
171             ($debug_level) if set.
172            
173             =back
174            
175             =cut
176 4     4 1 170 my $self = shift;
177             ####$self->logger(DEBUG3, 'debug_level('.join(',',@_).')'); # DO NOT DO THIS!
178 4         5 my $key = 'LOG_DEBUG_LEVEL';
179 4 50       12 if(!exists($self->{$key})){
180 0         0 $self->{$key} = $Deflt{$key};
181             }
182 4 100       9 if(@_){
183 1         3 $self->{$key} = $_[0];
184             }
185            
186 4         21 return($self->{$key});
187             }
188            
189            
190             ##############################################################################
191             sub info_level {
192             =pod
193            
194             =head2 info_level()
195            
196             C
197            
198             =over 2
199            
200             =item Usage:
201            
202             $info_level = $obj_ref->info_level(); #From Caller's Perspective
203             or
204             $self->info_level(INFO); # -2 from Log::AndError::Constants
205            
206             =item Purpose:
207            
208             Sets or gets the info debug level. Should be <= -2. If you decide against that then make sure you know what you are doing and info/alwayslog do not interfere. The default is in the POD above and can be retrieved at runtime from the return value.
209            
210             =item Returns:
211            
212             ($info_level) if set.
213            
214             =back
215            
216             =cut
217 3     3 1 151 my $self = shift;
218             ####$self->logger(DEBUG3, 'info_level('.join(',',@_).')'); # DO NOT DO THIS!
219 3         3 my $key = 'LOG_INFO_LEVEL';
220 3 50       9 if(!exists($self->{$key})){
221 0         0 $self->{$key} = $Deflt{$key};
222             }
223 3 100       16 if(@_){
224 1         3 $self->{$key} = $_[0];
225             }
226            
227 3         16 return($self->{$key});
228             }
229            
230            
231             ##############################################################################
232             sub alwayslog_level {
233             =pod
234            
235             =head2 alwayslog_level()
236            
237             C
238            
239             =over 2
240            
241             =item Usage:
242            
243             $alwayslog_level = $obj_ref->alwayslog_level(); #From Caller's Perspective
244             or
245             $self->alwayslog_level(ALWAYSLOG); # -3 from Log::AndError::Constants
246            
247             =item Purpose:
248            
249             Sets or gets the alwayslog level. Should be <= -2. If you decide against that then make sure you know what you are doing and info/alwayslog do not interfere. The default is in the POD above and can be retrieved at runtime from the return value.
250            
251             =item Returns:
252            
253             ($alwayslog_level) if set.
254            
255             =back
256            
257             =cut
258 3     3 1 143 my $self = shift;
259             ####$self->logger(DEBUG3, 'alwayslog_level('.join(',',@_).')'); # DO NOT DO THIS!
260 3         4 my $key = 'LOG_ALWAYSLOG_LEVEL';
261 3 50       11 if(!exists($self->{$key})){
262 0         0 $self->{$key} = $Deflt{$key};
263             }
264 3 100       7 if(@_){
265 1         3 $self->{$key} = $_[0];
266             }
267 3         10 return($self->{$key});
268             }
269            
270            
271             ##############################################################################
272             sub template{
273             =pod
274            
275             =head2 template()
276            
277             C
278            
279             =over 2
280            
281             =item Usage:
282            
283             my $template = $obj_ref->template(); #From Caller's Perspective
284             or
285             my $template = $self->template("%s: LEVEL[%d]: %s");
286            
287             =item Purpose:
288            
289             This is a method for setting the sprintf() template for the logging method. It must have a %s(string), %d(decimal), %s(string) format to it. What you place in between is up to you. The default is in the POD above and can be retrieved at runtime from the return value.
290            
291             =item Returns:
292            
293             ($template) if set and passes syntax test.
294            
295             =back
296            
297             =cut
298 7     7 1 467 my $self = shift;
299             ####$self->logger(DEBUG3, 'template('.join(',',@_).')');# DO NOT DO THIS!
300 7         10 my($ok, $error) = (1, undef);
301 7         11 my $key = 'LOG_TEMPLATE';
302 7 50       17 if(!exists($self->{$key})){
303 0         0 $self->{$key} = $Deflt{$key};
304             }
305            
306 7 100       34 if(@_) {
307 3 100       8 if(_template_check($_[0])){
308 2         6 $self->{$key} = $_[0];
309             }
310             else{
311 1         3 ($ok, $error) = (undef, 'Bad sprintf() Template');
312 1         5 $self->{$key} = undef;
313             }
314             }
315            
316 7         19 $self->error($ok, $error);
317 7         24 return($self->{$key});
318             }
319            
320             ##############################################################################
321             sub error{
322             =pod
323            
324             =head2 error()
325            
326             C
327            
328             =over 2
329            
330             =item Usage:
331            
332             my($err,$msg) = $obj_ref->error(); #From Caller's Perspective
333             or
334             $self->error($error_code, $error_msg);
335            
336             =item Purpose:
337            
338             This is a wrapper for the C and C functions. Remember that this is most useful when inherited by your module via ISA.
339            
340             =item Returns:
341            
342             ($err, $msg) Values are up to you. See Message for details
343            
344             =back
345            
346             =cut
347 9     9 1 497 my $self = shift;
348             ####$self->logger(DEBUG3, 'error('.join(',',@_).')');# DO NOT DO THIS!
349 9 100       55 if (@_){
350 8         16 my ($code,$msg) = ($_[0], $_[1]);
351 8         20 $self->error_code($code);
352 8         20 $self->error_msg($msg);
353             }
354 9         21 return($self->error_code(),$self->error_msg());
355             }
356            
357            
358             ##############################################################################
359             sub error_code{
360             =pod
361            
362             =head2 error_code()
363            
364             C
365            
366             =over 2
367            
368             =item Usage:
369            
370             $err = $obj_ref->error_code(); #From Caller's Perspective
371             or
372             $self->error_code($code);
373            
374             =item Purpose:
375            
376             Sets or gets the last error code encountered. Remember that this is most useful when inherited by your app via ISA.
377            
378             =item Returns:
379            
380             ($err) Values are up to you.
381            
382             =back
383            
384             =cut
385 17     17 1 22 my $self = shift;
386             ####$self->logger(DEBUG3, 'error_code('.join(',',@_).')'); # DO NOT DO THIS!
387 17         21 my $key = 'LOG_ERROR_CODE';
388 17 50       45 if(!exists($self->{$key})){
389 0         0 $self->{$key} = $Deflt{$key};
390             }
391 17 100       36 if(@_){
392 8         12 $self->{$key} = $_[0];
393             }
394 17         43 return($self->{$key});
395             }
396            
397             ##############################################################################
398             sub error_msg{
399            
400             =pod
401            
402             =head2 error_msg()
403            
404             C
405            
406             =over 2
407            
408             =item Usage:
409            
410             $msg = $obj_ref->error_msg(); #From Caller's Perspective
411             or
412             $self->error_msg($msg);
413            
414             =item Purpose:
415            
416             Sets or gets the textual description of last error. Remmber that this is most useful when inherited by your app via ISA.
417            
418             =item Returns:
419            
420             ($msg) Values are up to you.
421            
422             =back
423            
424             =cut
425 17     17 1 19 my $self = shift;
426             ####$self->logger(DEBUG3, 'error_msg('.join(',',@_).')'); # DO NOT DO THIS!
427 17         25 my $key = 'LOG_ERROR_MSG';
428 17 50       41 if(!exists($self->{$key})){
429 0         0 $self->{$key} = $Deflt{$key};
430             }
431 17 100       34 if(@_){
432 8         14 $self->{$key} = $_[0];
433             }
434 17         33 return($self->{$key});
435             }
436            
437             ##############################################################################
438             sub logger {
439            
440             =pod
441            
442             =head2 logger()
443            
444             C
445            
446             =over 2
447            
448             =item Usage:
449            
450             my($err, $msg) = $self->logger(DEBUG_CONSTANT, $msg);
451            
452             =item Purpose:
453            
454             Logs messages.
455            
456             =item Returns:
457            
458             ($err, $msg) undef is OK. Everything else > 0 is an error. See Message for details
459            
460             =back
461            
462             =cut
463 2     2 1 482 my $self = shift;
464             ####$self->logger(DEBUG3, 'add('.join(',',@_).')'); # DO NOT DO THIS!
465 2         4 my($level,$msg) = ($_[0], $_[1]);
466 2         5 my($nok,$error) = (undef, 'ENTRY NOT LOGGED');
467 2         2 my $key = 'LOG_LOGGER';
468            
469 2 50       7 if(!exists($self->{$key})){
470 0         0 $self->{$key} = $Deflt{$key};
471             }
472 2 50 66     7 if(( ($level <= $self->debug_level) && ($level >= 0) ) || ($level == $self->info_level) || ($level == $self->alwayslog_level)) {
      66        
      66        
473 1         4 $self->{$key}->(sprintf($self->template,$self->service_name,$level,$msg));
474 1         4 ($nok, $error) = (undef, 'ENTRY LOGGED');
475             }
476             #$self->error($nok,$error); # DO NOT do this as it screws up ISA users
477 2         7 return($nok,$error);
478             }
479            
480            
481             #################################################################################
482             ## Private Methods
483             #################################################################################
484            
485             ##############################################################################
486             sub _log {
487 0     0   0 warn(join(', ',@_));
488             }
489            
490             sub _template_check {
491 3     3   4 my $temp = $_[0];
492 3         29 return($temp =~ m/.*\%s.*\%d.*\%s.*/gox);
493             }
494            
495             =pod
496            
497             =head1 HISTORY
498            
499             =head2 See Changes file in distribution.
500            
501             =head1 TODO
502            
503             =over 1
504            
505             =item *
506            
507             More Documentation.
508            
509             =item *
510            
511             More samples Log functions. (syslog, SQL, etc...)
512             The SQL example should implement a time sequence for preserving order
513            
514             =back
515            
516             =head1 AUTHOR
517            
518             =over 1
519            
520             Thomas Bolioli
521            
522             =back
523            
524             =head1 THANKS
525            
526             =over 1
527            
528             Thanks to John Ballem of Brown University for the Constants module and the push to do this one.
529            
530             =back
531            
532            
533             =head1 COPYRIGHT
534            
535             Copyright (c) 2001 Thomas Bolioli. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
536            
537             =head1 SEE ALSO
538            
539             =over 1
540            
541             =item *
542            
543             perl
544            
545             =item *
546            
547             Log::AndError::Constants
548            
549             =cut
550            
551             1;