File Coverage

blib/lib/Log/LogMethods.pm
Criterion Covered Total %
statement 220 261 84.2
branch 41 78 52.5
condition 4 9 44.4
subroutine 44 47 93.6
pod 11 13 84.6
total 320 408 78.4


line stmt bran cond sub pod time code
1             package Log::LogMethods;
2              
3 4     4   336426 use Modern::Perl;
  4         11  
  4         39  
4 4     4   1559 use Time::HiRes qw(tv_interval gettimeofday);
  4         10  
  4         44  
5 4     4   2486 use Ref::Util qw(is_plain_hashref is_blessed_hashref);
  4         9164  
  4         531  
6 4     4   36 use Scalar::Util qw(blessed);
  4         9  
  4         290  
7 4     4   32 use B qw(svref_2object);
  4         10  
  4         796  
8 4     4   32 use Scalar::Util qw(looks_like_number);
  4         12  
  4         276  
9 4     4   29 no warnings 'redefine';
  4         9  
  4         274  
10 4     4   7330 use Log::Log4perl;
  4         212375  
  4         37  
11 4     4   309 use Log::Log4perl::Level;
  4         12  
  4         30  
12             Log::Log4perl->wrapper_register(__PACKAGE__);
13 4     4   3889 use Moo::Role;
  4         61838  
  4         30  
14              
15 4     4   4872 use Carp qw(croak);
  4         19  
  4         373  
16 4     4   1833 use namespace::clean;
  4         63423  
  4         46  
