use Log::Log4perl qw(:easy); my $conf = qq( log4perl.category = WARN, Syncer # File appender (unsynchronized) log4perl.appender.Logfile = Log::Log4perl::Appender::File log4perl.appender.Logfile.autoflush = 1 log4perl.appender.Logfile.filename = test.log log4perl.appender.Logfile.mode = truncate log4perl.appender.Logfile.layout = SimpleLayout # Synchronizing appender, using the file appender above log4perl.appender.Syncer = Log::Log4perl::Appender::Synchronized log4perl.appender.Syncer.appender = Logfile ); Log::Log4perl->init(\$conf); WARN("This message is guaranteed to be complete.");
In most cases, you won't need an external synchronisation tool like Log::Log4perl::Appender::Synchronized at all. Log4perl's file appender, Log::Log4perl::Appender::File, for example, provides the "syswrite" mechanism for making sure that even long log lines won't interleave. Short log lines won't interleave anyway, because the operating system makes sure the line gets written before a task switch occurs.
In cases where you need additional synchronization, however, you can use "Log::Log4perl::Appender::Synchronized" as a gateway between your loggers and your appenders. An appender itself, "Log::Log4perl::Appender::Synchronized" just takes two additional arguments:
"Log::Log4perl::Appender::Synchronized" uses Log::Log4perl::Util::Semaphore internally to perform locking with semaphores provided by the operating system used.
Unless specified otherwise, all instances of "Log::Log4perl::Appender::Synchronized" objects in the system will use the same global IPC key "_l4p".
To control access to different appender instances, it often makes sense to define different keys for different synchronizing appenders. In this way, Log::Log4perl serializes access to each appender instance separately:
log4perl.category = WARN, Syncer1, Syncer2 # File appender 1 (unsynchronized) log4perl.appender.Logfile1 = Log::Log4perl::Appender::File log4perl.appender.Logfile1.filename = test1.log log4perl.appender.Logfile1.layout = SimpleLayout # File appender 2 (unsynchronized) log4perl.appender.Logfile2 = Log::Log4perl::Appender::File log4perl.appender.Logfile2.filename = test2.log log4perl.appender.Logfile2.layout = SimpleLayout # Synchronizing appender, using the file appender above log4perl.appender.Syncer1 = Log::Log4perl::Appender::Synchronized log4perl.appender.Syncer1.appender = Logfile1 log4perl.appender.Syncer1.key = l4p1 # Synchronizing appender, using the file appender above log4perl.appender.Syncer2 = Log::Log4perl::Appender::Synchronized log4perl.appender.Syncer2.appender = Logfile2 log4perl.appender.Syncer2.key = l4p2
Without the ".key = l4p1" and ".key = l4p2" lines, both Synchronized appenders would be using the default "_l4p" key, causing unnecessary serialization of output written to different files.
log4perl.appender.Syncer1.destroy = 1 log4perl.appender.Syncer1.mode = sub { 0775 } log4perl.appender.Syncer1.uid = hugo log4perl.appender.Syncer1.gid = 100
Valid options are "destroy" (Remove the semaphore on exit), "mode" (permissions on the semaphore), "uid" (uid or user name the semaphore is owned by), and "gid" (group id the semaphore is owned by),
Note that "mode" is usually given in octal and therefore needs to be specified as a perl sub {}, unless you want to calculate what 0755 means in decimal.
Changing ownership or group settings for a semaphore will obviously only work if the current user ID owns the semaphore already or if the current user is "root". The "destroy" option causes the current process to destroy the semaphore on exit. Spawned children of the process won't inherit this behavior.
Custom filters are also applied to the composite appender only. They are not applied to the sub-appender. Same applies to appender thresholds. This behaviour might change in the future.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
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.