diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2014-11-01 01:47:12 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2014-11-01 01:47:12 +0000 |
commit | 94566f012421026c8311552f99175a5989eba063 (patch) | |
tree | 0bfd47111b94a1715d14b8c4ab2d82ad1abc09b1 /lib/Log/Log4perl/Logger.pm | |
download | Log-Log4perl-tarball-master.tar.gz |
Log-Log4perl-1.46HEADLog-Log4perl-1.46master
Diffstat (limited to 'lib/Log/Log4perl/Logger.pm')
-rw-r--r-- | lib/Log/Log4perl/Logger.pm | 1165 |
1 files changed, 1165 insertions, 0 deletions
diff --git a/lib/Log/Log4perl/Logger.pm b/lib/Log/Log4perl/Logger.pm new file mode 100644 index 0000000..682c689 --- /dev/null +++ b/lib/Log/Log4perl/Logger.pm @@ -0,0 +1,1165 @@ +################################################## +package Log::Log4perl::Logger; +################################################## + +use 5.006; +use strict; +use warnings; + +use Log::Log4perl; +use Log::Log4perl::Level; +use Log::Log4perl::Layout; +use Log::Log4perl::Appender; +use Log::Log4perl::Appender::String; +use Log::Log4perl::Filter; +use Carp; + +$Carp::Internal{"Log::Log4perl"}++; +$Carp::Internal{"Log::Log4perl::Logger"}++; + +use constant _INTERNAL_DEBUG => 0; + + # Initialization +our $ROOT_LOGGER; +our $LOGGERS_BY_NAME = {}; +our %APPENDER_BY_NAME = (); +our $INITIALIZED = 0; +our $NON_INIT_WARNED; +our $DIE_DEBUG = 0; +our $DIE_DEBUG_BUFFER = ""; + # Define the default appender that's used for formatting + # warn/die/croak etc. messages. +our $STRING_APP_NAME = "_l4p_warn"; +our $STRING_APP = Log::Log4perl::Appender->new( + "Log::Log4perl::Appender::String", + name => $STRING_APP_NAME); +$STRING_APP->layout(Log::Log4perl::Layout::PatternLayout->new("%m")); +our $STRING_APP_CODEREF = generate_coderef([[$STRING_APP_NAME, $STRING_APP]]); + +__PACKAGE__->reset(); + +########################################### +sub warning_render { +########################################### + my($logger, @message) = @_; + + $STRING_APP->string(""); + $STRING_APP_CODEREF->($logger, + @message, + Log::Log4perl::Level::to_level($ALL)); + return $STRING_APP->string(); +} + +################################################## +sub cleanup { +################################################## + # warn "Logger cleanup"; + + # Nuke all convenience loggers to avoid them causing cleanup to + # be delayed until global destruction. Problem is that something like + # *{"DEBUG"} = sub { $logger->debug }; + # ties up a reference to $logger until global destruction, so we + # need to clean up all :easy shortcuts, hence freeing the last + # logger references, to then rely on the garbage collector for cleaning + # up the loggers. + Log::Log4perl->easy_closure_global_cleanup(); + + # Delete all loggers + $LOGGERS_BY_NAME = {}; + + # Delete the root logger + undef $ROOT_LOGGER; + + # Delete all appenders + %APPENDER_BY_NAME = (); + + undef $INITIALIZED; +} + +################################################## +sub DESTROY { +################################################## + CORE::warn "Destroying logger $_[0] ($_[0]->{category})" + if $Log::Log4perl::CHATTY_DESTROY_METHODS; +} + +################################################## +sub reset { +################################################## + $ROOT_LOGGER = __PACKAGE__->_new("", $OFF); +# $LOGGERS_BY_NAME = {}; #leave this alone, it's used by + #reset_all_output_methods when + #the config changes + + %APPENDER_BY_NAME = (); + undef $INITIALIZED; + undef $NON_INIT_WARNED; + Log::Log4perl::Appender::reset(); + + #clear out all the existing appenders + foreach my $logger (values %$LOGGERS_BY_NAME){ + $logger->{appender_names} = []; + + #this next bit deals with an init_and_watch case where a category + #is deleted from the config file, we need to zero out the existing + #loggers so ones not in the config file not continue with their old + #behavior --kg + next if $logger eq $ROOT_LOGGER; + $logger->{level} = undef; + $logger->level(); #set it from the hierarchy + } + + # Clear all filters + Log::Log4perl::Filter::reset(); +} + +################################################## +sub _new { +################################################## + my($class, $category, $level) = @_; + + print("_new: $class/$category/", defined $level ? $level : "undef", + "\n") if _INTERNAL_DEBUG; + + die "usage: __PACKAGE__->_new(category)" unless + defined $category; + + $category =~ s/::/./g; + + # Have we created it previously? + if(exists $LOGGERS_BY_NAME->{$category}) { + print "_new: exists already\n" if _INTERNAL_DEBUG; + return $LOGGERS_BY_NAME->{$category}; + } + + my $self = { + category => $category, + num_appenders => 0, + additivity => 1, + level => $level, + layout => undef, + }; + + bless $self, $class; + + $level ||= $self->level(); + + # Save it in global structure + $LOGGERS_BY_NAME->{$category} = $self; + + $self->set_output_methods; + + print("Created logger $self ($category)\n") if _INTERNAL_DEBUG; + + return $self; +} + +################################################## +sub category { +################################################## + my ($self) = @_; + + return $self->{ category }; +} + +################################################## +sub reset_all_output_methods { +################################################## + print "reset_all_output_methods: \n" if _INTERNAL_DEBUG; + + foreach my $loggername ( keys %$LOGGERS_BY_NAME){ + $LOGGERS_BY_NAME->{$loggername}->set_output_methods; + } + $ROOT_LOGGER->set_output_methods; +} + +################################################## +sub set_output_methods { +# Here's a big performance increase. Instead of having the logger +# calculate whether to log and whom to log to every time log() is called, +# we calculate it once when the logger is created, and recalculate +# it if the config information ever changes. +# +################################################## + my ($self) = @_; + + my (@appenders, %seen); + + my ($level) = $self->level(); + + print "set_output_methods: $self->{category}/$level\n" if _INTERNAL_DEBUG; + + #collect the appenders in effect for this category + + for(my $logger = $self; $logger; $logger = parent_logger($logger)) { + + foreach my $appender_name (@{$logger->{appender_names}}){ + + #only one message per appender, (configurable) + next if $seen{$appender_name} ++ && + $Log::Log4perl::one_message_per_appender; + + push (@appenders, + [$appender_name, + $APPENDER_BY_NAME{$appender_name}, + ] + ); + } + last unless $logger->{additivity}; + } + + #make a no-op coderef for inactive levels + my $noop = generate_noop_coderef(); + + #make a coderef + my $coderef = (! @appenders ? $noop : &generate_coderef(\@appenders)); + + my %priority = %Log::Log4perl::Level::PRIORITY; #convenience and cvs + + # changed to >= from <= as level ints were reversed + foreach my $levelname (keys %priority){ + if (Log::Log4perl::Level::isGreaterOrEqual($level, + $priority{$levelname} + )) { + print " ($priority{$levelname} <= $level)\n" + if _INTERNAL_DEBUG; + $self->{$levelname} = $coderef; + $self->{"is_$levelname"} = generate_is_xxx_coderef("1"); + print "Setting is_$levelname to 1\n" if _INTERNAL_DEBUG; + }else{ + print " ($priority{$levelname} > $level)\n" if _INTERNAL_DEBUG; + $self->{$levelname} = $noop; + $self->{"is_$levelname"} = generate_is_xxx_coderef("0"); + print "Setting is_$levelname to 0\n" if _INTERNAL_DEBUG; + } + + print(" Setting [$self] $self->{category}.$levelname to ", + ($self->{$levelname} == $noop ? "NOOP" : + ("Coderef [$coderef]: " . scalar @appenders . " appenders")), + "\n") if _INTERNAL_DEBUG; + } +} + +################################################## +sub generate_coderef { +################################################## + my $appenders = shift; + + print "generate_coderef: ", scalar @$appenders, + " appenders\n" if _INTERNAL_DEBUG; + + my $watch_check_code = generate_watch_code("logger", 1); + + return sub { + my $logger = shift; + my $level = pop; + + my $message; + my $appenders_fired = 0; + + # Evaluate all parameters that need to be evaluated. Two kinds: + # + # (1) It's a hash like { filter => "filtername", + # value => "value" } + # => filtername(value) + # + # (2) It's a code ref + # => coderef() + # + + $message = [map { ref $_ eq "HASH" && + exists $_->{filter} && + ref $_->{filter} eq 'CODE' ? + $_->{filter}->($_->{value}) : + ref $_ eq "CODE" ? + $_->() : $_ + } @_]; + + print("coderef: $logger->{category}\n") if _INTERNAL_DEBUG; + + if(defined $Log::Log4perl::Config::WATCHER) { + return unless $watch_check_code->($logger, @_, $level); + } + + foreach my $a (@$appenders) { #note the closure here + my ($appender_name, $appender) = @$a; + + print(" Sending message '<$message->[0]>' ($level) " . + "to $appender_name\n") if _INTERNAL_DEBUG; + + $appender->log( + #these get passed through to Log::Dispatch + { name => $appender_name, + level => $Log::Log4perl::Level::L4P_TO_LD{ + $level}, + message => $message, + }, + #these we need + $logger->{category}, + $level, + ) and $appenders_fired++; + # Only counting it if it returns a true value. Otherwise + # the appender threshold might have suppressed it after all. + + } #end foreach appenders + + return $appenders_fired; + + }; #end coderef +} + +################################################## +sub generate_noop_coderef { +################################################## + my $watch_delay_code; + + # This might seem crazy at first, but even in a Log4perl noop, we + # need to check if the configuration changed in a init_and_watch + # situation. Why? Say, an application is running in a loop that + # constantly tries to issue debug() messages, but they're suppressed by + # the current Log4perl configuration. If debug() (which is a noop + # here) wasn't watching the configuration for changes, it would never + # catch the case where someone bumps up the log level and expects + # the application to pick it up and start logging debug() statements. + + my $watch_check_code = generate_watch_code("logger", 1); + + my $coderef; + + if(defined $Log::Log4perl::Config::WATCHER) { + $coderef = $watch_check_code; + } else { + $coderef = sub { undef }; + } + + return $coderef; +} + +################################################## +sub generate_is_xxx_coderef { +################################################## + my($return_token) = @_; + + return generate_watch_code("checker", $return_token); +} + +################################################## +sub generate_watch_code { +################################################## + my($type, $return_token) = @_; + + print "generate_watch_code:\n" if _INTERNAL_DEBUG; + + # No watcher configured, return a no-op as watch code. + if(! defined $Log::Log4perl::Config::WATCHER) { + return sub { $return_token }; + } + + my $cond = generate_watch_conditional(); + + return sub { + print "exe_watch_code:\n" if _INTERNAL_DEBUG; + + if(_INTERNAL_DEBUG) { + print "Next check: ", + "$Log::Log4perl::Config::Watch::NEXT_CHECK_TIME ", + " Now: ", time(), " Mod: ", + (stat($Log::Log4perl::Config::WATCHER->file()))[9], + "\n"; + } + + if( $cond->() ) { + my $init_permitted = 1; + + if(exists $Log::Log4perl::Config::OPTS->{ preinit_callback } ) { + print "Calling preinit_callback\n" if _INTERNAL_DEBUG; + $init_permitted = + $Log::Log4perl::Config::OPTS->{ preinit_callback }->( + Log::Log4perl::Config->watcher()->file() ); + print "Callback returned $init_permitted\n" if _INTERNAL_DEBUG; + } + + if( $init_permitted ) { + Log::Log4perl->init_and_watch(); + } else { + # It was time to reinit, but init wasn't permitted. + # Return true, so that the logger continues as if + # it wasn't time to reinit. + return 1; + } + + my $logger = shift; + my $level = pop; + + # Forward call to new configuration + if($type eq "checker") { + return $logger->$level(); + + } elsif( $type eq "logger") { + my $methodname = lc($level); + + # Bump up the caller level by three, since + # we've artificially introduced additional levels. + local $Log::Log4perl::caller_depth = + $Log::Log4perl::caller_depth + 3; + + # Get a new logger for the same category (the old + # logger might be obsolete because of the re-init) + $logger = Log::Log4perl::get_logger( $logger->{category} ); + + $logger->$methodname(@_); # send the message + # to the new configuration + return undef; # Return false, so the logger finishes + # prematurely and doesn't log the same + # message again. + } else { + die "internal error: unknown type"; + } + } else { + if(_INTERNAL_DEBUG) { + print "Conditional returned false\n"; + } + return $return_token; + } + }; +} + +################################################## +sub generate_watch_conditional { +################################################## + + if(defined $Log::Log4perl::Config::Watch::SIGNAL_CAUGHT) { + # In this mode, we just check for the variable indicating + # that the signal has been caught + return sub { + return $Log::Log4perl::Config::Watch::SIGNAL_CAUGHT; + }; + } + + return sub { + return + ( time() > $Log::Log4perl::Config::Watch::NEXT_CHECK_TIME and + $Log::Log4perl::Config::WATCHER->change_detected() ); + }; +} + +################################################## +sub parent_string { +################################################## + my($string) = @_; + + if($string eq "") { + return undef; # root doesn't have a parent. + } + + my @components = split /\./, $string; + + if(@components == 1) { + return ""; + } + + pop @components; + + return join('.', @components); +} + +################################################## +sub level { +################################################## + my($self, $level, $dont_reset_all) = @_; + + # 'Set' function + if(defined $level) { + croak "invalid level '$level'" + unless Log::Log4perl::Level::is_valid($level); + if ($level =~ /\D/){ + $level = Log::Log4perl::Level::to_priority($level); + } + $self->{level} = $level; + + &reset_all_output_methods + unless $dont_reset_all; #keep us from getting overworked + #if it's the config file calling us + + return $level; + } + + # 'Get' function + if(defined $self->{level}) { + return $self->{level}; + } + + for(my $logger = $self; $logger; $logger = parent_logger($logger)) { + + # Does the current logger have the level defined? + + if($logger->{category} eq "") { + # It's the root logger + return $ROOT_LOGGER->{level}; + } + + if(defined $LOGGERS_BY_NAME->{$logger->{category}}->{level}) { + return $LOGGERS_BY_NAME->{$logger->{category}}->{level}; + } + } + + # We should never get here because at least the root logger should + # have a level defined + die "We should never get here."; +} + +################################################## +sub parent_logger { +# Get the parent of the current logger or undef +################################################## + my($logger) = @_; + + # Is it the root logger? + if($logger->{category} eq "") { + # Root has no parent + return undef; + } + + # Go to the next defined (!) parent + my $parent_class = parent_string($logger->{category}); + + while($parent_class ne "" and + ! exists $LOGGERS_BY_NAME->{$parent_class}) { + $parent_class = parent_string($parent_class); + $logger = $LOGGERS_BY_NAME->{$parent_class}; + } + + if($parent_class eq "") { + $logger = $ROOT_LOGGER; + } else { + $logger = $LOGGERS_BY_NAME->{$parent_class}; + } + + return $logger; +} + +################################################## +sub get_root_logger { +################################################## + my($class) = @_; + return $ROOT_LOGGER; +} + +################################################## +sub additivity { +################################################## + my($self, $onoff, $no_reinit) = @_; + + if(defined $onoff) { + $self->{additivity} = $onoff; + } + + if( ! $no_reinit ) { + $self->set_output_methods(); + } + + return $self->{additivity}; +} + +################################################## +sub get_logger { +################################################## + my($class, $category) = @_; + + unless(defined $ROOT_LOGGER) { + Carp::confess "Internal error: Root Logger not initialized."; + } + + return $ROOT_LOGGER if $category eq ""; + + my $logger = $class->_new($category); + return $logger; +} + +################################################## +sub add_appender { +################################################## + my($self, $appender, $dont_reset_all) = @_; + + # We take this as an indicator that we're initialized. + $INITIALIZED = 1; + + my $appender_name = $appender->name(); + + $self->{num_appenders}++; #should this be inside the unless? + + # Add newly created appender to the end of the appender array + unless (grep{$_ eq $appender_name} @{$self->{appender_names}}){ + $self->{appender_names} = [sort @{$self->{appender_names}}, + $appender_name]; + } + + $APPENDER_BY_NAME{$appender_name} = $appender; + + reset_all_output_methods + unless $dont_reset_all; # keep us from getting overworked + # if it's the config file calling us + + # For chaining calls ... + return $appender; +} + +################################################## +sub remove_appender { +################################################## + my($self, $appender_name, $dont_reset_all, $sloppy) = @_; + + my %appender_names = map { $_ => 1 } @{$self->{appender_names}}; + + if(!exists $appender_names{$appender_name}) { + die "No such appender: $appender_name" unless $sloppy; + return undef; + } + + delete $appender_names{$appender_name}; + $self->{num_appenders}--; + $self->{appender_names} = [sort keys %appender_names]; + + &reset_all_output_methods + unless $dont_reset_all; +} + +################################################## +sub eradicate_appender { +################################################## + # If someone calls Logger->... and not Logger::... + shift if $_[0] eq __PACKAGE__; + + my($appender_name, $dont_reset_all) = @_; + + return 0 unless exists + $APPENDER_BY_NAME{$appender_name}; + + # Remove the given appender from all loggers + # and delete all references to it, causing + # its DESTROY method to be called. + foreach my $logger (values %$LOGGERS_BY_NAME){ + $logger->remove_appender($appender_name, 0, 1); + } + # Also remove it from the root logger + $ROOT_LOGGER->remove_appender($appender_name, 0, 1); + + delete $APPENDER_BY_NAME{$appender_name}; + + &reset_all_output_methods + unless $dont_reset_all; + + return 1; +} + +################################################## +sub has_appenders { +################################################## + my($self) = @_; + + return $self->{num_appenders}; +} + +################################################## +sub log { +# external api +################################################## + my ($self, $priority, @messages) = @_; + + confess("log: No priority given!") unless defined($priority); + + # Just in case of 'init_and_watch' -- see Changes 0.21 + $_[0] = $LOGGERS_BY_NAME->{$_[0]->{category}} if + defined $Log::Log4perl::Config::WATCHER; + + init_warn() unless $INITIALIZED or $NON_INIT_WARNED; + + croak "priority $priority isn't numeric" if ($priority =~ /\D/); + + my $which = Log::Log4perl::Level::to_level($priority); + + $self->{$which}->($self, @messages, + Log::Log4perl::Level::to_level($priority)); +} + +###################################################################### +# +# create_custom_level +# creates a custom level +# in theory, could be used to create the default ones +###################################################################### +sub create_custom_level { +###################################################################### + my $level = shift || die("create_custom_level: " . + "forgot to pass in a level string!"); + my $after = shift || die("create_custom_level: " . + "forgot to pass in a level after which to " . + "place the new level!"); + my $syslog_equiv = shift; # can be undef + my $log_dispatch_level = shift; # optional + + ## only let users create custom levels before initialization + + die("create_custom_level must be called before init or " . + "first get_logger() call") if ($INITIALIZED); + + my %PRIORITY = %Log::Log4perl::Level::PRIORITY; #convenience + + die("create_custom_level: no such level \"$after\"! Use one of: ", + join(", ", sort keys %PRIORITY)) unless $PRIORITY{$after}; + + # figure out new int value by AFTER + (AFTER+ 1) / 2 + + my $next_prio = Log::Log4perl::Level::get_lower_level($PRIORITY{$after}, 1); + my $cust_prio = int(($PRIORITY{$after} + $next_prio) / 2); + + die(qq{create_custom_level: Calculated level of $cust_prio already exists! + This should only happen if you've made some insane number of custom + levels (like 15 one after another) + You can usually fix this by re-arranging your code from: + create_custom_level("cust1", X); + create_custom_level("cust2", X); + create_custom_level("cust3", X); + create_custom_level("cust4", X); + create_custom_level("cust5", X); + into: + create_custom_level("cust3", X); + create_custom_level("cust5", X); + create_custom_level("cust4", 4); + create_custom_level("cust2", cust3); + create_custom_level("cust1", cust2); + }) if (${Log::Log4perl::Level::LEVELS{$cust_prio}}); + + Log::Log4perl::Level::add_priority($level, $cust_prio, $syslog_equiv, + $log_dispatch_level); + + print("Adding prio $level at $cust_prio\n") if _INTERNAL_DEBUG; + + # get $LEVEL into namespace of Log::Log4perl::Logger to + # create $logger->foo nd $logger->is_foo + my $name = "Log::Log4perl::Logger::"; + my $key = $level; + + no strict qw(refs); + # be sure to use ${Log...} as CVS adds log entries for Log + *{"$name$key"} = \${Log::Log4perl::Level::PRIORITY{$level}}; + + # now, stick it in the caller's namespace + $name = caller(0) . "::"; + *{"$name$key"} = \${Log::Log4perl::Level::PRIORITY{$level}}; + use strict qw(refs); + + create_log_level_methods($level); + + return 0; + +} + +######################################## +# +# if we were hackin' lisp (or scheme), we'd be returning some lambda +# expressions. But we aren't. :) So we'll just create some strings and +# eval them. +######################################## +sub create_log_level_methods { +######################################## + my $level = shift || die("create_log_level_methods: " . + "forgot to pass in a level string!"); + my $lclevel = lc($level); + my $levelint = uc($level) . "_INT"; + my $initial_cap = ucfirst($lclevel); + + no strict qw(refs); + + # This is a bit better way to create code on the fly than eval'ing strings. + # -erik + + *{__PACKAGE__ . "::$lclevel"} = sub { + if(_INTERNAL_DEBUG) { + my $level_disp = (defined $_[0]->{level} ? $_[0]->{level} + : "[undef]"); + print "$lclevel: ($_[0]->{category}/$level_disp) [@_]\n"; + } + init_warn() unless $INITIALIZED or $NON_INIT_WARNED; + $_[0]->{$level}->(@_, $level) if defined $_[0]->{$level}; + }; + + # Added these to have is_xxx functions as fast as xxx functions + # -ms + + my $islevel = "is_" . $level; + my $islclevel = "is_" . $lclevel; + + *{__PACKAGE__ . "::is_$lclevel"} = sub { + $_[0]->{$islevel}->($_[0], $islclevel); + }; + + # Add the isXxxEnabled() methods as identical to the is_xxx + # functions. - dviner + + *{__PACKAGE__ . "::is".$initial_cap."Enabled"} = + \&{__PACKAGE__ . "::is_$lclevel"}; + + use strict qw(refs); + + return 0; +} + +#now lets autogenerate the logger subs based on the defined priorities +foreach my $level (keys %Log::Log4perl::Level::PRIORITY){ + create_log_level_methods($level); +} + +################################################## +sub init_warn { +################################################## + CORE::warn "Log4perl: Seems like no initialization happened. " . + "Forgot to call init()?\n"; + # Only tell this once; + $NON_INIT_WARNED = 1; +} + +####################################################### +# call me from a sub-func to spew the sub-func's caller +####################################################### +sub callerline { + my $message = join ('', @_); + + my $caller_offset = + Log::Log4perl::caller_depth_offset( + $Log::Log4perl::caller_depth + 1 ); + + my ($pack, $file, $line) = caller($caller_offset); + + if (not chomp $message) { # no newline + $message .= " at $file line $line"; + + # Someday, we'll use Threads. Really. + if (defined &Thread::tid) { + my $tid = Thread->self->tid; + $message .= " thread $tid" if $tid; + } + } + + return ($message, "\n"); +} + +####################################################### +sub and_warn { +####################################################### + my $self = shift; + CORE::warn(callerline($self->warning_render(@_))); +} + +####################################################### +sub and_die { +####################################################### + my $self = shift; + my $arg = $_[0]; + + my($msg) = callerline($self->warning_render(@_)); + + if($DIE_DEBUG) { + $DIE_DEBUG_BUFFER = "DIE_DEBUG: $msg"; + } else { + if( $Log::Log4perl::STRINGIFY_DIE_MESSAGE ) { + die("$msg\n"); + } + die $arg; + } +} + +################################################## +sub logwarn { +################################################## + my $self = shift; + + local $Log::Log4perl::caller_depth = + $Log::Log4perl::caller_depth + 1; + + if ($self->is_warn()) { + # Since we're one caller level off now, compensate for that. + my @chomped = @_; + chomp($chomped[-1]); + $self->warn(@chomped); + } + + $self->and_warn(@_); +} + +################################################## +sub logdie { +################################################## + my $self = shift; + + local $Log::Log4perl::caller_depth = + $Log::Log4perl::caller_depth + 1; + + if ($self->is_fatal()) { + # Since we're one caller level off now, compensate for that. + my @chomped = @_; + chomp($chomped[-1]); + $self->fatal(@chomped); + } + + $Log::Log4perl::LOGDIE_MESSAGE_ON_STDERR ? + $self->and_die(@_) : + exit($Log::Log4perl::LOGEXIT_CODE); +} + +################################################## +sub logexit { +################################################## + my $self = shift; + + local $Log::Log4perl::caller_depth = + $Log::Log4perl::caller_depth + 1; + + if ($self->is_fatal()) { + # Since we're one caller level off now, compensate for that. + my @chomped = @_; + chomp($chomped[-1]); + $self->fatal(@chomped); + } + + exit $Log::Log4perl::LOGEXIT_CODE; +} + +################################################## +# clucks and carps are WARN level +sub logcluck { +################################################## + my $self = shift; + + local $Log::Log4perl::caller_depth = + $Log::Log4perl::caller_depth + 1; + + local $Carp::CarpLevel = + $Carp::CarpLevel + 1; + + my $msg = $self->warning_render(@_); + + if ($self->is_warn()) { + my $message = Carp::longmess($msg); + foreach (split(/\n/, $message)) { + $self->warn("$_\n"); + } + } + + Carp::cluck($msg); +} + +################################################## +sub logcarp { +################################################## + my $self = shift; + + local $Carp::CarpLevel = $Carp::CarpLevel + 1; + + local $Log::Log4perl::caller_depth = + $Log::Log4perl::caller_depth + 1; + + my $msg = $self->warning_render(@_); + + if ($self->is_warn()) { + my $message = Carp::shortmess($msg); + foreach (split(/\n/, $message)) { + $self->warn("$_\n"); + } + } + + Carp::carp($msg); +} + +################################################## +# croaks and confess are FATAL level +################################################## +sub logcroak { +################################################## + my $self = shift; + my $arg = $_[0]; + + my $msg = $self->warning_render(@_); + + local $Carp::CarpLevel = + $Carp::CarpLevel + 1; + + local $Log::Log4perl::caller_depth = + $Log::Log4perl::caller_depth + 1; + + if ($self->is_fatal()) { + my $message = Carp::shortmess($msg); + foreach (split(/\n/, $message)) { + $self->fatal("$_\n"); + } + } + + my $croak_msg = $arg; + + if( $Log::Log4perl::STRINGIFY_DIE_MESSAGE ) { + $croak_msg = $msg; + } + + $Log::Log4perl::LOGDIE_MESSAGE_ON_STDERR ? + Carp::croak($croak_msg) : + exit($Log::Log4perl::LOGEXIT_CODE); +} + +################################################## +sub logconfess { +################################################## + my $self = shift; + my $arg = $_[0]; + + local $Carp::CarpLevel = + $Carp::CarpLevel + 1; + + local $Log::Log4perl::caller_depth = + $Log::Log4perl::caller_depth + 1; + + my $msg = $self->warning_render(@_); + + if ($self->is_fatal()) { + my $message = Carp::longmess($msg); + foreach (split(/\n/, $message)) { + $self->fatal("$_\n"); + } + } + + my $confess_msg = $arg; + + if( $Log::Log4perl::STRINGIFY_DIE_MESSAGE ) { + $confess_msg = $msg; + } + + $Log::Log4perl::LOGDIE_MESSAGE_ON_STDERR ? + confess($confess_msg) : + exit($Log::Log4perl::LOGEXIT_CODE); +} + +################################################## +# in case people prefer to use error for warning +################################################## +sub error_warn { +################################################## + my $self = shift; + + local $Log::Log4perl::caller_depth = + $Log::Log4perl::caller_depth + 1; + + if ($self->is_error()) { + $self->error(@_); + } + + $self->and_warn(@_); +} + +################################################## +sub error_die { +################################################## + my $self = shift; + + local $Log::Log4perl::caller_depth = + $Log::Log4perl::caller_depth + 1; + + my $msg = $self->warning_render(@_); + + if ($self->is_error()) { + $self->error($msg); + } + + $Log::Log4perl::LOGDIE_MESSAGE_ON_STDERR ? + $self->and_die($msg) : + exit($Log::Log4perl::LOGEXIT_CODE); +} + +################################################## +sub more_logging { +################################################## + my ($self) = shift; + return $self->dec_level(@_); +} + +################################################## +sub inc_level { +################################################## + my ($self, $delta) = @_; + + $delta ||= 1; + + $self->level(Log::Log4perl::Level::get_higher_level($self->level(), + $delta)); + + $self->set_output_methods; +} + +################################################## +sub less_logging { +################################################## + my ($self) = shift; + return $self->inc_level(@_); +} + +################################################## +sub dec_level { +################################################## + my ($self, $delta) = @_; + + $delta ||= 1; + + $self->level(Log::Log4perl::Level::get_lower_level($self->level(), $delta)); + + $self->set_output_methods; +} + +1; + +__END__ + +=encoding utf8 + +=head1 NAME + +Log::Log4perl::Logger - Main Logger Class + +=head1 SYNOPSIS + + # It's not here + +=head1 DESCRIPTION + +While everything that makes Log4perl tick is implemented here, +please refer to L<Log::Log4perl> for documentation. + +=head1 LICENSE + +Copyright 2002-2013 by Mike Schilli E<lt>m@perlmeister.comE<gt> +and Kevin Goess E<lt>cpan@goess.orgE<gt>. + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=head1 AUTHOR + +Please contribute patches to the project on Github: + + http://github.com/mschilli/log4perl + +Send bug reports or requests for enhancements to the authors via our + +MAILING LIST (questions, bug reports, suggestions/patches): +log4perl-devel@lists.sourceforge.net + +Authors (please contact them via the list above, not directly): +Mike Schilli <m@perlmeister.com>, +Kevin Goess <cpan@goess.org> + +Contributors (in alphabetical order): +Ateeq Altaf, Cory Bennett, Jens Berthold, Jeremy Bopp, Hutton +Davidson, Chris R. Donnelly, Matisse Enzer, Hugh Esco, Anthony +Foiani, James FitzGibbon, Carl Franks, Dennis Gregorovic, Andy +Grundman, Paul Harrington, Alexander Hartmaier David Hull, +Robert Jacobson, Jason Kohles, Jeff Macdonald, Markus Peter, +Brett Rann, Peter Rabbitson, Erik Selberg, Aaron Straup Cope, +Lars Thegler, David Viner, Mac Yang. + |