File Coverage

blib/lib/Log/LogMethods.pm
Criterion Covered Total %
statement 205 235 87.2
branch 40 74 54.0
condition 4 6 66.6
subroutine 43 45 95.5
pod 10 12 83.3
total 302 372 81.1


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