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".

Log::Log4perl::Appender->new($dispatcher_class_name, ...);
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.

$appender->layout($layout);
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: Text of the rendered message Name of the category of the logger that triggered the event. Log::Log4perl level of the event 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>