File Coverage

blib/lib/Log/LogMethods.pm
Criterion Covered Total %
statement 205 235 87.2
branch 39 72 54.1
condition 4 6 66.6
subroutine 43 45 95.5
pod 10 12 83.3
total 301 370 81.3


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