Log::Log4perl::Appender - Log appender class
use Log::Log4perl;
# Define a logger my $logger = Log::Log4perl->get_logger("abc.def.ghi");
# Define a layout my $layout = Log::Log4perl::Layout::PatternLayout->new( "%d (%F:%L)> %m");
# Define an appender my $appender = Log::Log4perl::Appender->new( "Log::Log4perl::Appender::Screen", name => 'dumpy');
# Set the appender's layout $appender->layout($layout); $logger->add_appender($appender);
This class is a wrapper around the Log::Log4perl::Appender
appender set.
It also supports the <Log::Dispatch::*> collections of appenders. The
module hides the idiosyncrasies of Log::Dispatch
(e.g. every
dispatcher gotta have a name, but there's no accessor to retrieve it)
from Log::Log4perl
and yet re-uses the extremely useful variety of
dispatchers already created and tested in Log::Dispatch
.
The constructor new()
takes the name of the appender
class to be created as a string (!) argument, optionally followed by
a number of appender-specific parameters,
for example:
# Define an appender my $appender = Log::Log4perl::Appender->new( "Log::Log4perl::Appender::File" file => 'out.log');
In case of Log::Dispatch
appenders,
if no name
parameter is specified, the appender object will create
a unique one (format appNNN
), which can be retrieved later via
the name()
method:
print "The appender's name is ", $appender->name(), "\n";
Other parameters are specific to the appender class being used.
In the case above, the file
parameter specifies the name of
the Log::Log4perl::Appender::File
dispatcher used.
However, if, for instance,
you're using a Log::Dispatch::Email
dispatcher to send you
email, you'll have to specify from
and to
email addresses.
Every dispatcher is different.
Please check the Log::Dispatch::*
documentation for the appender used
for details on specific requirements.
The new()
method will just pass these parameters on to a newly created
Log::Dispatch::*
object of the specified type.
When it comes to logging, the Log::Log4perl::Appender
will transparently
relay all messages to the Log::Dispatch::*
object it carries
in its womb.
The layout()
method sets the log layout
used by the appender to the format specified by the
Log::Log4perl::Layout::*
object which is passed to it as a reference.
Currently there's two layouts available:
Log::Log4perl::Layout::SimpleLayout Log::Log4perl::Layout::PatternLayout
Please check the Log::Log4perl::Layout::SimpleLayout and Log::Log4perl::Layout::PatternLayout manual pages for details.
Here's the list of appender modules currently available via Log::Dispatch
,
if not noted otherwise, written by Dave Rolsky:
Log::Dispatch::ApacheLog Log::Dispatch::DBI (by Tatsuhiko Miyagawa) Log::Dispatch::Email, Log::Dispatch::Email::MailSend, Log::Dispatch::Email::MailSendmail, Log::Dispatch::Email::MIMELite Log::Dispatch::File Log::Dispatch::FileRotate (by Mark Pfeiffer) Log::Dispatch::Handle Log::Dispatch::Screen Log::Dispatch::Syslog Log::Dispatch::Tk (by Dominique Dumont)
Log4perl
doesn't care which ones you use, they're all handled in
the same way via the Log::Log4perl::Appender
interface.
Please check the well-written manual pages of the
Log::Dispatch
hierarchy on how to use each one of them.
When calling the appender's log()-Funktion, Log::Log4perl will submit a list of key/value pairs. Entries to the following keys are guaranteed to be present:
Since the Log::Dispatch::File
appender truncates log files by default,
and most of the time this is not what you want, we've instructed
Log::Log4perl
to change this behaviour by slipping it the
mode => append
parameter behind the scenes. So, effectively
with Log::Log4perl
0.23, a configuration like
log4perl.category = INFO, FileAppndr log4perl.appender.FileAppndr = Log::Dispatch::File log4perl.appender.FileAppndr.filename = test.log log4perl.appender.FileAppndr.layout = Log::Log4perl::Layout::SimpleLayout
will always append to an existing logfile test.log
while if you
specifically request clobbering like in
log4perl.category = INFO, FileAppndr log4perl.appender.FileAppndr = Log::Dispatch::File log4perl.appender.FileAppndr.filename = test.log log4perl.appender.FileAppndr.mode = write log4perl.appender.FileAppndr.layout = Log::Log4perl::Layout::SimpleLayout
it will overwrite an existing log file test.log
and start from scratch.
Instead of simple strings, certain appenders are expecting multiple fields as log messages. If a statement like
$logger->debug($ip, $user, "signed in");
causes an off-the-shelf Log::Log4perl::Screen
appender to fire, the appender will
just concatenate the three message chunks passed to it
in order to form a single string.
The chunks will be separated by a string defined in
$Log::Log4perl::JOIN_MSG_ARRAY_CHAR
(defaults to the empty string
"").
However, different appenders might choose to
interpret the message above differently: An
appender like Log::Log4perl::Appender::DBI
might take the
three arguments passed to the logger and put them in three separate
rows into the DB.
The warp_message
appender option is used to specify the desired
behaviour.
If no setting for the appender property
# *** Not defined *** # log4perl.appender.SomeApp.warp_message
is defined in the Log4perl configuration file, the
appender referenced by SomeApp
will fall back to the standard behaviour
and join all message chunks together, separating them by
$Log::Log4perl::JOIN_MSG_ARRAY_CHAR
.
If, on the other hand, it is set to a false value, like in
log4perl.appender.SomeApp.layout=NoopLayout log4perl.appender.SomeApp.warp_message = 0
then the message chunks are passed unmodified to the appender as an
array reference. Please note that you need to set the appender's
layout to Log::Log4perl::Layout::NoopLayout
which just leaves
the messages chunks alone instead of formatting them or replacing
conversion specifiers.
Please note that the standard appenders in the Log::Dispatch hierarchy
will choke on a bunch of messages passed to them as an array reference.
You can't use warp_message = 0
(or the function name syntax
defined below) on them.
Only special appenders like Log::Log4perl::Appender::DBI can deal with
this.
If (and now we're getting fancy)
an appender expects message chunks, but we would
like to pre-inspect and probably modify them before they're
actually passed to the appender's log
method, an inspection subroutine can be defined with the
appender's warp_message
property:
log4perl.appender.SomeApp.layout=NoopLayout log4perl.appender.SomeApp.warp_message = sub { \ $#_ = 2 if @_ > 3; \ return @_; }
The inspection subroutine defined by the warp_message
property will receive the list of message chunks, like they were
passed to the logger and is expected to return a corrected list.
The example above simply limits the argument list to a maximum of
three by cutting off excess elements and returning the shortened list.
Also, the warp function can be specified by name like in
log4perl.appender.SomeApp.layout=NoopLayout log4perl.appender.SomeApp.warp_message = main::filter_my_message
In this example,
filter_my_message
is a function in the main
package,
defined like this:
my $COUNTER = 0;
sub filter_my_message { my @chunks = @_; unshift @chunks, ++$COUNTER; return @chunks; }
The subroutine above will add an ever increasing counter
as an additional first field to
every message passed to the SomeApp
appender -- but not to
any other appender in the system.
Log::Dispatch
Mike Schilli, <log4perl@perlmeister.com>