1##################################################
2package Log::Log4perl::Logger;
3##################################################
4
5use 5.006;
6use strict;
7use warnings;
8
9use Log::Log4perl;
10use Log::Log4perl::Level;
11use Log::Log4perl::Layout;
12use Log::Log4perl::Appender;
13use Log::Log4perl::Appender::String;
14use Log::Log4perl::Filter;
15use Carp;
16
17$Carp::Internal{"Log::Log4perl"}++;
18$Carp::Internal{"Log::Log4perl::Logger"}++;
19
20use constant _INTERNAL_DEBUG => 0;
21
22    # Initialization
23our $ROOT_LOGGER;
24our $LOGGERS_BY_NAME = {};
25our %APPENDER_BY_NAME = ();
26our $INITIALIZED = 0;
27our $NON_INIT_WARNED;
28
29    # Define the default appender that's used for formatting
30    # warn/die/croak etc. messages.
31our $STRING_APP_NAME = "_l4p_warn";
32our $STRING_APP      = Log::Log4perl::Appender->new(
33                          "Log::Log4perl::Appender::String",
34                          name => $STRING_APP_NAME);
35$STRING_APP->layout(Log::Log4perl::Layout::PatternLayout->new("%m"));
36our $STRING_APP_CODEREF = generate_coderef([[$STRING_APP_NAME, $STRING_APP]]);
37
38__PACKAGE__->reset();
39
40###########################################
41sub warning_render {
42###########################################
43    my($logger, @message) = @_;
44
45    $STRING_APP->string("");
46    $STRING_APP_CODEREF->($logger,
47                          @message,
48                          Log::Log4perl::Level::to_level($ALL));
49    return $STRING_APP->string();
50}
51
52##################################################
53sub cleanup {
54##################################################
55    # warn "Logger cleanup";
56
57    # Delete all loggers
58    foreach my $loggername (keys %$LOGGERS_BY_NAME){
59        # warn "Logger delete: $loggername";
60        $LOGGERS_BY_NAME->{$loggername}->DESTROY();
61        delete $LOGGERS_BY_NAME->{$loggername};
62    }
63
64    # Delete the root logger
65    undef $ROOT_LOGGER;
66
67    # Delete all appenders
68    foreach my $appendername (keys %APPENDER_BY_NAME){
69        if (exists $APPENDER_BY_NAME{$appendername} &&
70            exists $APPENDER_BY_NAME{$appendername}->{appender}) {
71                # Destroy the specific appender
72            my $appref = $APPENDER_BY_NAME{$appendername}->{appender};
73            eval { $appref->DESTROY() };
74                # Destroy L4p::Appender
75            $APPENDER_BY_NAME{$appendername}->DESTROY();
76            delete $APPENDER_BY_NAME{$appendername}->{appender};
77        }
78        delete $APPENDER_BY_NAME{$appendername};
79    }
80    %APPENDER_BY_NAME   = ();
81
82    undef $INITIALIZED;
83}
84
85##################################################
86sub DESTROY {
87##################################################
88    warn "Destroying logger $_[0]" if $Log::Log4perl::CHATTY_DESTROY_METHODS;
89
90    for(keys %{$_[0]}) {
91        delete $_[0]->{$_};
92    }
93}
94
95##################################################
96sub reset {
97##################################################
98    $ROOT_LOGGER        = __PACKAGE__->_new("", $DEBUG);
99#    $LOGGERS_BY_NAME    = {};  #leave this alone, it's used by
100                                #reset_all_output_methods when
101                                #the config changes
102
103
104    #we've got a circular reference thing going on somewhere
105    foreach my $appendername (keys %APPENDER_BY_NAME){
106        delete $APPENDER_BY_NAME{$appendername}->{appender}
107                if (exists $APPENDER_BY_NAME{$appendername} &&
108                    exists $APPENDER_BY_NAME{$appendername}->{appender});
109    }
110    %APPENDER_BY_NAME   = ();
111    undef $INITIALIZED;
112    undef $NON_INIT_WARNED;
113    Log::Log4perl::Appender::reset();
114
115    #clear out all the existing appenders
116    foreach my $logger (values %$LOGGERS_BY_NAME){
117        $logger->{appender_names} = ();
118
119	#this next bit deals with an init_and_watch case where a category
120	#is deleted from the config file, we need to zero out the existing
121	#loggers so ones not in the config file not continue with their old
122	#behavior --kg
123        next if $logger eq $ROOT_LOGGER;
124        $logger->{level} = undef;
125        $logger->level();  #set it from the heirarchy
126    }
127
128    # Clear all filters
129    Log::Log4perl::Filter::reset();
130}
131
132##################################################
133sub _new {
134##################################################
135    my($class, $category, $level) = @_;
136
137    print("_new: $class/$category/", defined $level ? $level : "undef",
138          "\n") if _INTERNAL_DEBUG;
139
140    die "usage: __PACKAGE__->_new(category)" unless
141        defined $category;
142
143    $category  =~ s/::/./g;
144
145       # Have we created it previously?
146    if(exists $LOGGERS_BY_NAME->{$category}) {
147        print "_new: exists already\n" if _INTERNAL_DEBUG;
148        return $LOGGERS_BY_NAME->{$category};
149    }
150
151    my $self  = {
152        category  => $category,
153        num_appenders => 0,
154        additivity    => 1,
155        level         => $level,
156        layout        => undef,
157                };
158
159   bless $self, $class;
160
161   $level ||= $self->level();
162
163        # Save it in global structure
164   $LOGGERS_BY_NAME->{$category} = $self;
165
166   $self->set_output_methods;
167
168   return $self;
169}
170
171##################################################
172sub reset_all_output_methods {
173##################################################
174    print "reset_all_output_methods: \n" if _INTERNAL_DEBUG;
175
176    foreach my $loggername ( keys %$LOGGERS_BY_NAME){
177        $LOGGERS_BY_NAME->{$loggername}->set_output_methods;
178    }
179    $ROOT_LOGGER->set_output_methods;
180}
181
182##################################################
183sub set_output_methods {
184# Here's a big performance increase.  Instead of having the logger
185# calculate whether to log and whom to log to every time log() is called,
186# we calculcate it once when the logger is created, and recalculate
187# it if the config information ever changes.
188#
189##################################################
190   my ($self) = @_;
191
192   my (@appenders, %seen);
193
194   my ($level) = $self->level();
195
196   print "set_output_methods: $self->{category}/$level\n" if _INTERNAL_DEBUG;
197
198   #collect the appenders in effect for this category
199
200   for(my $logger = $self; $logger; $logger = parent_logger($logger)) {
201
202        foreach my $appender_name (@{$logger->{appender_names}}){
203
204                #only one message per appender, (configurable)
205            next if $seen{$appender_name} ++ &&
206                    $Log::Log4perl::one_message_per_appender;
207
208            push (@appenders,
209                   [$appender_name,
210                    $APPENDER_BY_NAME{$appender_name},
211                   ]
212            );
213        }
214        last unless $logger->{additivity};
215    }
216
217        #make a no-op coderef for inactive levels
218    my $noop = generate_noop_coderef();
219
220       #make a coderef
221    my $coderef = (! @appenders ? $noop : &generate_coderef(\@appenders));
222
223    my %priority = %Log::Log4perl::Level::PRIORITY; #convenience and cvs
224
225   # changed to >= from <= as level ints were reversed
226    foreach my $levelname (keys %priority){
227        if (Log::Log4perl::Level::isGreaterOrEqual($level,
228						   $priority{$levelname}
229						   )) {
230            print "  ($priority{$levelname} <= $level)\n"
231                  if _INTERNAL_DEBUG;
232            $self->{$levelname}      = $coderef;
233            $self->{"is_$levelname"} = generate_is_xxx_coderef("1");
234            #$self->{"is_$levelname"} = sub { 1 };
235        }else{
236            print "  ($priority{$levelname} > $level)\n" if _INTERNAL_DEBUG;
237            $self->{$levelname}      = $noop;
238            $self->{"is_$levelname"} = generate_is_xxx_coderef("0");
239            #$self->{"is_$levelname"} = sub { 0 };
240        }
241
242        print("  Setting [$self] $self->{category}.$levelname to ",
243              ($self->{$levelname} == $noop ? "NOOP" :
244              ("Coderef [$coderef]: " . scalar @appenders . " appenders")),
245              "\n") if _INTERNAL_DEBUG;
246    }
247}
248
249##################################################
250sub generate_coderef {
251##################################################
252    my $appenders = shift;
253
254    print "generate_coderef: ", scalar @$appenders,
255          " appenders\n" if _INTERNAL_DEBUG;
256
257    my $coderef = '';
258    my $watch_delay_code = '';
259
260    # Doing this with eval strings to sacrifice init/reload time
261    # for runtime efficiency, so the conditional won't be included
262    # if it's not needed
263
264    if (defined $Log::Log4perl::Config::WATCHER) {
265        $watch_delay_code = generate_watch_code();
266    }
267
268    my $code = <<EOL;
269    sub {
270      my (\$logger)  = shift;
271      my (\$level)   = pop;
272      my \$message;
273      my \$appenders_fired = 0;
274
275      # Evaluate all parameters that need to evaluated. Two kinds:
276      #
277      # (1) It's a hash like { filter => "filtername",
278      #                        value  => "value" }
279      #     => filtername(value)
280      #
281      # (2) It's a code ref
282      #     => coderef()
283      #
284
285      \$message   = [map { ref \$_ eq "HASH" &&
286                           exists \$_->{filter} &&
287                           ref \$_->{filter} eq 'CODE' ?
288                               \$_->{filter}->(\$_->{value}) :
289                           ref \$_ eq "CODE" ?
290                               \$_->() : \$_
291                          } \@_];
292
293      print("coderef: \$logger->{category}\n") if _INTERNAL_DEBUG;
294
295      $watch_delay_code;  #note interpolation here
296
297      foreach my \$a (\@\$appenders) {   #note the closure here
298          my (\$appender_name, \$appender) = \@\$a;
299
300          print("  Sending message '<\$message>' (\$level) " .
301                "to \$appender_name\n") if _INTERNAL_DEBUG;
302
303          \$appender->log(
304              #these get passed through to Log::Dispatch
305              { name    => \$appender_name,
306                level   => \$Log::Log4perl::Level::L4P_TO_LD{
307                               \$level},
308                message => \$message,
309              },
310              #these we need
311              \$logger->{category},
312              \$level,
313          ) and \$appenders_fired++;
314              # Only counting it if it returns a true value. Otherwise
315              # the appender threshold might have suppressed it after all.
316
317      } #end foreach appenders
318
319      return \$appenders_fired;
320
321    }; #end coderef
322
323EOL
324
325    $coderef = eval $code or die "$@";
326
327    return $coderef;
328}
329
330##################################################
331sub generate_noop_coderef {
332##################################################
333    my $coderef = '';
334    my $watch_delay_code = '';
335
336    if (defined $Log::Log4perl::Config::WATCHER) {
337        $watch_delay_code = generate_watch_code();
338        $watch_delay_code = <<EOL;
339        my \$logger;
340        my \$level;
341        $watch_delay_code
342EOL
343    }
344
345    my $code = <<EOL;
346    \$coderef = sub {
347        print("noop: \n") if _INTERNAL_DEBUG;
348        $watch_delay_code
349        return undef;
350     };
351EOL
352
353    eval $code or die "$@";
354
355    return $coderef;
356}
357
358##################################################
359sub generate_is_xxx_coderef {
360##################################################
361    my($return_token) = @_;
362
363    my $coderef    = sub { $return_token };
364
365    if (defined $Log::Log4perl::Config::WATCHER) {
366
367        my $cond = generate_watch_conditional();
368
369        my $watch_code = <<EOL;
370        my(\$logger, \$subname) = \@_;
371        if($cond) {
372            Log::Log4perl->init_and_watch();
373            # Forward call to new configuration
374            return \$logger->\$subname();
375        }
376EOL
377
378        my $code = <<EOL;
379        \$coderef = sub { $watch_code return $return_token; };
380EOL
381
382        eval $code or die "$@";
383    }
384
385    return $coderef;
386}
387
388##################################################
389sub generate_watch_code {
390##################################################
391    print "generate_watch_code:\n" if _INTERNAL_DEBUG;
392
393    my $cond = generate_watch_conditional();
394
395    return <<EOL;
396        print "exe_watch_code:\n" if _INTERNAL_DEBUG;
397
398        # more closures here
399        if($cond) {
400            if(!defined \$logger) {
401                \$logger  = shift;
402                \$level   = pop;
403            }
404
405            Log::Log4perl->init_and_watch();
406
407            my \$methodname = lc(\$level);
408
409                # Bump up the caller level by two, since
410                # we've artifically introduced additional levels.
411            local(\$Log::Log4perl::caller_depth);
412            \$Log::Log4perl::caller_depth += 2;
413
414            \$logger->\$methodname(\@_); # send the message
415                                         # to the new configuration
416            return;        #and return, we're done with this incarnation
417        }
418EOL
419}
420
421##################################################
422sub generate_watch_conditional {
423##################################################
424
425    if(defined $Log::Log4perl::Config::Watch::SIGNAL_CAUGHT) {
426        # In this mode, we just check for the variable indicating
427        # that the signal has been caught
428        return q{$Log::Log4perl::Config::Watch::SIGNAL_CAUGHT};
429    }
430
431    # In this mode, we check if the config file has been modified
432    return q{time() > $Log::Log4perl::Config::Watch::NEXT_CHECK_TIME
433              and $Log::Log4perl::Config::WATCHER->change_detected()};
434
435}
436
437##################################################
438sub parent_string {
439##################################################
440    my($string) = @_;
441
442    if($string eq "") {
443        return undef; # root doesn't have a parent.
444    }
445
446    my @components = split /\./, $string;
447
448    if(@components == 1) {
449        return "";
450    }
451
452    pop @components;
453
454    return join('.', @components);
455}
456
457##################################################
458sub level {
459##################################################
460    my($self, $level, $dont_reset_all) = @_;
461
462        # 'Set' function
463    if(defined $level) {
464        croak "invalid level '$level'"
465                unless Log::Log4perl::Level::is_valid($level);
466        if ($level =~ /\D/){
467            $level = Log::Log4perl::Level::to_priority($level);
468        }
469        $self->{level} = $level;
470
471        &reset_all_output_methods
472            unless $dont_reset_all;  #keep us from getting overworked
473                                     #if it's the config file calling us
474
475        return $level;
476    }
477
478        # 'Get' function
479    if(defined $self->{level}) {
480        return $self->{level};
481    }
482
483    for(my $logger = $self; $logger; $logger = parent_logger($logger)) {
484
485        # Does the current logger have the level defined?
486
487        if($logger->{category} eq "") {
488            # It's the root logger
489            return $ROOT_LOGGER->{level};
490        }
491
492        if(defined $LOGGERS_BY_NAME->{$logger->{category}}->{level}) {
493            return $LOGGERS_BY_NAME->{$logger->{category}}->{level};
494        }
495    }
496
497    # We should never get here because at least the root logger should
498    # have a level defined
499    die "We should never get here.";
500}
501
502##################################################
503sub parent_logger {
504# Get the parent of the current logger or undef
505##################################################
506    my($logger) = @_;
507
508        # Is it the root logger?
509    if($logger->{category} eq "") {
510        # Root has no parent
511        return undef;
512    }
513
514        # Go to the next defined (!) parent
515    my $parent_class = parent_string($logger->{category});
516
517    while($parent_class ne "" and
518          ! exists $LOGGERS_BY_NAME->{$parent_class}) {
519        $parent_class = parent_string($parent_class);
520        $logger =  $LOGGERS_BY_NAME->{$parent_class};
521    }
522
523    if($parent_class eq "") {
524        $logger = $ROOT_LOGGER;
525    } else {
526        $logger = $LOGGERS_BY_NAME->{$parent_class};
527    }
528
529    return $logger;
530}
531
532##################################################
533sub get_root_logger {
534##################################################
535    my($class) = @_;
536    return $ROOT_LOGGER;
537}
538
539##################################################
540sub additivity {
541##################################################
542    my($self, $onoff) = @_;
543
544    if(defined $onoff) {
545        $self->{additivity} = $onoff;
546    }
547
548    return $self->{additivity};
549}
550
551##################################################
552sub get_logger {
553##################################################
554    my($class, $category) = @_;
555
556    unless(defined $ROOT_LOGGER) {
557        die "Internal error: Root Logger not initialized.";
558    }
559
560    return $ROOT_LOGGER if $category eq "";
561
562    my $logger = $class->_new($category);
563    return $logger;
564}
565
566##################################################
567sub add_appender {
568##################################################
569    my($self, $appender, $dont_reset_all) = @_;
570
571    my $not_to_dispatcher = 0;
572
573        # We take this as an indicator that we're initialized.
574    $INITIALIZED = 1;
575
576    my $appender_name = $appender->name();
577
578    $self->{num_appenders}++;  #should this be inside the unless?
579
580    unless (grep{$_ eq $appender_name} @{$self->{appender_names}}){
581        $self->{appender_names} = [sort @{$self->{appender_names}},
582                                        $appender_name];
583    }
584
585    if ($APPENDER_BY_NAME{$appender_name}) {
586        $not_to_dispatcher = 1;
587    }else{
588        $APPENDER_BY_NAME{$appender_name} = $appender;
589    }
590
591    &reset_all_output_methods
592                unless $dont_reset_all;  # keep us from getting overworked
593                                         # if it's  the config file calling us
594
595        # For chaining calls ...
596    return $appender;
597}
598
599##################################################
600sub remove_appender {
601##################################################
602    my($self, $appender_name, $dont_reset_all, $sloppy) = @_;
603
604    my %appender_names = map { $_ => 1 } @{$self->{appender_names}};
605
606    if(!exists $appender_names{$appender_name}) {
607        die "No such appender: $appender_name" unless $sloppy;
608        return undef;
609    }
610
611    delete $appender_names{$appender_name};
612    $self->{num_appenders}--;
613    $self->{appender_names} = [sort keys %appender_names];
614
615    &reset_all_output_methods
616                unless $dont_reset_all;
617}
618
619##################################################
620sub eradicate_appender {
621##################################################
622        # If someone calls Logger->... and not Logger::...
623    shift if $_[0] eq __PACKAGE__;
624
625    my($appender_name, $dont_reset_all) = @_;
626
627    return 0 unless exists
628        $APPENDER_BY_NAME{$appender_name};
629
630        # Remove the given appender from all loggers
631        # and delete all references to it, causing
632        # its DESTROY method to be called.
633    foreach my $logger (values %$LOGGERS_BY_NAME){
634        $logger->remove_appender($appender_name, 0, 1);
635    }
636        # Also remove it from the root logger
637    $ROOT_LOGGER->remove_appender($appender_name, 0, 1);
638
639    delete $APPENDER_BY_NAME{$appender_name};
640
641    &reset_all_output_methods
642                unless $dont_reset_all;
643
644    return 1;
645}
646
647##################################################
648sub has_appenders {
649##################################################
650    my($self) = @_;
651
652    return $self->{num_appenders};
653}
654
655##################################################
656sub log {
657# external api
658##################################################
659    my ($self, $priority, @messages) = @_;
660
661    confess("log: No priority given!") unless defined($priority);
662
663       # Just in case of 'init_and_watch' -- see Changes 0.21
664    $_[0] = $LOGGERS_BY_NAME->{$_[0]->{category}} if
665        defined $Log::Log4perl::Config::WATCHER;
666
667    init_warn() unless $INITIALIZED or $NON_INIT_WARNED;
668
669    croak "priority $priority isn't numeric" if ($priority =~ /\D/);
670
671    my $which = Log::Log4perl::Level::to_level($priority);
672
673    $self->{$which}->($self, @messages,
674                    Log::Log4perl::Level::to_level($priority));
675}
676
677######################################################################
678#
679# create_custom_level
680# creates a custom level
681# in theory, could be used to create the default ones
682######################################################################
683sub create_custom_level {
684######################################################################
685  my $level = shift || die("create_custom_level: " .
686                           "forgot to pass in a level string!");
687  my $after = shift || die("create_custom_level: " .
688                           "forgot to pass in a level after which to " .
689                           "place the new level!");
690  my $syslog_equiv = shift; # can be undef
691
692  ## only let users create custom levels before initialization
693
694  die("create_custom_level must be called before init or " .
695      "first get_logger() call") if ($INITIALIZED);
696
697  my %PRIORITY = %Log::Log4perl::Level::PRIORITY; #convenience
698
699  die("create_custom_level: no such level \"$after\"! Use one of: ",
700     join(", ", sort keys %PRIORITY)) unless $PRIORITY{$after};
701
702  # figure out new int value by AFTER + (AFTER+ 1) / 2
703
704  my $next_prio = Log::Log4perl::Level::get_lower_level($PRIORITY{$after}, 1);
705  my $cust_prio = int(($PRIORITY{$after} + $next_prio) / 2);
706
707  die(qq{create_custom_level: Calculated level of $cust_prio already exists!
708      This should only happen if you've made some insane number of custom
709      levels (like 15 one after another)
710      You can usually fix this by re-arranging your code from:
711      create_custom_level("cust1", X);
712      create_custom_level("cust2", X);
713      create_custom_level("cust3", X);
714      create_custom_level("cust4", X);
715      create_custom_level("cust5", X);
716      into:
717      create_custom_level("cust3", X);
718      create_custom_level("cust5", X);
719      create_custom_level("cust4", 4);
720      create_custom_level("cust2", cust3);
721      create_custom_level("cust1", cust2);
722   }) if (${Log::Log4perl::Level::LEVELS{$cust_prio}});
723
724  Log::Log4perl::Level::add_priority($level, $cust_prio, $syslog_equiv);
725
726  print("Adding prio $level at $cust_prio\n") if _INTERNAL_DEBUG;
727
728  # get $LEVEL into namespace of Log::Log4perl::Logger to
729  # create $logger->foo nd $logger->is_foo
730  my $name = "Log::Log4perl::Logger::";
731  my $key = $level;
732
733  no strict qw(refs);
734  # be sure to use ${Log...} as CVS adds log entries for Log
735  *{"$name$key"} = \${Log::Log4perl::Level::PRIORITY{$level}};
736
737  # now, stick it in the caller's namespace
738  $name = caller(0) . "::";
739  *{"$name$key"} = \${Log::Log4perl::Level::PRIORITY{$level}};
740  use strict qw(refs);
741
742  create_log_level_methods($level);
743
744  return 0;
745
746}
747
748########################################
749#
750# if we were hackin' lisp (or scheme), we'd be returning some lambda
751# expressions. But we aren't. :) So we'll just create some strings and
752# eval them.
753########################################
754sub create_log_level_methods {
755########################################
756  my $level = shift || die("create_log_level_methods: " .
757                           "forgot to pass in a level string!");
758  my $lclevel = lc($level);
759  my $levelint = uc($level) . "_INT";
760  my $initial_cap = ucfirst($lclevel);
761
762  no strict qw(refs);
763
764  # This is a bit better way to create code on the fly than eval'ing strings.
765  # -erik
766
767  *{__PACKAGE__ . "::$lclevel"} = sub {
768        print "$lclevel: ($_[0]->{category}/$_[0]->{level}) [@_]\n"
769            if _INTERNAL_DEBUG;
770        init_warn() unless $INITIALIZED or $NON_INIT_WARNED;
771        $_[0]->{$level}->(@_, $level) if defined $_[0]->{$level};
772     };
773
774  # Added these to have is_xxx functions as fast as xxx functions
775  # -ms
776
777  *{__PACKAGE__ . "::is_$lclevel"} = sub {
778      $_[0]->{"is_" . $level}->($_[0], "is_" . $lclevel) if
779          defined $_[0]->{$level};
780  };
781
782  # Add the isXxxEnabled() methods as identical to the is_xxx
783  # functions. - dviner
784
785  *{__PACKAGE__ . "::is".$initial_cap."Enabled"} =
786                           \&{__PACKAGE__ . "::is_$lclevel"};
787
788  use strict qw(refs);
789
790  return 0;
791}
792
793#now lets autogenerate the logger subs based on the defined priorities
794foreach my $level (keys %Log::Log4perl::Level::PRIORITY){
795  create_log_level_methods($level);
796}
797
798##################################################
799sub init_warn {
800##################################################
801    CORE::warn "Log4perl: Seems like no initialization happened. " .
802               "Forgot to call init()?\n";
803    # Only tell this once;
804    $NON_INIT_WARNED = 1;
805}
806
807#######################################################
808# call me from a sub-func to spew the sub-func's caller
809#######################################################
810sub callerline {
811  # the below could all be just:
812  # my ($pack, $file, $line) = caller(2);
813  # but if we every bury this further, it'll break. So we do this
814  # little trick stolen and paraphrased from Carp/Heavy.pm
815  my($message) = @_;
816
817  my $i = 0;
818  my (undef, $localfile, undef) = caller($i++);
819  my ($pack, $file, $line);
820  do {
821    ($pack, $file, $line) = caller($i++);
822  } while ($file && $file eq $localfile);
823
824  my $has_newline;
825
826  $has_newline++ if chomp $message;
827
828  $message .= " at $file line $line" if !$has_newline;
829
830  # Someday, we'll use Threads. Really.
831  if (defined &Thread::tid) {
832    my $tid = Thread->self->tid;
833    $message .= " thread $tid" if $tid and !$has_newline;
834  }
835  return ($message, "\n");
836}
837
838#######################################################
839sub and_warn {
840#######################################################
841  my $self = shift;
842  my $msg = join("", @_[0 .. $#_]);
843  CORE::warn(callerline($self->warning_render(@_[0 .. $#_])));
844}
845
846#######################################################
847sub and_die {
848#######################################################
849  my $self = shift;
850  die(callerline($self->warning_render(@_[0 .. $#_])));
851}
852
853##################################################
854sub logwarn {
855##################################################
856  my $self = shift;
857  if ($self->is_warn()) {
858        # Since we're one caller level off now, compensate for that.
859    $Log::Log4perl::caller_depth++;
860    my @chomped = @_;
861    chomp($chomped[-1]);
862    $self->warn(@chomped);
863    $Log::Log4perl::caller_depth--;
864    $self->and_warn(@_);
865  }
866}
867
868##################################################
869sub logdie {
870##################################################
871  my $self = shift;
872  if ($self->is_fatal()) {
873        # Since we're one caller level off now, compensate for that.
874    $Log::Log4perl::caller_depth++;
875    my @chomped = @_;
876    chomp($chomped[-1]);
877    $self->fatal(@chomped);
878    $Log::Log4perl::caller_depth--;
879  }
880
881  $Log::Log4perl::LOGDIE_MESSAGE_ON_STDERR ?
882      $self->and_die(@_) :
883        exit($Log::Log4perl::LOGEXIT_CODE);
884}
885
886##################################################
887sub logexit {
888##################################################
889  my $self = shift;
890
891  if ($self->is_fatal()) {
892        # Since we're one caller level off now, compensate for that.
893    $Log::Log4perl::caller_depth++;
894    my @chomped = @_;
895    chomp($chomped[-1]);
896    $self->fatal(@chomped);
897    $Log::Log4perl::caller_depth--;
898  }
899
900  exit $Log::Log4perl::LOGEXIT_CODE;
901}
902
903##################################################
904# clucks and carps are WARN level
905sub logcluck {
906##################################################
907  my $self = shift;
908
909  local $Carp::CarpLevel = $Carp::CarpLevel + 1;
910  my $msg = $self->warning_render(@_);
911
912  if ($self->is_warn()) {
913    my $message = Carp::longmess($msg);
914    local $Log::Log4perl::caller_depth =
915          $Log::Log4perl::caller_depth + 1;
916    foreach (split(/\n/, $message)) {
917      $self->warn("$_\n");
918    }
919    Carp::cluck($msg);
920  }
921}
922
923##################################################
924sub logcarp {
925##################################################
926  my $self = shift;
927
928  local $Carp::CarpLevel = $Carp::CarpLevel + 1;
929  my $msg = $self->warning_render(@_);
930
931  if ($self->is_warn()) {
932    my $message = Carp::shortmess($msg);
933    local $Log::Log4perl::caller_depth =
934          $Log::Log4perl::caller_depth + 1;
935    foreach (split(/\n/, $message)) {
936      $self->warn("$_\n");
937    }
938    Carp::carp($msg) if $Log::Log4perl::LOGDIE_MESSAGE_ON_STDERR;
939  }
940}
941
942##################################################
943# croaks and confess are FATAL level
944##################################################
945sub logcroak {
946##################################################
947  my $self = shift;
948
949  local $Carp::CarpLevel = $Carp::CarpLevel + 1;
950  my $msg = $self->warning_render(@_);
951
952  my $message = Carp::shortmess($msg);
953  local $Log::Log4perl::caller_depth =
954        $Log::Log4perl::caller_depth + 1;
955  if ($self->is_fatal()) {
956    foreach (split(/\n/, $message)) {
957      $self->fatal("$_\n");
958    }
959  }
960
961  $Log::Log4perl::LOGDIE_MESSAGE_ON_STDERR ?
962      Carp::croak($msg) :
963        exit($Log::Log4perl::LOGEXIT_CODE);
964}
965
966##################################################
967sub logconfess {
968##################################################
969  my $self = shift;
970
971  my $msg = $self->warning_render(@_);
972  local $Carp::CarpLevel = $Carp::CarpLevel + 1;
973
974  my $message = Carp::longmess($msg);
975  local $Log::Log4perl::caller_depth =
976        $Log::Log4perl::caller_depth + 1;
977  if ($self->is_fatal()) {
978    foreach (split(/\n/, $message)) {
979      $self->fatal("$_\n");
980    }
981  }
982
983  $Log::Log4perl::LOGDIE_MESSAGE_ON_STDERR ?
984      confess($msg) :
985        exit($Log::Log4perl::LOGEXIT_CODE);
986}
987
988##################################################
989# in case people prefer to use error for warning
990##################################################
991sub error_warn {
992##################################################
993  my $self = shift;
994  if ($self->is_error()) {
995    $Log::Log4perl::caller_depth++;
996    $self->error(@_);
997    $Log::Log4perl::caller_depth--;
998    $self->and_warn(@_);
999  }
1000}
1001
1002##################################################
1003sub error_die {
1004##################################################
1005  my $self = shift;
1006
1007  my $msg = $self->warning_render(@_);
1008
1009  if ($self->is_error()) {
1010    $Log::Log4perl::caller_depth++;
1011    $self->error($msg);
1012    $Log::Log4perl::caller_depth--;
1013  }
1014
1015  $Log::Log4perl::LOGDIE_MESSAGE_ON_STDERR ?
1016      $self->and_die($msg) :
1017        exit($Log::Log4perl::LOGEXIT_CODE);
1018}
1019
1020##################################################
1021sub more_logging {
1022##################################################
1023  my ($self) = shift;
1024  return $self->dec_level(@_);
1025}
1026
1027##################################################
1028sub inc_level {
1029##################################################
1030    my ($self, $delta) = @_;
1031
1032    $delta ||= 1;
1033
1034    $self->level(Log::Log4perl::Level::get_higher_level($self->level(),
1035                                                        $delta));
1036
1037    $self->set_output_methods;
1038}
1039
1040##################################################
1041sub less_logging {
1042##################################################
1043  my ($self) = shift;
1044  return $self->inc_level(@_);
1045}
1046
1047##################################################
1048sub dec_level {
1049##################################################
1050    my ($self, $delta) = @_;
1051
1052    $delta ||= 1;
1053
1054    $self->level(Log::Log4perl::Level::get_lower_level($self->level(), $delta));
1055
1056    $self->set_output_methods;
1057}
1058
1059##################################################
1060
10611;
1062
1063__END__
1064
1065=head1 NAME
1066
1067Log::Log4perl::Logger - Main Logger Class
1068
1069=head1 SYNOPSIS
1070
1071    # It's not here
1072
1073=head1 DESCRIPTION
1074
1075While everything that makes Log4perl tick is implemented here,
1076please refer to L<Log::Log4perl> for documentation.
1077
1078=head1 SEE ALSO
1079
1080=head1 AUTHOR
1081
1082    Mike Schilli, <log4perl@perlmeister.com>
1083    Kevin Goess, <cpan@goess.org>
1084
1085=cut
1086