AnyEvent
view release on metacpan or search on metacpan
lib/AnyEvent/Log.pm view on Meta::CPAN
# level cap
if ($ctx->[5] > $level) {
push @ctx, $level; # restore level when going up in tree
$level = $ctx->[5];
}
# log if log cb
if ($ctx->[3]) {
# logging target found
local ($!, $@);
# 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;
}
}
sub logger($;$) {
_logger
$CTX{ (caller)[0] } ||= _pkg_ctx +(caller)[0],
@_
}
=item AnyEvent::Log::exact_time $on
By default, C<AnyEvent::Log> will use C<AE::now>, i.e. the cached
eventloop time, for the log timestamps. After calling this function with a
true value it will instead resort to C<AE::time>, i.e. fetch the current
time on each log message. This only makes a difference for event loops
that actually cache the time (such as L<EV> or L<AnyEvent::Loop>).
This setting can be changed at any time by calling this function.
Since C<AnyEvent::Log> has to work even before the L<AnyEvent> has been
initialised, this switch will also decide whether to use C<CORE::time> or
C<Time::HiRes::time> when logging a message before L<AnyEvent> becomes
available.
=item AnyEvent::Log::format_time $timestamp
Formats a timestamp as returned by C<< AnyEvent->now >> or C<<
AnyEvent->time >> or many other functions in the same way as
C<AnyEvent::Log> does.
In your main program (as opposed to in your module) you can override
the default timestamp display format by loading this module and then
redefining this function.
Most commonly, this function can be used in formatting callbacks.
=item AnyEvent::Log::default_format $time, $ctx, $level, $msg
Format a log message using the given timestamp, logging context, log level
and log message.
This is the formatting function used to format messages when no custom
function is provided.
In your main program (as opposed to in your module) you can override the
default message format by loading this module and then redefining this
function.
=item AnyEvent::Log::fatal_exit()
This is the function that is called after logging a C<fatal> log
message. It must not return.
The default implementation simply calls C<exit 1>.
In your main program (as opposed to in your module) you can override
the fatal exit function by loading this module and then redefining this
function. Make sure you don't return.
=back
=head1 LOGGING CONTEXTS
This module associates every log message with a so-called I<logging
context>, based on the package of the caller. Every perl package has its
own logging context.
A logging context has three major responsibilities: filtering, logging and
propagating the message.
For the first purpose, filtering, each context has a set of logging
levels, called the log level mask. Messages not in the set will be ignored
by this context (masked).
For logging, the context stores a formatting callback (which takes the
timestamp, context, level and string message and formats it in the way
it should be logged) and a logging callback (which is responsible for
actually logging the formatted message and telling C<AnyEvent::Log>
whether it has consumed the message, or whether it should be propagated).
For propagation, a context can have any number of attached I<slave
( run in 1.460 second using v1.01-cache-2.11-cpan-39bf76dae61 )