17              
18             our $VERSION='1.010';
19             our $SKIP_TRIGGER=0;
20              
21             # used as a place holder for extended format data
22             our $CURRENT_CB;
23             BEGIN {
24              
25             # disable logging
26             #local $SIG{__WARN__}=sub { };
27              
28             # always should be before off
29 4     4   2821 Log::Log4perl::Logger::create_custom_level(qw( ALWAYS OFF));
30             }
31              
32 34     34 0 119 sub LOOK_BACK_DEPTH { 3; }
33              
34             our %LEVEL_MAP=(
35             OFF=>$OFF,
36             ALWAYS=>$ALWAYS,
37             FATAL=>$FATAL,
38             ERROR=>$ERROR,
39             WARN=>$WARN,
40             INFO=>$INFO,
41             DEBUG=>$DEBUG,
42             TRACE=>$TRACE,
43             );
44              
45             =pod
46              
47             =head1 NAME
48              
49             Log::LogMethods - Writes your logging code for you!
50              
51             =head1 SYNOPSIS
52              
53             package test_moo;
54              
55             use Moo;
56             BEGIN { with qw(Log::LogMethods) }
57             sub test_always : BENCHMARK_ALWAYS { ... }
58              
59             my $logger=Log::Log4perl->get_logger(__PACKAGE__);
60             my $class=new test_moo(logger=>$logger);
61              
62             =cut
63              
64             =head1 Log4Perl Sugested PatternLayout
65              
66             To get everything you were expecting from classes that extend this one, use the following PatternLayout:
67              
68             %H %P %d %p %f %k %S [%h] %s %b %j %B%n
69              
70             The above format will produce logs like this:
71              
72             d00nappu0019 108201 2017/03/13 18:36:45 INFO t/Log-LogMethods.t 292 test_header::res_info [HEADER TEST] Starting 1
73             d00nappu0019 108201 2017/03/13 18:36:45 ERROR t/Log-LogMethods.t 292 test_header::res_info [HEADER TEST] error message 1
74             d00nappu0019 108201 2017/03/13 18:36:45 INFO t/Log-LogMethods.t 292 test_header::res_info [HEADER TEST] Finished 1 elapsed 0.000362
75              
76             =head2 Log4Perl Custom PatternLayouts
77              
78             Since log4perl can get pertty confused with what the (package::method and line) number should be from Log::LogMethods, the following Custom PatternLayout have been added:
79              
80             +------------------------------------------------------+
81             | Layout | Replaces | Description |
82             +--------+----------+----------------------------------+
83             | %f | %F | File the alert came from |
84             | %s | %m | actual Message |
85             | %k | %L | Line Number ( if any ) |
86             | %S | | fully qualified package::method |
87             | %v | %C | package |
88             +--------+----------+----------------------------------+
89              
90             Special case PatternLayouts
91              
92             +--------+----------------------------------------+
93             | %h | Log Header value ( if any ) |
94             | %b | Benchmark recursion_level |
95             | %B | Benchmaked time in microseconds |
96             | %j | set to "elapsed" for benchmark methods |
97             +--------+----------------------------------------+
98              
99             =cut
100              
101             our %FORMAT_MAP=(
102             qw(
103             f filename
104             s msg
105             k line
106             h header
107             S sub
108             v package
109              
110             b recursion_level
111             B elapsed
112             j kw_elapsed
113             )
114             );
115              
116             while(my ($format,$key)=each %FORMAT_MAP) {
117             Log::Log4perl::Layout::PatternLayout::add_global_cspec($format,sub {
118             my ($layout, $msg, $category, $priority, $caller_level)=@_;
119              
120             my $hash=$CURRENT_CB;
121              
122             # make us a real drop in replacement!
123             unless(is_plain_hashref $hash) {
124             $hash=__PACKAGE__->strack_trace_to_level( $caller_level);
125             while($hash->{package} eq 'Log::Log4perl::Logger') {
126             ++$caller_level;
127             $hash=__PACKAGE__->strack_trace_to_level( $caller_level);
128             if($hash->{sub}=~ /^Log::Log4perl::Logger/s) {
129             $hash->{sub}=__PACKAGE__->strack_trace_to_level(1+ $caller_level)->{sub};
130             }
131             }
132             $hash->{msg}=$msg;
133             }
134             exists $hash->{$key} ? $hash->{$key} : '';
135             }
136             );
137             }
138              
139             =head1 DESCRIPTION
140              
141             This library provides a common logging interfcaes that expects: Log::Log4perl::Logger or something that extends those features.
142              
143             =head1 Get and set log levels
144              
145             If you want to manualy get/set log levels
146              
147             use Log::Log4perl::Level;
148              
149             if($self->level!=$WARN) { $self->level($WARN) }
150              
151             =cut
152              
153             sub level {
154 29     29 1 229930 my ($self,$level)=@_;
155            
156 29 100       970 if(defined($self->logger)) {
157 26 100       359 if(looks_like_number($level)) {
158 10         213 $self->logger->level($level);
159             }
160 26         11663 return $self->logger->level;
161             } else {
162 3         39 return;
163             }
164             }
165              
166             =head1 OO Methods provided
167              
168             This class adds the following arguments and accessors to any class that loads using 'with';
169              
170             logger: DOES(Log::Log4perl::Logger)
171              
172             When the object DOES Log::Log4perl::Logger, the correct Log::Log4perl->get_logger(__PACKAGE__) call will be done. If you wish to modify the logger method, use an around declaration. This will keep the trigger $self->_trigger_logger($logger|undef) in tact.
173              
174             Example:
175              
176             around logger=>sub {
177             my ($code,$self,$logger)=@_;
178              
179             if(defined($logger)) {
180              
181             # Do something here
182             return $org->($self,$logger);
183             } else {
184             return $org->($self);
185             }
186             };
187              
188              
189             If you wish to just disable the trigger globally, you just disable it using the following flag.
190              
191             $Log::LogMethods::SKIP_TRIGGER=1;
192              
193             =over 4
194              
195             =cut
196              
197             has logger=>(
198             is=>'rw',
199             isa=>sub {
200             my ($logger)=@_;
201             croak 'argument: logger must DOES(Log::Log4perl::Logger)' unless defined($logger);
202             croak 'argument: logger must DOES(Log::Log4perl::Logger)' unless $logger->DOES('Log::Log4perl::Logger')
203             },
204             trigger=>1,
205             );
206              
207             sub _trigger_logger {
208 2     2   35 my ($self,$logger)=@_;
209              
210 2 50       6 unless(defined($logger)) {
211 0 0       0 return undef unless exists $self->{logger};
212 0         0 return $self->{logger};
213             }
214 2 50       7 return $logger if $SKIP_TRIGGER;
215              
216 2 50       9 if($logger->DOES('Log::Log4perl::Logger')) {
217 2         3 my $class=blessed $self;
218 2 50       6 $class=$self unless defined($class);
219              
220             # create our logging class, if we wern't given the one for us
221 2         8 my $cat=$logger->category;
222 2         13 $class=~ s/::/./g;
223 2 100       7 if($cat ne $class) {
224 1         26 $self->log_debug("Logger->category eq '$cat', Creating our own: Log::Log4perl->get_logger('$class')");
225 1         6 my $our_logger=Log::Log4perl->get_logger($class);
226 1         408 $self->{logger}=$our_logger;
227 1         9 return $our_logger;
228             }
229             }
230              
231 1         4 return $logger;
232             };
233              
234             =item * $self->log_error("Some error");
235              
236             This is a lazy man's wrapper function for
237              
238             my $log=$self->logger;
239             $log->log_error("Some error") if $log;
240              
241             =cut
242              
243             sub log_error {
244 6     6 1 6391 my ( $self, @args ) = @_;
245              
246 6         24 $self->log_to_log4perl('ERROR',$self->LOOK_BACK_DEPTH,@args);
247              
248             }
249              
250             =item * $log->log_die("Log this and die");
251              
252             Logs the given message then dies.
253              
254             =cut
255              
256             sub log_die {
257 1     1 1 628 my ( $self, @args ) = @_;
258              
259 1         56 my $log = $self->logger;
260 1         11 my @list = ('DIE');
261 1 50       23 push @list, $self->log_header if $self->can('log_header');
262 1 50       6 return die join(' ',map { defined($_) ? $_ : 'undef' } @list,@args)."\n" if $self->log_to_log4perl('ERROR',$self->LOOK_BACK_DEPTH,@args);
  3 50       14  
263              
264 0         0 my $string=$self->format_log(@list,@args);
265              
266 0 0       0 return die $string unless $log;
267              
268 0         0 $self->log_to_log4perl('FATAL',$self->LOOK_BACK_DEPTH,@args);
269 0         0 die $string;
270             }
271              
272             sub format_log {
273 0     0 0 0 my ($self,@args)=@_;
274              
275 0 0       0 return join(' ',@args)."\n" unless $self->logger;
276 0         0 return $self->logger->format_log(@args);
277              
278             }
279              
280             =item * $self->log_always("Some msg");
281              
282             This is a lazy man's wrapper function for
283              
284             my $log=$self->logger;
285             $log->log_always("Some msg") if $log;
286              
287             =cut
288              
289             sub log_always {
290 6     6 1 6033 my ( $self, @args ) = @_;
291 6         30 $self->log_to_log4perl('ALWAYS',$self->LOOK_BACK_DEPTH,@args);
292             }
293              
294             =item * my $string=$self->log_header;
295              
296             This is a stub function that allows a quick addin for logging, the string returned will be inserted after the log_level in the log file if this function is created.
297              
298             =cut
299              
300             =item * $self->log_warn("Some msg");
301              
302             This is a lazy man's wrapper function for:
303              
304             my $log=$self->logger;
305             $log->log_warn("Some msg") if $log;
306              
307             =cut
308              
309             sub log_warn {
310 6     6 1 6338 my ( $self, @args ) = @_;
311              
312 6         23 $self->log_to_log4perl('WARN',$self->LOOK_BACK_DEPTH,@args);
313             }
314              
315             =item * $self->log_info("Some msg");
316              
317             This is a lazy man's wrapper function for:
318              
319             my $log=$self->logger;
320             $log->log_info("Some msg") if $log;
321              
322             =cut
323              
324             sub log_info {
325 8     8 1 5370 my ( $self, @args ) = @_;
326 8         31 $self->log_to_log4perl('INFO',$self->LOOK_BACK_DEPTH,@args);
327             }
328              
329             =item * $self->log_debug("Some msg");
330              
331             This is a lazy man's wrapper function for:
332              
333             my $log=$self->logger;
334             $log->log_debug("Some msg") if $log;
335              
336             =cut
337              
338             sub log_debug {
339 7     7 1 7627 my ( $self, @args ) = @_;
340 7         31 $self->log_to_log4perl('DEBUG',$self->LOOK_BACK_DEPTH,@args);
341             }
342              
343             =item * $self->log_trace('some trace message')
344              
345             Same as calling $self->trace('some trace message');
346              
347             =cut
348              
349             sub log_trace {
350 0     0 1 0 my ( $self, @args ) = @_;
351 0         0 $self->log_to_log4perl('TRACE',$self->LOOK_BACK_DEPTH,@args);
352             }
353              
354             =back
355              
356             =head2 ATTRIBUTES
357              
358             Logging attributes can be set for a given function. All logging wrappers autmatically log failed Data::Result objects as log_level ERROR.
359              
360             =head3 BASIC WRAPPERS
361              
362             These attributes provide the baseic Starting and Ending log entries for a given function.
363              
364             =over 4
365              
366             =cut
367              
368             =item * sub some_method : RESULT_ALWAYS { ... }
369              
370             Will always produce a start and end log entry
371              
372             =item * sub some_method : RESULT_ERROR { ... }
373              
374             Will always produce a starting and ending log entry at log level ERROR.
375              
376             =item * sub some_method : RESULT_WARN { ... }
377              
378             Will always produce a starting and ending log entry at log level WARN.
379              
380             =item * sub some_method : RESULT_INFO { ... }
381              
382             Will always produce a starting and ending log entry at log level INFO.
383              
384             =item * sub some_method : RESULT_DEBUG { ... }
385              
386             Will always produce a starting and ending log entry at log level DEBUG.
387              
388             =cut
389              
390             =back
391              
392             =head3 BENCHMARKING
393              
394             Functions can be declared with a given benchmark method.
395              
396             =over 4
397              
398             =item * BENCHMARK_INFO
399              
400             Declares Start and End log entries for the given function, along with a benchmark timestamp. Benchmark time differences are in microseconds.
401              
402             =cut
403              
404              
405             =item * sub method : BENCHMARK_ALWAYS { ... }
406              
407             Always benchmark this method.
408              
409             =item * sub method : BENCHMARK_ERROR { ... }
410              
411             Only benchmark this function if log level is >= ERROR
412              
413             =item * sub method : BENCHMARK_WARN { ... }
414              
415             Only benchmark this function if log level is >= WARN
416              
417             =item * sub method : BENCHMARK_INFO { ... }
418              
419             Only benchmark this function if log level is >= INFO
420              
421             =item * sub method : BENCHMARK_DEBUG { ... }
422              
423             Only benchmark this function if log level is >= DEBUG
424              
425             =back
426              
427             =head1 INTERNAL METHODS
428              
429             This section documents internal methods.
430              
431             =over 4
432              
433             =item * $self->MODIFY_CODE_ATTRIBUTES($code,$att)
434              
435             Method that generates the wrapper funcitons.
436              
437             Attrivutes:
438              
439             code: glob to overwrite
440             att: The Attribute being overwritten
441              
442             =cut
443              
444             sub MODIFY_CODE_ATTRIBUTES {
445 60     60   27770 my $self=shift;
446 60         114 my $code=shift;
447 60 50       179 return () unless @_;
448 60         118 my @attr;
449 60 50       344 if(my $root=$self->SUPER::can('MODIFY_CODE_ATTRIBUTES')) {
450 60 50       227 if($root eq \&MODIFY_CODE_ATTRIBUTES) {
451 60         201 @attr=@_;
452             } else {
453 0         0 my @list;
454 0         0 for my $attr (@_) {
455 0         0 my ($type,$level)=split /_/,$attr;
456 0 0 0     0 if(exists $LEVEL_MAP{$level} and $type=~ m/^(?:BENCHMARK|RESULT)$/s) {
457 0         0 push @attr,$attr,
458             } else {
459 0         0 push @list,$attr;
460             }
461             }
462              
463 0         0 push @attr,$self->$root($code,@list);
464             }
465             } else {
466 0         0 @attr=@_;
467             }
468 60         139 my $attr=shift @attr;
469 60         251 my $trace=$self->strack_trace_to_level(2);
470            
471 60         404 my $gv=svref_2object($code)->GV;
472 60         227 my $name=$gv->NAME;
473 60         134 my $tn="${self}::$name";
474 60         130 $trace->{sub}=$tn;
475 60         149 $trace->{line}=$gv->LINE;
476 60         253 my ($type,$level)=split /_/,$attr;
477 60 50 33     513 return ($attr,@attr) unless exists $LEVEL_MAP{$level} and $type=~ m/^(?:BENCHMARK|RESULT)$/s;
478              
479 60         152 my $lc=lc($type);
480 60         112 my $method="_attribute_${lc}_common";
481 60         103 my $target=$code;
482             {
483 4     4   12304 no strict 'refs';
  4         11  
  4         1323  
  60         84  
484 60 50       100 if(my $nc=\&{$tn} ne $code) {
  60         372  
485             # the code we intended to modify was changed
486 0         0 $target=$nc
487             }
488             }
489 60         283 my $ref=$self->$method($trace,$level,$target);
490 60         345 return (@attr);
491             }
492              
493              
494             =item * $self->_attribute_result_common( $stack,$level,$code );
495              
496             Compile time code, generates basic Startin Finsihed log messages for a given "LEVEL" and also creates ERROR Log entries if the object returned DOES('Data::Result') and is in an error state.
497              
498             Arguments:
499              
500             stack: stack hashref
501             level: level(WARN|ALWAYS|INFO|ERROR|DEBUG|TRACE)
502             code: code ref to replcae
503              
504             =cut
505              
506             sub _attribute_result_common {
507 20     20   67 my ($self,$stack,$level,$code)=@_;
508              
509 20         44 my $method=$stack->{sub};
510             my $ref=sub {
511 4     4   35 use strict;
  4         8  
  4         200  
512 4     4   27 use warnings;
  4         9  
  4         1572  
513 0     0   0 my ($self)=@_;
514              
515 0         0 my $log=$self->logger;
516 0         0 my $constant="LOG_$level";
517              
518 0         0 $self->log_to_log4perl($level,$stack,'Starting');
519              
520 0         0 my $result;
521 0 0       0 if(wantarray) {
522 0         0 $result=[$code->(@_)];
523 0 0       0 if($#{$result}==0) {
  0         0  
524 0         0 $self->data_result_auto_log_error($stack,$result->[0]);
525             }
526             } else {
527 0         0 $result=$code->(@_);
528 0         0 $self->data_result_auto_log_error($stack,$result);
529             }
530              
531 0         0 $self->log_to_log4perl($level,$stack,'Finished');
532              
533 0 0       0 return wantarray ? @{$result} : $result;
  0         0  
534 20         136 };
535 4     4   47 no strict;
  4         9  
  4         230  
536 4     4   28 no warnings 'redefine';
  4         11  
  4         820  
537 20         39 *{$method}=$ref;
  20         79  
538 20         68 return $ref;
539             }
540              
541             =item * $self->_attribute_benchmark_common( $stack,$level,$code);
542              
543             Compile time code, generates Benchmarking log for a given function: Startin Finsihed log messages for a given "LEVEL" and also creates ERROR Log entries if the object returned DOES('Data::Result') and is in an error state.
544              
545             Arguments:
546              
547             stack: stack hashref
548             level: level(WARN|ALWAYS|INFO|ERROR|DEBUG|TRACE)
549             code: code ref to replcae
550              
551             =cut
552              
553             sub _attribute_benchmark_common {
554 40     40   123 my ($self,$stack,$level,$code)=@_;
555              
556 40         75 my $method=$stack->{sub};
557 40         64 my $id=0;
558             my $ref=sub {
559 4     4   34 use strict;
  4         10  
  4         142  
560 4     4   22 use warnings;
  4         8  
  4         2481  
561 30     30   27005 my ($self)=@_;
562              
563 30         61 ++$id;
564 30         485 my $log=$self->logger;
565              
566 30         176 my $constant="LOG_$level";
567 30         116 my $t0 = [gettimeofday];
568 30         54 my $stack={%{$stack}};
  30         156  
569 30         87 $stack->{recursion_level}=$id;
570              
571 30         116 $self->log_to_log4perl($level,$stack,'Starting');
572              
573 30         67 my $result;
574 30 50       68 if(wantarray) {
575 0         0 $result=[$code->(@_)];
576 0 0       0 if($#{$result}==0) {
  0         0  
577 0         0 $self->data_result_auto_log_error($stack,$result->[0]);
578             }
579             } else {
580 30         113 $result=$code->(@_);
581 30         4530 $self->data_result_auto_log_error($stack,$result);
582             }
583              
584 30         483 my $elapsed = tv_interval ( $t0, [gettimeofday]);
585 30         470 $stack->{elapsed}=$elapsed;
586 30         101 $stack->{kw_elapsed}='elapsed';
587 30         84 $self->log_to_log4perl($level,$stack,'Finished');
588              
589 30         54 --$id;
590              
591 30 50       170 return wantarray ? @{$result} : $result;
  0         0  
592 40         467 };
593 4     4   40 no strict;
  4         10  
  4         174  
594 4     4   26 no warnings 'redefine';
  4         9  
  4         5567  
595 40         102 *{$method}=$ref;
  40         177  
596 40         111 return $ref;
597             }
598              
599             =item * $self->log_to_log4perl($level,$stack,@args)
600              
601             Low level Automatic logger selection.
602              
603             Arguments:
604              
605             level: Log level (ALWAYS|ERROR|WARN|INFO|DEBUG)
606             stack: number or hashref $trace
607             args: argument list for logging
608              
609             =cut
610              
611             =item * $self->data_result_auto_log_error($stack,$result);
612              
613             Creates a required log entry for a false Data::Result object
614              
615             Arguments:
616              
617             stack: level or $trace
618             result: Object, if DOES('Data::Result') and !$result->is_true a log entry is created
619              
620             =cut
621              
622             sub data_result_auto_log_error {
623 30     30 1 74 my ($self,$stack,$result)=@_;
624 30 50       89 if(is_blessed_hashref($result)) {
625 30 50       126 if($result->DOES('Data::Result')) {
626 30 100       553 $self->log_to_log4perl('ERROR',$stack,$result) unless $result->is_true;
627             }
628             }
629             }
630              
631             =item * my $strace=$self->strack_trace_to_level($number)
632              
633             Given the number, trturns the currect $trace
634              
635             trace
636              
637             sub: Name of the function
638             filename: source file
639             package: Package name
640             line: Line number
641              
642             =cut
643              
644             sub strack_trace_to_level {
645 152     152 1 336 my ($self, $level) = @_;
646              
647 152         247 my $hash = {};
648 152         1542 @{$hash}{qw(package filename line sub)} = caller($level);
  152         754  
649              
650             # Look up the stack until we find something that explains who and what called us
651 152   100     1127 LOOK_BACK_LOOP: while ( defined( $hash->{sub} ) and $hash->{sub} =~ /eval/ ) {
652              
653 2         12 my $copy = {%$hash};
654 2         7 @{$hash}{qw(package filename line sub)} = caller( ++$level );
  2         7  
655              
656             # give up when we have a dead package name
657 2 50       8 unless ( defined( $hash->{package} ) ) {
658              
659 2         6 $hash = $copy;
660 2         6 $hash->{eval} = 1;
661              
662 2         7 last LOOK_BACK_LOOP;
663             }
664             }
665              
666             # if we don't know where we were called from, we can assume main.
667 25         100 @{$hash}{qw(sub filename package line)} = ( 'main::', $0, 'main', 'undef' )
668 152 100       416 unless defined( $hash->{package} );
669              
670 152         334 $hash->{level}=$level;
671              
672 152         361 return $hash;
673             }
674              
675             =item * if($self->log_to_log4perl($level,$trace,@args)) { ... }
676              
677             Low Level check and log to log4perl logger object
678              
679             Arguments:
680              
681             level: Log Level (ALWAYS|ERROR|WARN|INFO|DEBUG|TRACE)
682             trace: level number or $trace
683             args: list of strings to log
684              
685             =cut
686              
687             sub log_to_log4perl {
688 121     121 1 593 my ($self,$level,$trace,@args)=@_;
689              
690 121         2492 my $log=$self->logger;
691 121 50       790 return 0 unless defined($log);
692            
693 121         182 my $header=' ';
694 121 100       504 $header=' '.$self->log_header.' ' if $self->can('log_header');
695 121         245 foreach my $value (@args) {
696 121 50       300 $value='undef' unless defined($value);
697             }
698              
699 121 100       250 if(is_plain_hashref($trace)) {
700              
701             # this will be modified, so make a copy!
702 87         115 $trace={%{$trace}};
  87         378  
703             } else {
704 34         161 $trace=$self->strack_trace_to_level($trace);
705 34         93 $trace->{line}=$self->strack_trace_to_level($trace->{level} -1)->{line};
706             }
707            
708 121 100       526 $trace->{header}=$self->log_header if $self->can('log_header');
709 121         409 $trace->{msg}=join ' ',@args;
710              
711 121         542 my $id;
712 121 50       248 if(exists $LEVEL_MAP{$level}) {
713 121         229 $id=$LEVEL_MAP{$level};
714             } else {
715 0         0 $id=$LEVEL_MAP{OFF};
716             }
717 121         148 $CURRENT_CB=$trace;
718 121         588 $log->log($id,$trace->{msg});
719 121         28238 $CURRENT_CB=undef;
720 121         516 return 1;
721             }
722              
723             =back
724              
725             =head1 Method Generation
726              
727             This section documents the code generation methods
728              
729             =over 4
730              
731             =item * $self->_create_is_check($name,$level)
732              
733             Generates the "is_xxx" method based on $name and $level.
734              
735             Argumetns:
736              
737             name: Human readable word such as: DEBUG
738             level: Levels come from Log::Log4perl::Level
739              
740             =cut
741              
742             sub _create_is_check {
743 32     32   77 my ($self,$name,$level)=@_;
744              
745 32 100       117 my $method="is_".lc($name eq 'WARN' ? 'warning' : $name);
746             my $code=sub {
747 8     8   5454 my ($self)=@_;
748              
749 8         25 my $level=$self->level;
750 8 50       409 return 0 unless looks_like_number($level);
751 8         36 return $level == $Log::LogMethods::LEVEL_MAP{$name};
752 32         199 };
753              
754 4     4   40 no strict;
  4         9  
  4         160  
755 4     4   25 no warnings 'redefine';
  4         18  
  4         1923  
756 32         3469 eval "*$method=\$code";
757             }
758              
759             =item * $self->_create_logging_methods($name,$level)
760              
761             Generates the logging methods based on $name and $level.
762              
763             Argumetns:
764              
765             name: Human readable word such as: DEBUG
766             level: Levels come from Log::Log4perl::Level
767              
768             =cut
769              
770             sub _create_logging_methods {
771 32     32   92 my ($self,$name,$level)=@_;
772 32 100       115 my $method=lc($name eq 'WARN' ? 'warning' : $name);
773             my $code=sub {
774 12     12   15151 my ($self,@args)=@_;
775              
776 12         47 my $trace=$self->strack_trace_to_level(2);
777 12         37 $trace->{line}=$self->strack_trace_to_level($trace->{level} -1)->{line};
778              
779 12         45 return $self->log_to_log4perl($name,$trace,@args);
780 32         209 };
781 32         3078 eval "*$method=\$code";
782             }
783              
784              
785             while(my ($name,$level)=each %Log::LogMethods::LEVEL_MAP) {
786             __PACKAGE__->_create_is_check($name,$level);
787             __PACKAGE__->_create_logging_methods($name,$level);
788             }
789              
790             =back
791              
792             =head2 log level checks
793              
794             The logging and is_xxx methods are auto generated based on the key/value pairs in %Log::LogMethods::LEVEL_MAP.
795              
796             =over 4
797              
798             =item * if($self->is_always) { ... }
799              
800             =item * if($self->is_error) { ... }
801              
802             =item * if($self->is_warning) { ... }
803              
804             =item * if($self->is_info) { ... }
805              
806             =item * if($self->is_debug) { ... }
807              
808             =item * if($self->is_default_debug) { ... }
809              
810             =item * if($self->is_trace) { ... }
811              
812             =back
813              
814             =head2 Logging methods
815              
816             The following methods are autogenerated based on the key/value pairs in %Log::LogMethods::LEVEL_MAP.
817              
818             =over 4
819              
820             =item * $self->always("Some log entry")
821              
822             =item * $self->error("Some log entry")
823              
824             =item * $self->warning("Some log entry")
825              
826             =item * $self->info("Some log entry")
827              
828             =item * $self->debug("Some log entry")
829              
830             =item * $self->default_debug("Some log entry")
831              
832             =item * $self->trace("Some log entry")
833              
834             =back
835              
836             =head1 AUTHOR
837              
838             Mike Shipper <AKALINUX@CPAN.ORG>
839              
840             =cut
841              
842             1;