AnyEvent
view release on metacpan or search on metacpan
lib/AnyEvent/Log.pm view on Meta::CPAN
# now get raw message, unless we have it already
unless ($now) {
$format = $format->() if ref $format;
$format = sprintf $format, @args if @args;
$format =~ s/\n$//;
$now = _ts;
};
# format msg
my $str = $ctx->[4]
? $ctx->[4]($now, $_[0], $level, $format)
: ($fmt[$level] ||= default_format $now, $_[0], $level, $format);
$success = 1;
$ctx->[3]($str)
or push @ctx, values %{ $ctx->[2] }; # not consumed - propagate
} else {
push @ctx, values %{ $ctx->[2] }; # not masked - propagate
}
}
}
while $ctx = pop @ctx;
fatal_exit if $level <= 1;
$success
}
sub log($$;@) {
_log
$CTX{ (caller)[0] } ||= _pkg_ctx +(caller)[0],
@_;
}
=item $logger = AnyEvent::Log::logger $level[, \$enabled]
Creates a code reference that, when called, acts as if the
C<AnyEvent::Log::log> function was called at this point with the given
level. C<$logger> is passed a C<$msg> and optional C<@args>, just as with
the C<AnyEvent::Log::log> function:
my $debug_log = AnyEvent::Log::logger "debug";
$debug_log->("debug here");
$debug_log->("%06d emails processed", 12345);
$debug_log->(sub { $obj->as_string });
The idea behind this function is to decide whether to log before actually
logging - when the C<logger> function is called once, but the returned
logger callback often, then this can be a tremendous speed win.
Despite this speed advantage, changes in logging configuration will
still be reflected by the logger callback, even if configuration changes
I<after> it was created.
To further speed up logging, you can bind a scalar variable to the logger,
which contains true if the logger should be called or not - if it is
false, calling the logger can be safely skipped. This variable will be
updated as long as C<$logger> is alive.
Full example:
# near the init section
use AnyEvent::Log;
my $debug_log = AnyEvent:Log::logger debug => \my $debug;
# and later in your program
$debug_log->("yo, stuff here") if $debug;
$debug and $debug_log->("123");
=cut
our %LOGGER;
# re-assess logging status for all loggers
sub _reassess {
local $SIG{__DIE__};
my $die = sub { die };
for (@_ ? $LOGGER{$_[0]} : values %LOGGER) {
my ($ctx, $level, $renabled) = @$_;
# to detect whether a message would be logged, we actually
# try to log one and die. this isn't fast, but we can be
# sure that the logging decision is correct :)
$$renabled = !eval {
_log $ctx, $level, $die;
1
};
}
}
sub _logger {
my ($ctx, $level, $renabled) = @_;
$$renabled = 1;
my $logger = [$ctx, $level, $renabled];
$LOGGER{$logger+0} = $logger;
_reassess $logger+0;
require AnyEvent::Util unless $AnyEvent::Util::VERSION;
my $guard = AnyEvent::Util::guard (sub {
# "clean up"
delete $LOGGER{$logger+0};
});
sub {
$guard if 0; # keep guard alive, but don't cause runtime overhead
_log $ctx, $level, @_
if $$renabled;
}
( run in 0.513 second using v1.01-cache-2.11-cpan-39bf76dae61 )