1FAQ(3)                User Contributed Perl Documentation               FAQ(3)
2
3
4

NAME

6       Log::Log4perl::FAQ - Frequently Asked Questions on Log::Log4perl
7

DESCRIPTION

9       This FAQ shows a wide variety of commonly encountered logging tasks and
10       how to solve them in the most elegant way with Log::Log4perl. Most of
11       the time, this will be just a matter of smartly configuring your
12       Log::Log4perl configuration files.
13
14   Why use Log::Log4perl instead of any other logging module on CPAN?
15       That's a good question. There's dozens of logging modules on CPAN.
16       When it comes to logging, people typically think: "Aha. Writing out
17       debug and error messages. Debug is lower than error. Easy. I'm gonna
18       write my own." Writing a logging module is like a rite of passage for
19       every Perl programmer, just like writing your own templating system.
20
21       Of course, after getting the basics right, features need to be added.
22       You'd like to write a timestamp with every message. Then timestamps
23       with microseconds. Then messages need to be written to both the screen
24       and a log file.
25
26       And, as your application grows in size you might wonder: Why doesn't my
27       logging system scale along with it? You would like to switch on logging
28       in selected parts of the application, and not all across the board,
29       because this kills performance. This is when people turn to
30       Log::Log4perl, because it handles all of that.
31
32       Avoid this costly switch.
33
34       Use "Log::Log4perl" right from the start. "Log::Log4perl"'s ":easy"
35       mode supports easy logging in simple scripts:
36
37           use Log::Log4perl qw(:easy);
38           Log::Log4perl->easy_init($DEBUG);
39
40           DEBUG "A low-level message";
41           ERROR "Won't make it until level gets increased to ERROR";
42
43       And when your application inevitably grows, your logging system grows
44       with it without you having to change any code.
45
46       Please, don't re-invent logging. "Log::Log4perl" is here, it's easy to
47       use, it scales, and covers many areas you haven't thought of yet, but
48       will enter soon.
49
50   What's the easiest way to use Log4perl?
51       If you just want to get all the comfort of logging, without much
52       overhead, use Stealth Loggers. If you use Log::Log4perl in ":easy" mode
53       like
54
55           use Log::Log4perl qw(:easy);
56
57       you'll have the following functions available in the current package:
58
59           DEBUG("message");
60           INFO("message");
61           WARN("message");
62           ERROR("message");
63           FATAL("message");
64
65       Just make sure that every package of your code where you're using them
66       in pulls in "use Log::Log4perl qw(:easy)" first, then you're set.
67       Every stealth logger's category will be equivalent to the name of the
68       package it's located in.
69
70       These stealth loggers will be absolutely silent until you initialize
71       Log::Log4perl in your main program with either
72
73               # Define any Log4perl behavior
74           Log::Log4perl->init("foo.conf");
75
76       (using a full-blown Log4perl config file) or the super-easy method
77
78               # Just log to STDERR
79           Log::Log4perl->easy_init($DEBUG);
80
81       or the parameter-style method with a complexity somewhat in between:
82
83               # Append to a log file
84           Log::Log4perl->easy_init( { level   => $DEBUG,
85                                       file    => ">>test.log" } );
86
87       For more info, please check out "Stealth Loggers" in Log::Log4perl.
88
89   How can I simply log all my ERROR messages to a file?
90       After pulling in the "Log::Log4perl" module, just initialize its
91       behavior by passing in a configuration to its "init" method as a string
92       reference. Then, obtain a logger instance and write out a message with
93       its error() method:
94
95           use Log::Log4perl qw(get_logger);
96
97               # Define configuration
98           my $conf = q(
99               log4perl.logger                    = ERROR, FileApp
100               log4perl.appender.FileApp          = Log::Log4perl::Appender::File
101               log4perl.appender.FileApp.filename = test.log
102               log4perl.appender.FileApp.layout   = PatternLayout
103               log4perl.appender.FileApp.layout.ConversionPattern = %d> %m%n
104           );
105
106               # Initialize logging behavior
107           Log::Log4perl->init( \$conf );
108
109               # Obtain a logger instance
110           my $logger = get_logger("Bar::Twix");
111           $logger->error("Oh my, a dreadful error!");
112           $logger->warn("Oh my, a dreadful warning!");
113
114       This will append something like
115
116           2002/10/29 20:11:55> Oh my, a dreadful error!
117
118       to the log file "test.log". How does this all work?
119
120       While the Log::Log4perl init() method typically takes the name of a
121       configuration file as its input parameter like in
122
123           Log::Log4perl->init( "/path/mylog.conf" );
124
125       the example above shows how to pass in a configuration as text in a
126       scalar reference.
127
128       The configuration as shown defines a logger of the root category, which
129       has an appender of type "Log::Log4perl::Appender::File" attached. The
130       line
131
132           log4perl.logger = ERROR, FileApp
133
134       doesn't list a category, defining a root logger. Compare that with
135
136           log4perl.logger.Bar.Twix = ERROR, FileApp
137
138       which would define a logger for the category "Bar::Twix", showing
139       probably different behavior. "FileApp" on the right side of the
140       assignment is an arbitrarily defined variable name, which is only used
141       to somehow reference an appender defined later on.
142
143       Appender settings in the configuration are defined as follows:
144
145           log4perl.appender.FileApp          = Log::Log4perl::Appender::File
146           log4perl.appender.FileApp.filename = test.log
147
148       It selects the file appender of the "Log::Log4perl::Appender"
149       hierarchy, which will append to the file "test.log" if it already
150       exists. If we wanted to overwrite a potentially existing file, we would
151       have to explicitly set the appropriate "Log::Log4perl::Appender::File"
152       parameter "mode":
153
154           log4perl.appender.FileApp          = Log::Log4perl::Appender::File
155           log4perl.appender.FileApp.filename = test.log
156           log4perl.appender.FileApp.mode     = write
157
158       Also, the configuration defines a PatternLayout format, adding the
159       nicely formatted current date and time, an arrow (>) and a space before
160       the messages, which is then followed by a newline:
161
162           log4perl.appender.FileApp.layout   = PatternLayout
163           log4perl.appender.FileApp.layout.ConversionPattern = %d> %m%n
164
165       Obtaining a logger instance and actually logging something is typically
166       done in a different system part as the Log::Log4perl initialisation
167       section, but in this example, it's just done right after init for the
168       sake of compactness:
169
170               # Obtain a logger instance
171           my $logger = get_logger("Bar::Twix");
172           $logger->error("Oh my, a dreadful error!");
173
174       This retrieves an instance of the logger of the category "Bar::Twix",
175       which, as all other categories, inherits behavior from the root logger
176       if no other loggers are defined in the initialization section.
177
178       The error() method fires up a message, which the root logger catches.
179       Its priority is equal to or higher than the root logger's priority
180       (ERROR), which causes the root logger to forward it to its attached
181       appender. By contrast, the following
182
183           $logger->warn("Oh my, a dreadful warning!");
184
185       doesn't make it through, because the root logger sports a higher
186       setting (ERROR and up) than the WARN priority of the message.
187
188   How can I install Log::Log4perl on Microsoft Windows?
189       You can install Log::Log4perl using the CPAN client.
190
191       Alternatively you can install it using
192
193           ppm install Log-Log4perl
194
195       if you're using ActiveState perl.
196
197       That's it! Afterwards, just create a Perl script like
198
199           use Log::Log4perl qw(:easy);
200           Log::Log4perl->easy_init($DEBUG);
201
202           my $logger = get_logger("Twix::Bar");
203           $logger->debug("Watch me!");
204
205       and run it. It should print something like
206
207           2002/11/06 01:22:05 Watch me!
208
209       If you find that something doesn't work, please let us know at
210       log4perl-devel@lists.sourceforge.net -- we'll appreciate it. Have fun!
211
212   How can I include global (thread-specific) data in my log messages?
213       Say, you're writing a web application and want all your log messages to
214       include the current client's IP address. Most certainly, you don't want
215       to include it in each and every log message like in
216
217           $logger->debug( $r->connection->remote_ip,
218                           " Retrieving user data from DB" );
219
220       do you? Instead, you want to set it in a global data structure and have
221       Log::Log4perl include it automatically via a PatternLayout setting in
222       the configuration file:
223
224           log4perl.appender.FileApp.layout.ConversionPattern = %X{ip} %m%n
225
226       The conversion specifier %X{ip} references an entry under the key "ip"
227       in the global "MDC" (mapped diagnostic context) table, which you've set
228       once via
229
230           Log::Log4perl::MDC->put("ip", $r->connection->remote_ip);
231
232       at the start of the request handler. Note that this is a static (class)
233       method, there's no logger object involved.  You can use this method
234       with as many key/value pairs as you like as long as you reference them
235       under different names.
236
237       The mappings are stored in a global hash table within Log::Log4perl.
238       Luckily, because the thread model in 5.8.0 doesn't share global
239       variables between threads unless they're explicitly marked as such,
240       there's no problem with multi-threaded environments.
241
242       For more details on the MDC, please refer to "Mapped Diagnostic Context
243       (MDC)" in Log::Log4perl and Log::Log4perl::MDC.
244
245   My application is already logging to a file. How can I duplicate all
246       messages to also go to the screen?
247       Assuming that you already have a Log4perl configuration file like
248
249           log4perl.logger                    = DEBUG, FileApp
250
251           log4perl.appender.FileApp          = Log::Log4perl::Appender::File
252           log4perl.appender.FileApp.filename = test.log
253           log4perl.appender.FileApp.layout   = PatternLayout
254           log4perl.appender.FileApp.layout.ConversionPattern = %d> %m%n
255
256       and log statements all over your code, it's very easy with Log4perl to
257       have the same messages both printed to the logfile and the screen. No
258       reason to change your code, of course, just add another appender to the
259       configuration file and you're done:
260
261           log4perl.logger                    = DEBUG, FileApp, ScreenApp
262
263           log4perl.appender.FileApp          = Log::Log4perl::Appender::File
264           log4perl.appender.FileApp.filename = test.log
265           log4perl.appender.FileApp.layout   = PatternLayout
266           log4perl.appender.FileApp.layout.ConversionPattern = %d> %m%n
267
268           log4perl.appender.ScreenApp          = Log::Log4perl::Appender::Screen
269           log4perl.appender.ScreenApp.stderr   = 0
270           log4perl.appender.ScreenApp.layout   = PatternLayout
271           log4perl.appender.ScreenApp.layout.ConversionPattern = %d> %m%n
272
273       The configuration file above is assuming that both appenders are active
274       in the same logger hierarchy, in this case the "root" category.  But
275       even if you've got file loggers defined in several parts of your
276       system, belonging to different logger categories, each logging to
277       different files, you can gobble up all logged messages by defining a
278       root logger with a screen appender, which would duplicate messages from
279       all your file loggers to the screen due to Log4perl's appender
280       inheritance. Check
281
282           http://www.perl.com/pub/a/2002/09/11/log4perl.html
283
284       for details. Have fun!
285
286   How can I make sure my application logs a message when it dies
287       unexpectedly?
288       Whenever you encounter a fatal error in your application, instead of
289       saying something like
290
291           open FILE, "<blah" or die "Can't open blah -- bailing out!";
292
293       just use Log::Log4perl's fatal functions instead:
294
295           my $log = get_logger("Some::Package");
296           open FILE, "<blah" or $log->logdie("Can't open blah -- bailing out!");
297
298       This will both log the message with priority FATAL according to your
299       current Log::Log4perl configuration and then call Perl's die()
300       afterwards to terminate the program. It works the same with stealth
301       loggers (see "Stealth Loggers" in Log::Log4perl), all you need to do is
302       call
303
304           use Log::Log4perl qw(:easy);
305           open FILE, "<blah" or LOGDIE "Can't open blah -- bailing out!";
306
307       What can you do if you're using some library which doesn't use
308       Log::Log4perl and calls die() internally if something goes wrong? Use a
309       $SIG{__DIE__} pseudo signal handler
310
311           use Log::Log4perl qw(get_logger);
312
313           $SIG{__DIE__} = sub {
314               if($^S) {
315                   # We're in an eval {} and don't want log
316                   # this message but catch it later
317                   return;
318               }
319               local $Log::Log4perl::caller_depth =
320                     $Log::Log4perl::caller_depth + 1;
321               my $logger = get_logger("");
322               $logger->fatal(@_);
323               die @_; # Now terminate really
324           };
325
326       This will catch every die()-Exception of your application or the
327       modules it uses. In case you want to It will fetch a root logger and
328       pass on the die()-Message to it.  If you make sure you've configured
329       with a root logger like this:
330
331           Log::Log4perl->init(\q{
332               log4perl.category         = FATAL, Logfile
333               log4perl.appender.Logfile = Log::Log4perl::Appender::File
334               log4perl.appender.Logfile.filename = fatal_errors.log
335               log4perl.appender.Logfile.layout = \
336                          Log::Log4perl::Layout::PatternLayout
337               log4perl.appender.Logfile.layout.ConversionPattern = %F{1}-%L (%M)> %m%n
338           });
339
340       then all die() messages will be routed to a file properly. The line
341
342            local $Log::Log4perl::caller_depth =
343                  $Log::Log4perl::caller_depth + 1;
344
345       in the pseudo signal handler above merits a more detailed explanation.
346       With the setup above, if a module calls die() in one of its functions,
347       the fatal message will be logged in the signal handler and not in the
348       original function -- which will cause the %F, %L and %M placeholders in
349       the pattern layout to be replaced by the filename, the line number and
350       the function/method name of the signal handler, not the error-throwing
351       module. To adjust this, Log::Log4perl has the $caller_depth variable,
352       which defaults to 0, but can be set to positive integer values to
353       offset the caller level. Increasing it by one will cause it to log the
354       calling function's parameters, not the ones of the signal handler.  See
355       "Using Log::Log4perl from wrapper classes" in Log::Log4perl for more
356       details.
357
358   How can I hook up the LWP library with Log::Log4perl?
359       Or, to put it more generally: How can you utilize a third-party
360       library's embedded logging and debug statements in Log::Log4perl?  How
361       can you make them print to configurable appenders, turn them on and
362       off, just as if they were regular Log::Log4perl logging statements?
363
364       The easiest solution is to map the third-party library logging
365       statements to Log::Log4perl's stealth loggers via a typeglob
366       assignment.
367
368       As an example, let's take LWP, one of the most popular Perl modules,
369       which makes handling WWW requests and responses a breeze.  Internally,
370       LWP uses its own logging and debugging system, utilizing the following
371       calls inside the LWP code (from the LWP::Debug man page):
372
373               # Function tracing
374           LWP::Debug::trace('send()');
375
376               # High-granular state in functions
377           LWP::Debug::debug('url ok');
378
379               # Data going over the wire
380           LWP::Debug::conns("read $n bytes: $data");
381
382       First, let's assign Log::Log4perl priorities to these functions: I'd
383       suggest that debug() messages have priority "INFO", trace() uses
384       "DEBUG" and conns() also logs with "DEBUG" -- although your mileage may
385       certainly vary.
386
387       Now, in order to transparently hook up LWP::Debug with Log::Log4perl,
388       all we have to do is say
389
390           package LWP::Debug;
391           use Log::Log4perl qw(:easy);
392
393           *trace = *INFO;
394           *conns = *DEBUG;
395           *debug = *DEBUG;
396
397           package main;
398           # ... go on with your regular program ...
399
400       at the beginning of our program. In this way, every time the, say,
401       "LWP::UserAgent" module calls LWP::Debug::trace(), it will implicitly
402       call INFO(), which is the info() method of a stealth logger defined for
403       the Log::Log4perl category "LWP::Debug". Is this cool or what?
404
405       Here's a complete program:
406
407           use LWP::UserAgent;
408           use HTTP::Request::Common;
409           use Log::Log4perl qw(:easy);
410
411           Log::Log4perl->easy_init(
412               { category => "LWP::Debug",
413                 level    => $DEBUG,
414                 layout   => "%r %p %M-%L %m%n",
415               });
416
417           package LWP::Debug;
418           use Log::Log4perl qw(:easy);
419           *trace = *INFO;
420           *conns = *DEBUG;
421           *debug = *DEBUG;
422
423           package main;
424           my $ua = LWP::UserAgent->new();
425           my $resp = $ua->request(GET "http://amazon.com");
426
427           if($resp->is_success()) {
428               print "Success: Received ",
429                     length($resp->content()), "\n";
430           } else {
431               print "Error: ", $resp->code(), "\n";
432           }
433
434       This will generate the following output on STDERR:
435
436           174 INFO LWP::UserAgent::new-164 ()
437           208 INFO LWP::UserAgent::request-436 ()
438           211 INFO LWP::UserAgent::send_request-294 GET http://amazon.com
439           212 DEBUG LWP::UserAgent::_need_proxy-1123 Not proxied
440           405 INFO LWP::Protocol::http::request-122 ()
441           859 DEBUG LWP::Protocol::collect-206 read 233 bytes
442           863 DEBUG LWP::UserAgent::request-443 Simple response: Found
443           869 INFO LWP::UserAgent::request-436 ()
444           871 INFO LWP::UserAgent::send_request-294
445            GET http://www.amazon.com:80/exec/obidos/gateway_redirect
446           872 DEBUG LWP::UserAgent::_need_proxy-1123 Not proxied
447           873 INFO LWP::Protocol::http::request-122 ()
448           1016 DEBUG LWP::UserAgent::request-443 Simple response: Found
449           1020 INFO LWP::UserAgent::request-436 ()
450           1022 INFO LWP::UserAgent::send_request-294
451            GET http://www.amazon.com/exec/obidos/subst/home/home.html/
452           1023 DEBUG LWP::UserAgent::_need_proxy-1123 Not proxied
453           1024 INFO LWP::Protocol::http::request-122 ()
454           1382 DEBUG LWP::Protocol::collect-206 read 632 bytes
455           ...
456           2605 DEBUG LWP::Protocol::collect-206 read 77 bytes
457           2607 DEBUG LWP::UserAgent::request-443 Simple response: OK
458           Success: Received 42584
459
460       Of course, in this way, the embedded logging and debug statements
461       within LWP can be utilized in any Log::Log4perl way you can think of.
462       You can have them sent to different appenders, block them based on the
463       category and everything else Log::Log4perl has to offer.
464
465       Only drawback of this method: Steering logging behavior via category is
466       always based on the "LWP::Debug" package. Although the logging
467       statements reflect the package name of the issuing module properly, the
468       stealth loggers in "LWP::Debug" are all of the category "LWP::Debug".
469       This implies that you can't control the logging behavior based on the
470       package that's initiating a log request (e.g. LWP::UserAgent) but only
471       based on the package that's actually executing the logging statement,
472       "LWP::Debug" in this case.
473
474       To work around this conundrum, we need to write a wrapper function and
475       plant it into the "LWP::Debug" package. It will determine the caller
476       and create a logger bound to a category with the same name as the
477       caller's package:
478
479           package LWP::Debug;
480
481           use Log::Log4perl qw(:levels get_logger);
482
483           sub l4p_wrapper {
484               my($prio, @message) = @_;
485               $Log::Log4perl::caller_depth += 2;
486               get_logger(scalar caller(1))->log($prio, @message);
487               $Log::Log4perl::caller_depth -= 2;
488           }
489
490           no warnings 'redefine';
491           *trace = sub { l4p_wrapper($INFO, @_); };
492           *debug = *conns = sub { l4p_wrapper($DEBUG, @_); };
493
494           package main;
495           # ... go on with your main program ...
496
497       This is less performant than the previous approach, because every log
498       request will request a reference to a logger first, then call the
499       wrapper, which will in turn call the appropriate log function.
500
501       This hierarchy shift has to be compensated for by increasing
502       $Log::Log4perl::caller_depth by 2 before calling the log function and
503       decreasing it by 2 right afterwards. Also, the "l4p_wrapper" function
504       shown above calls caller(1) which determines the name of the package
505       two levels down the calling hierarchy (and therefore compensates for
506       both the wrapper function and the anonymous subroutine calling it).
507
508       "no warnings 'redefine'" suppresses a warning Perl would generate
509       otherwise upon redefining "LWP::Debug"'s trace(), debug() and conns()
510       functions. In case you use a perl prior to 5.6.x, you need to
511       manipulate $^W instead.
512
513       To make things easy for you when dealing with LWP, Log::Log4perl 0.47
514       introduces "Log::Log4perl->infiltrate_lwp()" which does exactly the
515       above.
516
517   What if I need dynamic values in a static Log4perl configuration file?
518       Say, your application uses Log::Log4perl for logging and therefore
519       comes with a Log4perl configuration file, specifying the logging
520       behavior.  But, you also want it to take command line parameters to set
521       values like the name of the log file.  How can you have both a static
522       Log4perl configuration file and a dynamic command line interface?
523
524       As of Log::Log4perl 0.28, every value in the configuration file can be
525       specified as a Perl hook. So, instead of saying
526
527           log4perl.appender.Logfile.filename = test.log
528
529       you could just as well have a Perl subroutine deliver the value
530       dynamically:
531
532           log4perl.appender.Logfile.filename = sub { logfile(); };
533
534       given that logfile() is a valid function in your "main" package
535       returning a string containing the path to the log file.
536
537       Or, think about using the value of an environment variable:
538
539           log4perl.appender.DBI.user = sub { $ENV{USERNAME} };
540
541       When "Log::Log4perl->init()" parses the configuration file, it will
542       notice the assignment above because of its "sub {...}" pattern and
543       treat it in a special way: It will evaluate the subroutine (which can
544       contain arbitrary Perl code) and take its return value as the right
545       side of the assignment.
546
547       A typical application would be called like this on the command line:
548
549           app                # log file is "test.log"
550           app -l mylog.txt   # log file is "mylog.txt"
551
552       Here's some sample code implementing the command line interface above:
553
554           use Log::Log4perl qw(get_logger);
555           use Getopt::Std;
556
557           getopt('l:', \our %OPTS);
558
559           my $conf = q(
560           log4perl.category.Bar.Twix         = WARN, Logfile
561           log4perl.appender.Logfile          = Log::Log4perl::Appender::File
562           log4perl.appender.Logfile.filename = sub { logfile(); };
563           log4perl.appender.Logfile.layout   = SimpleLayout
564           );
565
566           Log::Log4perl::init(\$conf);
567
568           my $logger = get_logger("Bar::Twix");
569           $logger->error("Blah");
570
571           ###########################################
572           sub logfile {
573           ###########################################
574               if(exists $OPTS{l}) {
575                   return $OPTS{l};
576               } else {
577                   return "test.log";
578               }
579           }
580
581       Every Perl hook may contain arbitrary perl code, just make sure to
582       fully qualify eventual variable names (e.g. %main::OPTS instead of
583       %OPTS).
584
585       SECURITY NOTE: this feature means arbitrary perl code can be embedded
586       in the config file.  In the rare case where the people who have access
587       to your config file are different from the people who write your code
588       and shouldn't have execute rights, you might want to call
589
590           $Log::Log4perl::Config->allow_code(0);
591
592       before you call init(). This will prevent Log::Log4perl from executing
593       any Perl code in the config file (including code for custom conversion
594       specifiers (see "Custom cspecs" in
595       Log::Log4perl::Layout::PatternLayout).
596
597   How can I roll over my logfiles automatically at midnight?
598       Long-running applications tend to produce ever-increasing logfiles.
599       For backup and cleanup purposes, however, it is often desirable to move
600       the current logfile to a different location from time to time and start
601       writing a new one.
602
603       This is a non-trivial task, because it has to happen in sync with the
604       logging system in order not to lose any messages in the process.
605
606       Luckily, Mark Pfeiffer's "Log::Dispatch::FileRotate" appender works
607       well with Log::Log4perl to rotate your logfiles in a variety of ways.
608
609       Note, however, that having the application deal with rotating a log
610       file is not cheap. Among other things, it requires locking the log file
611       with every write to avoid race conditions.  There are good reasons to
612       use external rotators like "newsyslog" instead.  See the entry "How can
613       I rotate a logfile with newsyslog?" in the FAQ for more information on
614       how to configure it.
615
616       When using "Log::Dispatch::FileRotate", all you have to do is specify
617       it in your Log::Log4perl configuration file and your logfiles will be
618       rotated automatically.
619
620       You can choose between rolling based on a maximum size ("roll if
621       greater than 10 MB") or based on a date pattern ("roll everyday at
622       midnight").  In both cases, "Log::Dispatch::FileRotate" allows you to
623       define a number "max" of saved files to keep around until it starts
624       overwriting the oldest ones. If you set the "max" parameter to 2 and
625       the name of your logfile is "test.log", "Log::Dispatch::FileRotate"
626       will move "test.log" to "test.log.1" on the first rollover. On the
627       second rollover, it will move "test.log.1" to "test.log.2" and then
628       "test.log" to "test.log.1". On the third rollover, it will move
629       "test.log.1" to "test.log.2" (therefore discarding the old
630       "test.log.2") and "test.log" to "test.log.1". And so forth. This way,
631       there's always going to be a maximum of 2 saved log files around.
632
633       Here's an example of a Log::Log4perl configuration file, defining a
634       daily rollover at midnight (date pattern "yyyy-MM-dd"), keeping a
635       maximum of 5 saved logfiles around:
636
637           log4perl.category         = WARN, Logfile
638           log4perl.appender.Logfile = Log::Dispatch::FileRotate
639           log4perl.appender.Logfile.filename    = test.log
640           log4perl.appender.Logfile.max         = 5
641           log4perl.appender.Logfile.DatePattern = yyyy-MM-dd
642           log4perl.appender.Logfile.TZ          = PST
643           log4perl.appender.Logfile.layout = \
644               Log::Log4perl::Layout::PatternLayout
645           log4perl.appender.Logfile.layout.ConversionPattern = %d %m %n
646
647       Please see the "Log::Dispatch::FileRotate" documentation for details.
648       "Log::Dispatch::FileRotate" is available on CPAN.
649
650   What's the easiest way to turn off all logging, even with a lengthy
651       Log4perl configuration file?
652       In addition to category-based levels and appender thresholds,
653       Log::Log4perl supports system-wide logging thresholds. This is the
654       minimum level the system will require of any logging events in order
655       for them to make it through to any configured appenders.
656
657       For example, putting the line
658
659           log4perl.threshold = ERROR
660
661       anywhere in your configuration file will limit any output to any
662       appender to events with priority of ERROR or higher (ERROR or FATAL
663       that is).
664
665       However, in order to suppress all logging entirely, you need to use a
666       priority that's higher than FATAL: It is simply called "OFF", and it is
667       never used by any logger. By definition, it is higher than the highest
668       defined logger level.
669
670       Therefore, if you keep the line
671
672           log4perl.threshold = OFF
673
674       somewhere in your Log::Log4perl configuration, the system will be quiet
675       as a graveyard. If you deactivate the line (e.g. by commenting it out),
676       the system will, upon config reload, snap back to normal operation,
677       providing logging messages according to the rest of the configuration
678       file again.
679
680   How can I log DEBUG and above to the screen and INFO and above to a file?
681       You need one logger with two appenders attached to it:
682
683           log4perl.logger = DEBUG, Screen, File
684
685           log4perl.appender.Screen   = Log::Log4perl::Appender::Screen
686           log4perl.appender.Screen.layout = SimpleLayout
687
688           log4perl.appender.File   = Log::Log4perl::Appender::File
689           log4perl.appender.File.filename = test.log
690           log4perl.appender.File.layout = SimpleLayout
691           log4perl.appender.Screen.Threshold = INFO
692
693       Since the file logger isn't supposed to get any messages with a
694       priority less than INFO, the appender's "Threshold" setting blocks
695       those out, although the logger forwards them.
696
697       It's a common mistake to think you can define two loggers for this, but
698       it won't work unless those two loggers have different categories. If
699       you wanted to log all DEBUG and above messages from the Foo::Bar module
700       to a file and all INFO and above messages from the Quack::Schmack
701       module to the screen, then you could have defined two loggers with
702       different levels "log4perl.logger.Foo.Bar" (level INFO) and
703       "log4perl.logger.Quack.Schmack" (level DEBUG) and assigned the file
704       appender to the former and the screen appender to the latter. But what
705       we wanted to accomplish was to route all messages, regardless of which
706       module (or category) they came from, to both appenders. The only way to
707       accomplish this is to define the root logger with the lower level
708       (DEBUG), assign both appenders to it, and block unwanted messages at
709       the file appender ("Threshold" set to INFO).
710
711   I keep getting duplicate log messages! What's wrong?
712       Having several settings for related categories in the Log4perl
713       configuration file sometimes leads to a phenomenon called "message
714       duplication". It can be very confusing at first, but if thought through
715       properly, it turns out that Log4perl behaves as advertised. But, don't
716       despair, of course there's a number of ways to avoid message
717       duplication in your logs.
718
719       Here's a sample Log4perl configuration file that produces the
720       phenomenon:
721
722           log4perl.logger.Cat        = ERROR, Screen
723           log4perl.logger.Cat.Subcat = WARN, Screen
724
725           log4perl.appender.Screen   = Log::Log4perl::Appender::Screen
726           log4perl.appender.Screen.layout = SimpleLayout
727
728       It defines two loggers, one for category "Cat" and one for
729       "Cat::Subcat", which is obviously a subcategory of "Cat".  The parent
730       logger has a priority setting of ERROR, the child is set to the lower
731       "WARN" level.
732
733       Now imagine the following code in your program:
734
735           my $logger = get_logger("Cat.Subcat");
736           $logger->warn("Warning!");
737
738       What do you think will happen? An unexperienced Log4perl user might
739       think: "Well, the message is being sent with level WARN, so the
740       "Cat::Subcat" logger will accept it and forward it to the attached
741       "Screen" appender. Then, the message will percolate up the logger
742       hierarchy, find the "Cat" logger, which will suppress the message
743       because of its ERROR setting."  But, perhaps surprisingly, what you'll
744       get with the code snippet above is not one but two log messages written
745       to the screen:
746
747           WARN - Warning!
748           WARN - Warning!
749
750       What happened? The culprit is that once the logger "Cat::Subcat"
751       decides to fire, it will forward the message unconditionally to all
752       directly or indirectly attached appenders. The "Cat" logger will never
753       be asked if it wants the message or not -- the message will just be
754       pushed through to the appender attached to "Cat".
755
756       One way to prevent the message from bubbling up the logger hierarchy is
757       to set the "additivity" flag of the subordinate logger to 0:
758
759           log4perl.logger.Cat            = ERROR, Screen
760           log4perl.logger.Cat.Subcat     = WARN, Screen
761           log4perl.additivity.Cat.Subcat = 0
762
763           log4perl.appender.Screen   = Log::Log4perl::Appender::Screen
764           log4perl.appender.Screen.layout = SimpleLayout
765
766       The message will now be accepted by the "Cat::Subcat" logger, forwarded
767       to its appender, but then "Cat::Subcat" will suppress any further
768       action. While this setting avoids duplicate messages as seen before, it
769       is often not the desired behavior. Messages percolating up the
770       hierarchy are a useful Log4perl feature.
771
772       If you're defining different appenders for the two loggers, one other
773       option is to define an appender threshold for the higher-level
774       appender. Typically it is set to be equal to the logger's level
775       setting:
776
777           log4perl.logger.Cat           = ERROR, Screen1
778           log4perl.logger.Cat.Subcat    = WARN, Screen2
779
780           log4perl.appender.Screen1   = Log::Log4perl::Appender::Screen
781           log4perl.appender.Screen1.layout = SimpleLayout
782           log4perl.appender.Screen1.Threshold = ERROR
783
784           log4perl.appender.Screen2   = Log::Log4perl::Appender::Screen
785           log4perl.appender.Screen2.layout = SimpleLayout
786
787       Since the "Screen1" appender now blocks every message with a priority
788       less than ERROR, even if the logger in charge lets it through, the
789       message percolating up the hierarchy is being blocked at the last
790       minute and not appended to "Screen1".
791
792       So far, we've been operating well within the boundaries of the Log4j
793       standard, which Log4perl adheres to. However, if you would really,
794       really like to use a single appender and keep the message percolation
795       intact without having to deal with message duplication, there's a non-
796       standard solution for you:
797
798           log4perl.logger.Cat        = ERROR, Screen
799           log4perl.logger.Cat.Subcat = WARN, Screen
800
801           log4perl.appender.Screen   = Log::Log4perl::Appender::Screen
802           log4perl.appender.Screen.layout = SimpleLayout
803
804           log4perl.oneMessagePerAppender = 1
805
806       The "oneMessagePerAppender" flag will suppress duplicate messages to
807       the same appender. Again, that's non-standard. But way cool :).
808
809   How can I configure Log::Log4perl to send me email if something happens?
810       Some incidents require immediate action. You can't wait until someone
811       checks the log files, you need to get notified on your pager right
812       away.
813
814       The easiest way to do that is by using the
815       "Log::Dispatch::Email::MailSend" module as an appender. It comes with
816       the "Log::Dispatch" bundle and allows you to specify recipient and
817       subject of outgoing emails in the Log4perl configuration file:
818
819           log4perl.category = FATAL, Mailer
820           log4perl.appender.Mailer         = Log::Dispatch::Email::MailSend
821           log4perl.appender.Mailer.to      = drone@pageme.net
822           log4perl.appender.Mailer.subject = Something's broken!
823           log4perl.appender.Mailer.layout  = SimpleLayout
824
825       The message of every log incident this appender gets will then be
826       forwarded to the given email address. Check the
827       "Log::Dispatch::Email::MailSend" documentation for details. And please
828       make sure there's not a flood of email messages sent out by your
829       application, filling up the recipient's inbox.
830
831       There's one caveat you need to know about: The "Log::Dispatch::Email"
832       hierarchy of appenders turns on buffering by default. This means that
833       the appender will not send out messages right away but wait until a
834       certain threshold has been reached. If you'd rather have your alerts
835       sent out immediately, use
836
837           log4perl.appender.Mailer.buffered = 0
838
839       to turn buffering off.
840
841   How can I write my own appender?
842       First off, Log::Log4perl comes with a set of standard appenders. Then,
843       there's a lot of Log4perl-compatible appenders already available on
844       CPAN: Just run a search for "Log::Dispatch" on http://search.cpan.org
845       and chances are that what you're looking for has already been
846       developed, debugged and been used successfully in production -- no need
847       for you to reinvent the wheel.
848
849       Also, Log::Log4perl ships with a nifty database appender named
850       Log::Log4perl::Appender::DBI -- check it out if talking to databases is
851       your desire.
852
853       But if you're up for a truly exotic task, you might have to write an
854       appender yourself. That's very easy -- it takes no longer than a couple
855       of minutes.
856
857       Say, we wanted to create an appender of the class
858       "ColorScreenAppender", which logs messages to the screen in a
859       configurable color. Just create a new class in
860       "ColorScreenAppender.pm":
861
862           package ColorScreenAppender;
863
864       Now let's assume that your Log::Log4perl configuration file "test.conf"
865       looks like this:
866
867           log4perl.logger = INFO, ColorApp
868
869           log4perl.appender.ColorApp=ColorScreenAppender
870           log4perl.appender.ColorApp.color=blue
871
872           log4perl.appender.ColorApp.layout = PatternLayout
873           log4perl.appender.ColorApp.layout.ConversionPattern=%d %m %n
874
875       This will cause Log::Log4perl on init() to look for a class
876       ColorScreenAppender and call its constructor new(). Let's add new() to
877       ColorScreenAppender.pm:
878
879           sub new {
880               my($class, %options) = @_;
881
882               my $self = { %options };
883               bless $self, $class;
884
885               return $self;
886           }
887
888       To initialize this appender, Log::Log4perl will call and pass all
889       attributes of the appender as defined in the configuration file to the
890       constructor as name/value pairs (in this case just one):
891
892           ColorScreenAppender->new(color => "blue");
893
894       The new() method listed above stores the contents of the %options hash
895       in the object's instance data hash (referred to by $self).  That's all
896       for initializing a new appender with Log::Log4perl.
897
898       Second, ColorScreenAppender needs to expose a log() method, which will
899       be called by Log::Log4perl every time it thinks the appender should
900       fire. Along with the object reference (as usual in Perl's object
901       world), log() will receive a list of name/value pairs, of which only
902       the one under the key "message" shall be of interest for now since it
903       is the message string to be logged. At this point, Log::Log4perl has
904       already taken care of joining the message to be a single string.
905
906       For our special appender ColorScreenAppender, we're using the
907       Term::ANSIColor module to colorize the output:
908
909           use Term::ANSIColor;
910
911           sub log {
912               my($self, %params) = @_;
913
914               print colored($params{message},
915                             $self->{color});
916           }
917
918       The color (as configured in the Log::Log4perl configuration file) is
919       available as $self->{color} in the appender object. Don't forget to
920       return
921
922           1;
923
924       at the end of ColorScreenAppender.pm and you're done. Install the new
925       appender somewhere where perl can find it and try it with a test script
926       like
927
928           use Log::Log4perl qw(:easy);
929           Log::Log4perl->init("test.conf");
930           ERROR("blah");
931
932       to see the new colored output. Is this cool or what?
933
934       And it gets even better: You can write dynamically generated appender
935       classes using the "Class::Prototyped" module. Here's an example of an
936       appender prepending every outgoing message with a configurable number
937       of bullets:
938
939           use Class::Prototyped;
940
941           my $class = Class::Prototyped->newPackage(
942             "MyAppenders::Bulletizer",
943             bullets => 1,
944             log     => sub {
945               my($self, %params) = @_;
946               print "*" x $self->bullets(),
947                     $params{message};
948             },
949           );
950
951           use Log::Log4perl qw(:easy);
952
953           Log::Log4perl->init(\ q{
954             log4perl.logger = INFO, Bully
955
956             log4perl.appender.Bully=MyAppenders::Bulletizer
957             log4perl.appender.Bully.bullets=3
958
959             log4perl.appender.Bully.layout = PatternLayout
960             log4perl.appender.Bully.layout.ConversionPattern=%m %n
961           });
962
963               # ... prints: "***Boo!\n";
964           INFO "Boo!";
965
966   How can I drill down on references before logging them?
967       If you've got a reference to a nested structure or object, then you
968       probably don't want to log it as HASH(0x81141d4) but rather dump it as
969       something like
970
971           $VAR1 = {
972                     'a' => 'b',
973                     'd' => 'e'
974                   };
975
976       via a module like Data::Dumper. While it's syntactically correct to say
977
978           $logger->debug(Data::Dumper::Dumper($ref));
979
980       this call imposes a huge performance penalty on your application if the
981       message is suppressed by Log::Log4perl, because Data::Dumper will
982       perform its expensive operations in any case, because it doesn't know
983       that its output will be thrown away immediately.
984
985       As of Log::Log4perl 0.28, there's a better way: Use the message output
986       filter format as in
987
988           $logger->debug( {filter => \&Data::Dumper::Dumper,
989                            value  => $ref} );
990
991       and Log::Log4perl won't call the filter function unless the message
992       really gets written out to an appender. Just make sure to pass the
993       whole slew as a reference to a hash specifying a filter function (as a
994       sub reference) under the key "filter" and the value to be passed to the
995       filter function in "value").  When it comes to logging, Log::Log4perl
996       will call the filter function, pass the "value" as an argument and log
997       the return value.  Saves you serious cycles.
998
999   How can I collect all FATAL messages in an extra log file?
1000       Suppose you have employed Log4perl all over your system and you've
1001       already activated logging in various subsystems. On top of that,
1002       without disrupting any other settings, how can you collect all FATAL
1003       messages all over the system and send them to a separate log file?
1004
1005       If you define a root logger like this:
1006
1007           log4perl.logger                  = FATAL, File
1008           log4perl.appender.File           = Log::Log4perl::Appender::File
1009           log4perl.appender.File.filename  = /tmp/fatal.txt
1010           log4perl.appender.File.layout    = PatternLayout
1011           log4perl.appender.File.layout.ConversionPattern= %d %m %n
1012               # !!! Something's missing ...
1013
1014       you'll be surprised to not only receive all FATAL messages issued
1015       anywhere in the system, but also everything else -- gazillions of
1016       ERROR, WARN, INFO and even DEBUG messages will end up in your fatal.txt
1017       logfile!  Reason for this is Log4perl's (or better: Log4j's) appender
1018       additivity.  Once a lower-level logger decides to fire, the message is
1019       going to be forwarded to all appenders upstream -- without further
1020       priority checks with their attached loggers.
1021
1022       There's a way to prevent this, however: If your appender defines a
1023       minimum threshold, only messages of this priority or higher are going
1024       to be logged. So, just add
1025
1026           log4perl.appender.File.Threshold = FATAL
1027
1028       to the configuration above, and you'll get what you wanted in the first
1029       place: An overall system FATAL message collector.
1030
1031   How can I bundle several log messages into one?
1032       Would you like to tally the messages arriving at your appender and dump
1033       out a summary once they're exceeding a certain threshold?  So that
1034       something like
1035
1036           $logger->error("Blah");
1037           $logger->error("Blah");
1038           $logger->error("Blah");
1039
1040       won't be logged as
1041
1042           Blah
1043           Blah
1044           Blah
1045
1046       but as
1047
1048           [3] Blah
1049
1050       instead? If you'd like to hold off on logging a message until it has
1051       been sent a couple of times, you can roll that out by creating a
1052       buffered appender.
1053
1054       Let's define a new appender like
1055
1056           package TallyAppender;
1057
1058           sub new {
1059               my($class, %options) = @_;
1060
1061               my $self = { maxcount => 5,
1062                            %options
1063                          };
1064
1065               bless $self, $class;
1066
1067               $self->{last_message}        = "";
1068               $self->{last_message_count}  = 0;
1069
1070               return $self;
1071           }
1072
1073       with two additional instance variables "last_message" and
1074       "last_message_count", storing the content of the last message sent and
1075       a counter of how many times this has happened. Also, it features a
1076       configuration parameter "maxcount" which defaults to 5 in the snippet
1077       above but can be set in the Log4perl configuration file like this:
1078
1079           log4perl.logger = INFO, A
1080           log4perl.appender.A=TallyAppender
1081           log4perl.appender.A.maxcount = 3
1082
1083       The main tallying logic lies in the appender's "log" method, which is
1084       called every time Log4perl thinks a message needs to get logged by our
1085       appender:
1086
1087           sub log {
1088               my($self, %params) = @_;
1089
1090                   # Message changed? Print buffer.
1091               if($self->{last_message} and
1092                  $params{message} ne $self->{last_message}) {
1093                   print "[$self->{last_message_count}]: " .
1094                         "$self->{last_message}";
1095                   $self->{last_message_count} = 1;
1096                   $self->{last_message} = $params{message};
1097                   return;
1098               }
1099
1100               $self->{last_message_count}++;
1101               $self->{last_message} = $params{message};
1102
1103                   # Threshold exceeded? Print, reset counter
1104               if($self->{last_message_count} >=
1105                  $self->{maxcount}) {
1106                   print "[$self->{last_message_count}]: " .
1107                         "$params{message}";
1108                   $self->{last_message_count} = 0;
1109                   $self->{last_message}       = "";
1110                   return;
1111               }
1112           }
1113
1114       We basically just check if the oncoming message in $param{message} is
1115       equal to what we've saved before in the "last_message" instance
1116       variable. If so, we're increasing "last_message_count".  We print the
1117       message in two cases: If the new message is different than the buffered
1118       one, because then we need to dump the old stuff and store the new. Or,
1119       if the counter exceeds the threshold, as defined by the "maxcount"
1120       configuration parameter.
1121
1122       Please note that the appender always gets the fully rendered message
1123       and just compares it as a whole -- so if there's a date/timestamp in
1124       there, that might confuse your logic. You can work around this by
1125       specifying %m %n as a layout and add the date later on in the appender.
1126       Or, make the comparison smart enough to omit the date.
1127
1128       At last, don't forget what happens if the program is being shut down.
1129       If there's still messages in the buffer, they should be printed out at
1130       that point. That's easy to do in the appender's DESTROY method, which
1131       gets called at object destruction time:
1132
1133           sub DESTROY {
1134               my($self) = @_;
1135
1136               if($self->{last_message_count}) {
1137                   print "[$self->{last_message_count}]: " .
1138                         "$self->{last_message}";
1139                   return;
1140               }
1141           }
1142
1143       This will ensure that none of the buffered messages are lost.  Happy
1144       buffering!
1145
1146   I want to log ERROR and WARN messages to different files! How can I do
1147       that?
1148       Let's assume you wanted to have each logging statement written to a
1149       different file, based on the statement's priority. Messages with
1150       priority "WARN" are supposed to go to "/tmp/app.warn", events
1151       prioritized as "ERROR" should end up in "/tmp/app.error".
1152
1153       Now, if you define two appenders "AppWarn" and "AppError" and assign
1154       them both to the root logger, messages bubbling up from any loggers
1155       below will be logged by both appenders because of Log4perl's message
1156       propagation feature. If you limit their exposure via the appender
1157       threshold mechanism and set "AppWarn"'s threshold to "WARN" and
1158       "AppError"'s to "ERROR", you'll still get "ERROR" messages in
1159       "AppWarn", because "AppWarn"'s "WARN" setting will just filter out
1160       messages with a lower priority than "WARN" -- "ERROR" is higher and
1161       will be allowed to pass through.
1162
1163       What we need for this is a Log4perl Custom Filter, available with
1164       Log::Log4perl 0.30.
1165
1166       Both appenders need to verify that the priority of the oncoming
1167       messages exactly matches the priority the appender is supposed to log
1168       messages of. To accomplish this task, let's define two custom filters,
1169       "MatchError" and "MatchWarn", which, when attached to their appenders,
1170       will limit messages passed on to them to those matching a given
1171       priority:
1172
1173           log4perl.logger = WARN, AppWarn, AppError
1174
1175               # Filter to match level ERROR
1176           log4perl.filter.MatchError = Log::Log4perl::Filter::LevelMatch
1177           log4perl.filter.MatchError.LevelToMatch  = ERROR
1178           log4perl.filter.MatchError.AcceptOnMatch = true
1179
1180               # Filter to match level WARN
1181           log4perl.filter.MatchWarn  = Log::Log4perl::Filter::LevelMatch
1182           log4perl.filter.MatchWarn.LevelToMatch  = WARN
1183           log4perl.filter.MatchWarn.AcceptOnMatch = true
1184
1185               # Error appender
1186           log4perl.appender.AppError = Log::Log4perl::Appender::File
1187           log4perl.appender.AppError.filename = /tmp/app.err
1188           log4perl.appender.AppError.layout   = SimpleLayout
1189           log4perl.appender.AppError.Filter   = MatchError
1190
1191               # Warning appender
1192           log4perl.appender.AppWarn = Log::Log4perl::Appender::File
1193           log4perl.appender.AppWarn.filename = /tmp/app.warn
1194           log4perl.appender.AppWarn.layout   = SimpleLayout
1195           log4perl.appender.AppWarn.Filter   = MatchWarn
1196
1197       The appenders "AppWarn" and "AppError" defined above are logging to
1198       "/tmp/app.warn" and "/tmp/app.err" respectively and have the custom
1199       filters "MatchWarn" and "MatchError" attached.  This setup will direct
1200       all WARN messages, issued anywhere in the system, to /tmp/app.warn (and
1201       ERROR messages to /tmp/app.error) -- without any overlaps.
1202
1203   On our server farm, Log::Log4perl configuration files differ slightly from
1204       host to host. Can I roll them all into one?
1205       You sure can, because Log::Log4perl allows you to specify attribute
1206       values dynamically. Let's say that one of your appenders expects the
1207       host's IP address as one of its attributes. Now, you could certainly
1208       roll out different configuration files for every host and specify the
1209       value like
1210
1211           log4perl.appender.MyAppender    = Log::Log4perl::Appender::SomeAppender
1212           log4perl.appender.MyAppender.ip = 10.0.0.127
1213
1214       but that's a maintenance nightmare. Instead, you can have Log::Log4perl
1215       figure out the IP address at configuration time and set the appender's
1216       value correctly:
1217
1218               # Set the IP address dynamically
1219           log4perl.appender.MyAppender    = Log::Log4perl::Appender::SomeAppender
1220           log4perl.appender.MyAppender.ip = sub { \
1221              use Sys::Hostname; \
1222              use Socket; \
1223              return inet_ntoa(scalar gethostbyname hostname); \
1224           }
1225
1226       If Log::Log4perl detects that an attribute value starts with something
1227       like "sub {...", it will interpret it as a perl subroutine which is to
1228       be executed once at configuration time (not runtime!) and its return
1229       value is to be used as the attribute value. This comes in handy for
1230       rolling out applications where Log::Log4perl configuration files show
1231       small host-specific differences, because you can deploy the unmodified
1232       application distribution on all instances of the server farm.
1233
1234   Log4perl doesn't interpret my backslashes correctly!
1235       If you're using Log4perl's feature to specify the configuration as a
1236       string in your program (as opposed to a separate configuration file),
1237       chances are that you've written it like this:
1238
1239           # *** WRONG! ***
1240
1241           Log::Log4perl->init( \ <<END_HERE);
1242               log4perl.logger = WARN, A1
1243               log4perl.appender.A1 = Log::Log4perl::Appender::Screen
1244               log4perl.appender.A1.layout = \
1245                   Log::Log4perl::Layout::PatternLayout
1246               log4perl.appender.A1.layout.ConversionPattern = %m%n
1247           END_HERE
1248
1249           # *** WRONG! ***
1250
1251       and you're getting the following error message:
1252
1253           Layout not specified for appender A1 at .../Config.pm line 342.
1254
1255       What's wrong? The problem is that you're using a here-document with
1256       substitution enabled ("<<END_HERE") and that Perl won't interpret
1257       backslashes at line-ends as continuation characters but will
1258       essentially throw them out. So, in the code above, the layout line will
1259       look like
1260
1261           log4perl.appender.A1.layout =
1262
1263       to Log::Log4perl which causes it to report an error. To interpret the
1264       backslash at the end of the line correctly as a line-continuation
1265       character, use the non-interpreting mode of the here-document like in
1266
1267           # *** RIGHT! ***
1268
1269           Log::Log4perl->init( \ <<'END_HERE');
1270               log4perl.logger = WARN, A1
1271               log4perl.appender.A1 = Log::Log4perl::Appender::Screen
1272               log4perl.appender.A1.layout = \
1273                   Log::Log4perl::Layout::PatternLayout
1274               log4perl.appender.A1.layout.ConversionPattern = %m%n
1275           END_HERE
1276
1277           # *** RIGHT! ***
1278
1279       (note the single quotes around 'END_HERE') or use "q{...}" instead of a
1280       here-document and Perl will treat the backslashes at line-end as
1281       intended.
1282
1283   I want to suppress certain messages based on their content!
1284       Let's assume you've plastered all your functions with Log4perl
1285       statements like
1286
1287           sub some_func {
1288
1289               INFO("Begin of function");
1290
1291               # ... Stuff happens here ...
1292
1293               INFO("End of function");
1294           }
1295
1296       to issue two log messages, one at the beginning and one at the end of
1297       each function. Now you want to suppress the message at the beginning
1298       and only keep the one at the end, what can you do? You can't use the
1299       category mechanism, because both messages are issued from the same
1300       package.
1301
1302       Log::Log4perl's custom filters (0.30 or better) provide an interface
1303       for the Log4perl user to step in right before a message gets logged and
1304       decide if it should be written out or suppressed, based on the message
1305       content or other parameters:
1306
1307           use Log::Log4perl qw(:easy);
1308
1309           Log::Log4perl::init( \ <<'EOT' );
1310               log4perl.logger             = INFO, A1
1311               log4perl.appender.A1        = Log::Log4perl::Appender::Screen
1312               log4perl.appender.A1.layout = \
1313                   Log::Log4perl::Layout::PatternLayout
1314               log4perl.appender.A1.layout.ConversionPattern = %m%n
1315
1316               log4perl.filter.M1 = Log::Log4perl::Filter::StringMatch
1317               log4perl.filter.M1.StringToMatch = Begin
1318               log4perl.filter.M1.AcceptOnMatch = false
1319
1320               log4perl.appender.A1.Filter = M1
1321       EOT
1322
1323       The last four statements in the configuration above are defining a
1324       custom filter "M1" of type "Log::Log4perl::Filter::StringMatch", which
1325       comes with Log4perl right out of the box and allows you to define a
1326       text pattern to match (as a perl regular expression) and a flag
1327       "AcceptOnMatch" indicating if a match is supposed to suppress the
1328       message or let it pass through.
1329
1330       The last line then assigns this filter to the "A1" appender, which will
1331       call it every time it receives a message to be logged and throw all
1332       messages out not matching the regular expression "Begin".
1333
1334       Instead of using the standard "Log::Log4perl::Filter::StringMatch"
1335       filter, you can define your own, simply using a perl subroutine:
1336
1337           log4perl.filter.ExcludeBegin  = sub { !/Begin/ }
1338           log4perl.appender.A1.Filter   = ExcludeBegin
1339
1340       For details on custom filters, check Log::Log4perl::Filter.
1341
1342   My new module uses Log4perl -- but what happens if the calling program
1343       didn't configure it?
1344       If a Perl module uses Log::Log4perl, it will typically rely on the
1345       calling program to initialize it. If it is using Log::Log4perl in
1346       ":easy" mode, like in
1347
1348           package MyMod;
1349           use Log::Log4perl qw(:easy);
1350
1351           sub foo {
1352               DEBUG("In foo");
1353           }
1354
1355           1;
1356
1357       and the calling program doesn't initialize Log::Log4perl at all (e.g.
1358       because it has no clue that it's available), Log::Log4perl will
1359       silently ignore all logging messages. However, if the module is using
1360       Log::Log4perl in regular mode like in
1361
1362           package MyMod;
1363           use Log::Log4perl qw(get_logger);
1364
1365           sub foo {
1366               my $logger = get_logger("");
1367               $logger->debug("blah");
1368           }
1369
1370           1;
1371
1372       and the main program is just using the module like in
1373
1374           use MyMode;
1375           MyMode::foo();
1376
1377       then Log::Log4perl will also ignore all logging messages but issue a
1378       warning like
1379
1380           Log4perl: Seems like no initialization happened.
1381           Forgot to call init()?
1382
1383       (only once!) to remind novice users to not forget to initialize the
1384       logging system before using it.  However, if you want to suppress this
1385       message, just add the ":nowarn" target to the module's "use
1386       Log::Log4perl" call:
1387
1388           use Log::Log4perl qw(get_logger :nowarn);
1389
1390       This will have Log::Log4perl silently ignore all logging statements if
1391       no initialization has taken place. If, instead of using init(), you're
1392       using Log4perl's API to define loggers and appenders, the same
1393       notification happens if no call to add_appenders() is made, i.e. no
1394       appenders are defined.
1395
1396       If the module wants to figure out if some other program part has
1397       already initialized Log::Log4perl, it can do so by calling
1398
1399           Log::Log4perl::initialized()
1400
1401       which will return a true value in case Log::Log4perl has been
1402       initialized and a false value if not.
1403
1404   How can I synchronize access to an appender?
1405       If you're using the same instance of an appender in multiple processes,
1406       and each process is passing on messages to the appender in parallel,
1407       you might end up with overlapping log entries.
1408
1409       Typical scenarios include a file appender that you create in the main
1410       program, and which will then be shared between the parent and a forked
1411       child process. Or two separate processes, each initializing a Log4perl
1412       file appender on the same logfile.
1413
1414       Log::Log4perl won't synchronize access to the shared logfile by
1415       default. Depending on your operating system's flush mechanism, buffer
1416       size and the size of your messages, there's a small chance of an
1417       overlap.
1418
1419       The easiest way to prevent overlapping messages in logfiles written to
1420       by multiple processes is setting the file appender's "syswrite" flag
1421       along with a file write mode of "append".  This makes sure that
1422       "Log::Log4perl::Appender::File" uses syswrite() (which is guaranteed to
1423       run uninterrupted) instead of print() which might buffer the message or
1424       get interrupted by the OS while it is writing. And in "append" mode,
1425       the OS kernel ensures that multiple processes share one end-of-file
1426       marker, ensuring that each process writes to the real end of the file.
1427       (The value of "append" for the "mode" parameter is the default setting
1428       in Log4perl's file appender so you don't have to set it explicitly.)
1429
1430             # Guarantees atomic writes
1431
1432           log4perl.category.Bar.Twix          = WARN, Logfile
1433
1434           log4perl.appender.Logfile           = Log::Log4perl::Appender::File
1435           log4perl.appender.Logfile.mode      = append
1436           log4perl.appender.Logfile.syswrite  = 1
1437           log4perl.appender.Logfile.filename  = test.log
1438           log4perl.appender.Logfile.layout    = SimpleLayout
1439
1440       Another guaranteed way of having messages separated with any kind of
1441       appender is putting a Log::Log4perl::Appender::Synchronized composite
1442       appender in between Log::Log4perl and the real appender. It will make
1443       sure to let messages pass through this virtual gate one by one only.
1444
1445       Here's a sample configuration to synchronize access to a file appender:
1446
1447           log4perl.category.Bar.Twix          = WARN, Syncer
1448
1449           log4perl.appender.Logfile           = Log::Log4perl::Appender::File
1450           log4perl.appender.Logfile.autoflush = 1
1451           log4perl.appender.Logfile.filename  = test.log
1452           log4perl.appender.Logfile.layout    = SimpleLayout
1453
1454           log4perl.appender.Syncer            = Log::Log4perl::Appender::Synchronized
1455           log4perl.appender.Syncer.appender   = Logfile
1456
1457       "Log::Log4perl::Appender::Synchronized" uses the "IPC::Shareable"
1458       module and its semaphores, which will slow down writing the log
1459       messages, but ensures sequential access featuring atomic checks.  Check
1460       Log::Log4perl::Appender::Synchronized for details.
1461
1462   Can I use Log::Log4perl with log4j's Chainsaw?
1463       Yes, Log::Log4perl can be configured to send its events to log4j's
1464       graphical log UI Chainsaw.
1465
1466       Here's how it works:
1467
1468       •   Get Guido Carls' <gcarls@cpan.org> Log::Log4perl extension
1469           "Log::Log4perl::Layout::XMLLayout" from CPAN and install it:
1470
1471               perl -MCPAN -eshell
1472               cpan> install Log::Log4perl::Layout::XMLLayout
1473
1474       •   Install and start Chainsaw, which is part of the "log4j"
1475           distribution now (see http://jakarta.apache.org/log4j ). Create a
1476           configuration file like
1477
1478             <log4j:configuration debug="true">
1479               <plugin name="XMLSocketReceiver"
1480                       class="org.apache.log4j.net.XMLSocketReceiver">
1481                 <param name="decoder" value="org.apache.log4j.xml.XMLDecoder"/>
1482                 <param name="Port" value="4445"/>
1483               </plugin>
1484               <root> <level value="debug"/> </root>
1485             </log4j:configuration>
1486
1487           and name it e.g. "config.xml". Then start Chainsaw like
1488
1489             java -Dlog4j.debug=true -Dlog4j.configuration=config.xml \
1490               -classpath ".:log4j-1.3alpha.jar:log4j-chainsaw-1.3alpha.jar" \
1491               org.apache.log4j.chainsaw.LogUI
1492
1493           and watch the GUI coming up.
1494
1495       •   Configure Log::Log4perl to use a socket appender with an XMLLayout,
1496           pointing to the host/port where Chainsaw (as configured above) is
1497           waiting with its XMLSocketReceiver:
1498
1499             use Log::Log4perl qw(get_logger);
1500             use Log::Log4perl::Layout::XMLLayout;
1501
1502             my $conf = q(
1503               log4perl.category.Bar.Twix          = WARN, Appender
1504               log4perl.appender.Appender          = Log::Log4perl::Appender::Socket
1505               log4perl.appender.Appender.PeerAddr = localhost
1506               log4perl.appender.Appender.PeerPort = 4445
1507               log4perl.appender.Appender.layout   = Log::Log4perl::Layout::XMLLayout
1508             );
1509
1510             Log::Log4perl::init(\$conf);
1511
1512               # Nasty hack to suppress encoding header
1513             my $app = Log::Log4perl::appenders->{"Appender"};
1514             $app->layout()->{enc_set} = 1;
1515
1516             my $logger = get_logger("Bar.Twix");
1517             $logger->error("One");
1518
1519           The nasty hack shown in the code snippet above is currently
1520           (October 2003) necessary, because Chainsaw expects XML messages to
1521           arrive in a format like
1522
1523             <log4j:event logger="Bar.Twix"
1524                          timestamp="1066794904310"
1525                          level="ERROR"
1526                          thread="10567">
1527               <log4j:message><![CDATA[Two]]></log4j:message>
1528               <log4j:NDC><![CDATA[undef]]></log4j:NDC>
1529               <log4j:locationInfo class="main"
1530                 method="main"
1531                 file="./t"
1532                 line="32">
1533               </log4j:locationInfo>
1534             </log4j:event>
1535
1536           without a preceding
1537
1538             <?xml version = "1.0" encoding = "iso8859-1"?>
1539
1540           which Log::Log4perl::Layout::XMLLayout applies to the first event
1541           sent over the socket.
1542
1543       See figure 1 for a screenshot of Chainsaw in action, receiving events
1544       from the Perl script shown above.
1545
1546       Many thanks to Chainsaw's Scott Deboy <sdeboy@comotivsystems.com> for
1547       his support!
1548
1549   How can I run Log::Log4perl under mod_perl?
1550       In persistent environments it's important to play by the rules outlined
1551       in section "Initialize once and only once" in Log::Log4perl.  If you
1552       haven't read this yet, please go ahead and read it right now. It's very
1553       important.
1554
1555       And no matter if you use a startup handler to init() Log::Log4perl or
1556       use the init_once() strategy (added in 0.42), either way you're very
1557       likely to have unsynchronized writes to logfiles.
1558
1559       If Log::Log4perl is configured with a log file appender, and it is
1560       initialized via the Apache startup handler, the file handle created
1561       initially will be shared among all Apache processes. Similarly, with
1562       the init_once() approach: although every process has a separate L4p
1563       configuration, processes are gonna share the appender file names
1564       instead, effectively opening several different file handles on the same
1565       file.
1566
1567       Now, having several appenders using the same file handle or having
1568       several appenders logging to the same file unsynchronized, this might
1569       result in overlapping messages. Sometimes, this is acceptable. If it's
1570       not, here's two strategies:
1571
1572       •   Use the Log::Log4perl::Appender::Synchronized appender to connect
1573           to your file appenders. Here's the writeup:
1574           http://log4perl.sourceforge.net/releases/Log-Log4perl/docs/html/Log/Log4perl/FAQ.html#23804
1575
1576       •   Use a different logfile for every process like in
1577
1578                #log4perl.conf
1579                ...
1580                log4perl.appender.A1.filename = sub { "mylog.$$.log" }
1581
1582   My program already uses warn() and die(). How can I switch to Log4perl?
1583       If your program already uses Perl's warn() function to spew out error
1584       messages and you'd like to channel those into the Log4perl world, just
1585       define a "__WARN__" handler where your program or module resides:
1586
1587           use Log::Log4perl qw(:easy);
1588
1589           $SIG{__WARN__} = sub {
1590               local $Log::Log4perl::caller_depth =
1591                   $Log::Log4perl::caller_depth + 1;
1592               WARN @_;
1593           };
1594
1595       Why the "local" setting of $Log::Log4perl::caller_depth?  If you leave
1596       that out, "PatternLayout" conversion specifiers like %M or %F (printing
1597       the current function/method and source filename) will refer to where
1598       the __WARN__ handler resides, not the environment Perl's warn()
1599       function was issued from. Increasing "caller_depth" adjusts for this
1600       offset. Having it "local", makes sure the level gets set back after the
1601       handler exits.
1602
1603       Once done, if your program does something like
1604
1605           sub some_func {
1606               warn "Here's a warning";
1607           }
1608
1609       you'll get (depending on your Log::Log4perl configuration) something
1610       like
1611
1612           2004/02/19 20:41:02-main::some_func: Here's a warning at ./t line 25.
1613
1614       in the appropriate appender instead of having a screen full of STDERR
1615       messages. It also works with the "Carp" module and its carp() and
1616       cluck() functions.
1617
1618       If, on the other hand, catching die() and friends is required, a
1619       "__DIE__" handler is appropriate:
1620
1621           $SIG{__DIE__} = sub {
1622               if($^S) {
1623                   # We're in an eval {} and don't want log
1624                   # this message but catch it later
1625                   return;
1626               }
1627               local $Log::Log4perl::caller_depth =
1628                   $Log::Log4perl::caller_depth + 1;
1629               LOGDIE @_;
1630           };
1631
1632       This will call Log4perl's LOGDIE() function, which will log a fatal
1633       error and then call die() internally, causing the program to exit.
1634       Works equally well with "Carp"'s croak() and confess() functions.
1635
1636   Some module prints messages to STDERR. How can I funnel them to
1637       Log::Log4perl?
1638       If a module you're using doesn't use Log::Log4perl but prints logging
1639       messages to STDERR instead, like
1640
1641           ########################################
1642           package IgnorantModule;
1643           ########################################
1644
1645           sub some_method {
1646               print STDERR "Parbleu! An error!\n";
1647           }
1648
1649           1;
1650
1651       there's still a way to capture these messages and funnel them into
1652       Log::Log4perl, even without touching the module. What you need is a
1653       trapper module like
1654
1655           ########################################
1656           package Trapper;
1657           ########################################
1658
1659           use Log::Log4perl qw(:easy);
1660
1661           sub TIEHANDLE {
1662               my $class = shift;
1663               bless [], $class;
1664           }
1665
1666           sub PRINT {
1667               my $self = shift;
1668               $Log::Log4perl::caller_depth++;
1669               DEBUG @_;
1670               $Log::Log4perl::caller_depth--;
1671           }
1672
1673           1;
1674
1675       and a "tie" command in the main program to tie STDERR to the trapper
1676       module along with regular Log::Log4perl initialization:
1677
1678           ########################################
1679           package main;
1680           ########################################
1681
1682           use Log::Log4perl qw(:easy);
1683
1684           Log::Log4perl->easy_init(
1685               {level  => $DEBUG,
1686                file   => 'stdout',   # make sure not to use stderr here!
1687                layout => "%d %M: %m%n",
1688               });
1689
1690           tie *STDERR, "Trapper";
1691
1692       Make sure not to use STDERR as Log::Log4perl's file appender here
1693       (which would be the default in ":easy" mode), because it would end up
1694       in an endless recursion.
1695
1696       Now, calling
1697
1698           IgnorantModule::some_method();
1699
1700       will result in the desired output
1701
1702           2004/05/06 11:13:04 IgnorantModule::some_method: Parbleu! An error!
1703
1704   How come PAR (Perl Archive Toolkit) creates executables which then can't
1705       find their Log::Log4perl appenders?
1706       If not instructed otherwise, "Log::Log4perl" dynamically pulls in
1707       appender classes found in its configuration. If you specify
1708
1709           #!/usr/bin/perl
1710           # mytest.pl
1711
1712           use Log::Log4perl qw(get_logger);
1713
1714           my $conf = q(
1715             log4perl.category.Bar.Twix = WARN, Logfile
1716             log4perl.appender.Logfile  = Log::Log4perl::Appender::Screen
1717             log4perl.appender.Logfile.layout = SimpleLayout
1718           );
1719
1720           Log::Log4perl::init(\$conf);
1721           my $logger = get_logger("Bar::Twix");
1722           $logger->error("Blah");
1723
1724       then "Log::Log4perl::Appender::Screen" will be pulled in while the
1725       program runs, not at compile time. If you have PAR compile the script
1726       above to an executable binary via
1727
1728           pp -o mytest mytest.pl
1729
1730       and then run "mytest" on a machine without having Log::Log4perl
1731       installed, you'll get an error message like
1732
1733           ERROR: can't load appenderclass 'Log::Log4perl::Appender::Screen'
1734           Can't locate Log/Log4perl/Appender/Screen.pm in @INC ...
1735
1736       Why? At compile time, "pp" didn't realize that
1737       "Log::Log4perl::Appender::Screen" would be needed later on and didn't
1738       wrap it into the executable created. To avoid this, either say "use
1739       Log::Log4perl::Appender::Screen" in the script explicitly or compile it
1740       with
1741
1742           pp -o mytest -M Log::Log4perl::Appender::Screen mytest.pl
1743
1744       to make sure the appender class gets included.
1745
1746   How can I access a custom appender defined in the configuration?
1747       Any appender defined in the configuration file or somewhere in the code
1748       can be accessed later via
1749       "Log::Log4perl->appender_by_name("appender_name")", which returns a
1750       reference of the appender object.
1751
1752       Once you've got a hold of the object, it can be queried or modified to
1753       your liking. For example, see the custom "IndentAppender" defined
1754       below: After calling init() to define the Log4perl settings, the
1755       appender object is retrieved to call its indent_more() and
1756       indent_less() methods to control indentation of messages:
1757
1758           package IndentAppender;
1759
1760           sub new {
1761               bless { indent => 0 }, $_[0];
1762           }
1763
1764           sub indent_more  { $_[0]->{indent}++ }
1765           sub indent_less  { $_[0]->{indent}-- }
1766
1767           sub log {
1768               my($self, %params) = @_;
1769               print " " x $self->{indent}, $params{message};
1770           }
1771
1772           package main;
1773
1774           use Log::Log4perl qw(:easy);
1775
1776           my $conf = q(
1777           log4perl.category          = DEBUG, Indented
1778           log4perl.appender.Indented = IndentAppender
1779           log4perl.appender.Indented.layout = Log::Log4perl::Layout::SimpleLayout
1780           );
1781
1782           Log::Log4perl::init(\$conf);
1783
1784           my $appender = Log::Log4perl->appender_by_name("Indented");
1785
1786           DEBUG "No identation";
1787           $appender->indent_more();
1788           DEBUG "One more";
1789           $appender->indent_more();
1790           DEBUG "Two more";
1791           $appender->indent_less();
1792           DEBUG "One less";
1793
1794       As you would expect, this will print
1795
1796           DEBUG - No identation
1797            DEBUG - One more
1798             DEBUG - Two more
1799            DEBUG - One less
1800
1801       because the very appender used by Log4perl is modified dynamically at
1802       runtime.
1803
1804   I don't know if Log::Log4perl is installed. How can I prepare my script?
1805       In case your script needs to be prepared for environments that may or
1806       may not have Log::Log4perl installed, there's a trick.
1807
1808       If you put the following BEGIN blocks at the top of the program, you'll
1809       be able to use the DEBUG(), INFO(), etc. macros in Log::Log4perl's
1810       ":easy" mode.  If Log::Log4perl is installed in the target environment,
1811       the regular Log::Log4perl rules apply. If not, all of DEBUG(), INFO(),
1812       etc. are "stubbed" out, i.e. they turn into no-ops:
1813
1814           use warnings;
1815           use strict;
1816
1817           BEGIN {
1818               eval { require Log::Log4perl; };
1819
1820               if($@) {
1821                   print "Log::Log4perl not installed - stubbing.\n";
1822                   no strict qw(refs);
1823                   *{"main::$_"} = sub { } for qw(DEBUG INFO WARN ERROR FATAL);
1824               } else {
1825                   no warnings;
1826                   print "Log::Log4perl installed - life is good.\n";
1827                   require Log::Log4perl::Level;
1828                   Log::Log4perl::Level->import(__PACKAGE__);
1829                   Log::Log4perl->import(qw(:easy));
1830                   Log::Log4perl->easy_init($main::DEBUG);
1831               }
1832           }
1833
1834               # The regular script begins ...
1835           DEBUG "Hey now!";
1836
1837       This snippet will first probe for Log::Log4perl, and if it can't be
1838       found, it will alias DEBUG(), INFO(), with empty subroutines via
1839       typeglobs.  If Log::Log4perl is available, its level constants are
1840       first imported ($DEBUG, $INFO, etc.) and then easy_init() gets called
1841       to initialize the logging system.
1842
1843   Can file appenders create files with different permissions?
1844       Typically, when "Log::Log4perl::Appender::File" creates a new file, its
1845       permissions are set to "rw-r--r--". Why? Because your environment's
1846       umask most likely defaults to 0022, that's the standard setting.
1847
1848       What's a umask, you're asking? It's a template that's applied to the
1849       permissions of all newly created files. While calls like "open(FILE,
1850       ">foo")" will always try to create files in "rw-rw-rw- " mode, the
1851       system will apply the current umask template to determine the final
1852       permission setting. umask is a bit mask that's inverted and then
1853       applied to the requested permission setting, using a bitwise AND:
1854
1855           $request_permission &~ $umask
1856
1857       So, a umask setting of 0000 (the leading 0 simply indicates an octal
1858       value) will create files in "rw-rw-rw-" mode, a setting of 0277 will
1859       use "r--------", and the standard 0022 will use "rw-r--r--".
1860
1861       As an example, if you want your log files to be created with
1862       "rw-r--rw-" permissions, use a umask of 0020 before calling
1863       Log::Log4perl->init():
1864
1865           use Log::Log4perl;
1866
1867           umask 0020;
1868               # Creates log.out in rw-r--rw mode
1869           Log::Log4perl->init(\ q{
1870               log4perl.logger = WARN, File
1871               log4perl.appender.File = Log::Log4perl::Appender::File
1872               log4perl.appender.File.filename = log.out
1873               log4perl.appender.File.layout = SimpleLayout
1874           });
1875
1876   Using Log4perl in an END block causes a problem!
1877       It's not easy to get to this error, but if you write something like
1878
1879           END { Log::Log4perl::get_logger()->debug("Hey there."); }
1880
1881           use Log::Log4perl qw(:easy);
1882           Log::Log4perl->easy_init($DEBUG);
1883
1884       it won't work. The reason is that "Log::Log4perl" defines an END block
1885       that cleans up all loggers. And perl will run END blocks in the reverse
1886       order as they're encountered in the compile phase, so in the scenario
1887       above, the END block will run after Log4perl has cleaned up its
1888       loggers.
1889
1890       Placing END blocks using Log4perl after a "use Log::Log4perl" statement
1891       fixes the problem:
1892
1893           use Log::Log4perl qw(:easy);
1894           Log::Log4perl->easy_init($DEBUG);
1895
1896           END { Log::Log4perl::get_logger()->debug("Hey there."); }
1897
1898       In this scenario, the shown END block is executed before Log4perl
1899       cleans up and the debug message will be processed properly.
1900
1901   Help! My appender is throwing a "Wide character in print" warning!
1902       This warning shows up when Unicode strings are printed without
1903       precautions. The warning goes away if the complaining appender is set
1904       to utf-8 mode:
1905
1906             # Either in the log4perl configuration file:
1907         log4perl.appender.Logfile.filename = test.log
1908         log4perl.appender.Logfile.utf8     = 1
1909
1910             # Or, in easy mode:
1911         Log::Log4perl->easy_init( {
1912           level => $DEBUG,
1913           file  => ":utf8> test.log"
1914         } );
1915
1916       If the complaining appender is a screen appender, set its "utf8"
1917       option:
1918
1919             log4perl.appender.Screen.stderr = 1
1920             log4perl.appender.Screen.utf8   = 1
1921
1922       Alternatively, "binmode" does the trick:
1923
1924             # Either STDOUT ...
1925           binmode(STDOUT, ":utf8);
1926
1927             # ... or STDERR.
1928           binmode(STDERR, ":utf8);
1929
1930       Some background on this: Perl's strings are either byte strings or
1931       Unicode strings. "Mike" is a byte string.  "\x{30DE}\x{30A4}\x{30AF}"
1932       is a Unicode string. Unicode strings are marked specially and are UTF-8
1933       encoded internally.
1934
1935       If you print a byte string to STDOUT, all is well, because STDOUT is by
1936       default set to byte mode. However, if you print a Unicode string to
1937       STDOUT without precautions, "perl" will try to transform the Unicode
1938       string back to a byte string before printing it out. This is
1939       troublesome if the Unicode string contains 'wide' characters which
1940       can't be represented in Latin-1.
1941
1942       For example, if you create a Unicode string with three japanese
1943       Katakana characters as in
1944
1945           perl -le 'print "\x{30DE}\x{30A4}\x{30AF}"'
1946
1947       (coincidentally pronounced Ma-i-ku, the japanese pronunciation of
1948       "Mike"), STDOUT is in byte mode and the warning
1949
1950           Wide character in print at ./script.pl line 14.
1951
1952       appears. Setting STDOUT to UTF-8 mode as in
1953
1954           perl -le 'binmode(STDOUT, ":utf8"); print "\x{30DE}\x{30A4}\x{30AF}"'
1955
1956       will silently print the Unicode string to STDOUT in UTF-8. To see the
1957       characters printed, you'll need a UTF-8 terminal with a font including
1958       japanese Katakana characters.
1959
1960   How can I send errors to the screen, and debug messages to a file?
1961       Let's assume you want to maintain a detailed DEBUG output in a file and
1962       only messages of level ERROR and higher should be printed on the
1963       screen. Often times, developers come up with something like this:
1964
1965            # Wrong!!!
1966           log4perl.logger = DEBUG, FileApp
1967           log4perl.logger = ERROR, ScreenApp
1968            # Wrong!!!
1969
1970       This won't work, however. Logger definitions aren't additive, and the
1971       second statement will overwrite the first one. Log4perl versions below
1972       1.04 were silently accepting this, leaving people confused why it
1973       wouldn't work as expected.  As of 1.04, this will throw a fatal error
1974       to notify the user of the problem.
1975
1976       What you want to do instead, is this:
1977
1978           log4perl.logger                    = DEBUG, FileApp, ScreenApp
1979
1980           log4perl.appender.FileApp          = Log::Log4perl::Appender::File
1981           log4perl.appender.FileApp.filename = test.log
1982           log4perl.appender.FileApp.layout   = SimpleLayout
1983
1984           log4perl.appender.ScreenApp          = Log::Log4perl::Appender::Screen
1985           log4perl.appender.ScreenApp.stderr   = 0
1986           log4perl.appender.ScreenApp.layout   = SimpleLayout
1987              ### limiting output to ERROR messages
1988           log4perl.appender.ScreenApp.Threshold = ERROR
1989              ###
1990
1991       Note that without the second appender's "Threshold" setting, both
1992       appenders would receive all messages prioritized DEBUG and higher. With
1993       the threshold set to ERROR, the second appender will filter the
1994       messages as required.
1995
1996   Where should I put my logfiles?
1997       Your log files may go anywhere you want them, but the effective user id
1998       of the calling process must have write access.
1999
2000       If the log file doesn't exist at program start, Log4perl's file
2001       appender will create it. For this, it needs write access to the
2002       directory where the new file will be located in. If the log file
2003       already exists at startup, the process simply needs write access to the
2004       file. Note that it will need write access to the file's directory if
2005       you're encountering situations where the logfile gets recreated, e.g.
2006       during log rotation.
2007
2008       If Log::Log4perl is used by a web server application (e.g. in a CGI
2009       script or mod_perl), then the webserver's user (usually "nobody" or
2010       "www") must have the permissions mentioned above.
2011
2012       To prepare your web server to use log4perl, we'd recommend:
2013
2014           webserver:~$ su -
2015           webserver:~# mkdir /var/log/cgiapps
2016           webserver:~# chown nobody:root /var/log/cgiapps/
2017           webserver:~# chown nobody:root -R /var/log/cgiapps/
2018           webserver:~# chmod 02755 -R /var/log/cgiapps/
2019
2020       Then set your /etc/log4perl.conf file to include:
2021
2022           log4perl.appender.FileAppndr1.filename =
2023               /var/log/cgiapps/<app-name>.log
2024
2025   How can my file appender deal with disappearing log files?
2026       The file appender that comes with Log4perl,
2027       Log::Log4perl::Appender::File, will open a specified log file at
2028       initialization time and will keep writing to it via a file handle.
2029
2030       In case the associated file goes way, messages written by a long-
2031       running process will still be written to the file handle. In case the
2032       file has been moved to a different location on the same file system,
2033       the writer will keep writing to it under the new filename. In case the
2034       file has been removed from the file system, the log messages will end
2035       up in nowhere land. This is not a bug in Log4perl, this is how Unix
2036       works. There is no error message in this case, because the writer has
2037       no idea that the file handle is not associated with a visible file.
2038
2039       To prevent the loss of log messages when log files disappear, the file
2040       appender's "recreate" option needs to be set to a true value:
2041
2042           log4perl.appender.Logfile.recreate = 1
2043
2044       This will instruct the file appender to check in regular intervals
2045       (default: 30 seconds) if the log file is still there. If it finds out
2046       that the file is missing, it will recreate it.
2047
2048       Continuously checking if the log file still exists is fairly expensive.
2049       For this reason it is only performed every 30 seconds. To change this
2050       interval, the option "recreate_check_interval" can be set to the number
2051       of seconds between checks. In the extreme case where the check should
2052       be performed before every write, it can even be set to 0:
2053
2054           log4perl.appender.Logfile.recreate = 1
2055           log4perl.appender.Logfile.recreate_check_interval = 0
2056
2057       To avoid having to check the file system so frequently, a signal
2058       handler can be set up:
2059
2060           log4perl.appender.Logfile.recreate = 1
2061           log4perl.appender.Logfile.recreate_check_signal = USR1
2062
2063       This will install a signal handler which will recreate a missing log
2064       file immediately when it receives the defined signal.
2065
2066       Note that the init_and_watch() method for Log4perl's initialization can
2067       also be instructed to install a signal handler, usually using the HUP
2068       signal. Make sure to use a different signal if you're using both of
2069       them at the same time.
2070
2071   How can I rotate a logfile with newsyslog?
2072       Here's a few things that need to be taken care of when using the
2073       popular log file rotating utility "newsyslog"
2074       (http://www.courtesan.com/newsyslog) with Log4perl's file appender in
2075       long-running processes.
2076
2077       For example, with a newsyslog configuration like
2078
2079           # newsyslog.conf
2080           /tmp/test.log 666  12  5  *  B
2081
2082       and a call to
2083
2084           # newsyslog -f /path/to/newsyslog.conf
2085
2086       "newsyslog" will take action if "/tmp/test.log" is larger than the
2087       specified 5K in size. It will move the current log file "/tmp/test.log"
2088       to "/tmp/test.log.0" and create a new and empty "/tmp/test.log" with
2089       the specified permissions (this is why "newsyslog" needs to run as
2090       root).  An already existing "/tmp/test.log.0" would be moved to
2091       "/tmp/test.log.1", "/tmp/test.log.1" to "/tmp/test.log.2", and so
2092       forth, for every one of a max number of 12 archived logfiles that have
2093       been configured in "newsyslog.conf".
2094
2095       Although a new file has been created, from Log4perl's appender's point
2096       of view, this situation is identical to the one described in the
2097       previous FAQ entry, labeled "How can my file appender deal with
2098       disappearing log files".
2099
2100       To make sure that log messages are written to the new log file and not
2101       to an archived one or end up in nowhere land, the appender's "recreate"
2102       and "recreate_check_interval" have to be configured to deal with the
2103       'disappearing' log file.
2104
2105       The situation gets interesting when "newsyslog"'s option to compress
2106       archived log files is enabled. This causes the original log file not to
2107       be moved, but to disappear. If the file appender isn't configured to
2108       recreate the logfile in this situation, log messages will actually be
2109       lost without warning. This also applies for the short time frame of
2110       "recreate_check_interval" seconds in between the recreator's file
2111       checks.
2112
2113       To make sure that no messages get lost, one option is to set the
2114       interval to
2115
2116           log4perl.appender.Logfile.recreate_check_interval = 0
2117
2118       However, this is fairly expensive. A better approach is to define a
2119       signal handler:
2120
2121           log4perl.appender.Logfile.recreate = 1
2122           log4perl.appender.Logfile.recreate_check_signal  = USR1
2123           log4perl.appender.Logfile.recreate_pid_write = /tmp/myappid
2124
2125       As a service for "newsyslog" users, Log4perl's file appender writes the
2126       current process ID to a PID file specified by the "recreate_pid_write"
2127       option.  "newsyslog" then needs to be configured as in
2128
2129           # newsyslog.conf configuration for compressing archive files and
2130           # sending a signal to the Log4perl-enabled application
2131           /tmp/test.log 666  12  5  *  B /tmp/myappid 30
2132
2133       to send the defined signal (30, which is USR1 on FreeBSD) to the
2134       application process at rotation time. Note that the signal number is
2135       different on Linux, where USR1 denotes as 10. Check "man signal" for
2136       details.
2137
2138   How can a process under user id A log to a file under user id B?
2139       This scenario often occurs in configurations where processes run under
2140       various user IDs but need to write to a log file under a fixed, but
2141       different user id.
2142
2143       With a traditional file appender, the log file will probably be created
2144       under one user's id and appended to under a different user's id. With a
2145       typical umask of 0002, the file will be created with -rw-rw-r--
2146       permissions. If a user who's not in the first user's group subsequently
2147       appends to the log file, it will fail because of a permission problem.
2148
2149       Two potential solutions come to mind:
2150
2151       •   Creating the file with a umask of 0000 will allow all users to
2152           append to the log file. Log4perl's file appender
2153           "Log::Log4perl::Appender::File" has an "umask" option that can be
2154           set to support this:
2155
2156               log4perl.appender.File = Log::Log4perl::Appender::File
2157               log4perl.appender.File.umask = sub { 0000 };
2158
2159           This way, the log file will be created with -rw-rw-rw- permissions
2160           and therefore has world write permissions. This might open up the
2161           logfile for unwanted manipulations by arbitrary users, though.
2162
2163       •   Running the process under an effective user id of "root" will allow
2164           it to write to the log file, no matter who started the process.
2165           However, this is not a good idea, because of security concerns.
2166
2167       Luckily, under Unix, there's the syslog daemon which runs as root and
2168       takes log requests from user processes over a socket and writes them to
2169       log files as configured in "/etc/syslog.conf".
2170
2171       By modifying "/etc/syslog.conf" and HUPing the syslog daemon, you can
2172       configure new log files:
2173
2174           # /etc/syslog.conf
2175           ...
2176           user.* /some/path/file.log
2177
2178       Using the "Log::Dispatch::Syslog" appender, which comes with the
2179       "Log::Log4perl" distribution, you can then send messages via syslog:
2180
2181           use Log::Log4perl qw(:easy);
2182
2183           Log::Log4perl->init(\<<EOT);
2184               log4perl.logger = DEBUG, app
2185               log4perl.appender.app=Log::Dispatch::Syslog
2186               log4perl.appender.app.Facility=user
2187               log4perl.appender.app.layout=SimpleLayout
2188           EOT
2189
2190               # Writes to /some/path/file.log
2191           ERROR "Message!";
2192
2193       This way, the syslog daemon will solve the permission problem.
2194
2195       Note that while it is possible to use syslog() without Log4perl (syslog
2196       supports log levels, too), traditional syslog setups have a significant
2197       drawback.
2198
2199       Without Log4perl's ability to activate logging in only specific parts
2200       of a system, complex systems will trigger log events all over the place
2201       and slow down execution to a crawl at high debug levels.
2202
2203       Remote-controlling logging in the hierarchical parts of an application
2204       via Log4perl's categories is one of its most distinguished features.
2205       It allows for enabling high debug levels in specified areas without
2206       noticeable performance impact.
2207
2208   I want to use UTC instead of the local time!
2209       If a layout defines a date, Log::Log4perl uses local time to populate
2210       it.  If you want UTC instead, set
2211
2212           log4perl.utcDateTimes = 1
2213
2214       in your configuration. Alternatively, you can set
2215
2216           $Log::Log4perl::DateFormat::GMTIME = 1;
2217
2218       in your program before the first log statement.
2219
2220   Can Log4perl intercept messages written to a filehandle?
2221       You have a function that prints to a filehandle. You want to tie into
2222       that filehandle and forward all arriving messages to a Log4perl logger.
2223
2224       First, let's write a package that ties a file handle and forwards it to
2225       a Log4perl logger:
2226
2227           package FileHandleLogger;
2228           use Log::Log4perl qw(:levels get_logger);
2229
2230           sub TIEHANDLE {
2231              my($class, %options) = @_;
2232
2233              my $self = {
2234                  level    => $DEBUG,
2235                  category => '',
2236                  %options
2237              };
2238
2239              $self->{logger} = get_logger($self->{category}),
2240              bless $self, $class;
2241           }
2242
2243           sub PRINT {
2244               my($self, @rest) = @_;
2245               $Log::Log4perl::caller_depth++;
2246               $self->{logger}->log($self->{level}, @rest);
2247               $Log::Log4perl::caller_depth--;
2248           }
2249
2250           sub PRINTF {
2251               my($self, $fmt, @rest) = @_;
2252               $Log::Log4perl::caller_depth++;
2253               $self->PRINT(sprintf($fmt, @rest));
2254               $Log::Log4perl::caller_depth--;
2255           }
2256
2257           1;
2258
2259       Now, if you have a function like
2260
2261           sub function_printing_to_fh {
2262               my($fh) = @_;
2263               printf $fh "Hi there!\n";
2264           }
2265
2266       which takes a filehandle and prints something to it, it can be used
2267       with Log4perl:
2268
2269           use Log::Log4perl qw(:easy);
2270           usa FileHandleLogger;
2271
2272           Log::Log4perl->easy_init($DEBUG);
2273
2274           tie *SOMEHANDLE, 'FileHandleLogger' or
2275               die "tie failed ($!)";
2276
2277           function_printing_to_fh(*SOMEHANDLE);
2278               # prints "2007/03/22 21:43:30 Hi there!"
2279
2280       If you want, you can even specify a different log level or category:
2281
2282           tie *SOMEHANDLE, 'FileHandleLogger',
2283               level => $INFO, category => "Foo::Bar" or die "tie failed ($!)";
2284
2285   I want multiline messages rendered line-by-line!
2286       With the standard "PatternLayout", if you send a multiline message to
2287       an appender as in
2288
2289           use Log::Log4perl qw(:easy);
2290           Log
2291
2292       it gets rendered this way:
2293
2294           2007/04/04 23:23:39 multi
2295           line
2296           message
2297
2298       If you want each line to be rendered separately according to the layout
2299       use "Log::Log4perl::Layout::PatternLayout::Multiline":
2300
2301           use Log::Log4perl qw(:easy);
2302
2303           Log::Log4perl->init(\<<EOT);
2304             log4perl.category         = DEBUG, Screen
2305             log4perl.appender.Screen = Log::Log4perl::Appender::Screen
2306             log4perl.appender.Screen.layout = \\
2307               Log::Log4perl::Layout::PatternLayout::Multiline
2308             log4perl.appender.Screen.layout.ConversionPattern = %d %m %n
2309           EOT
2310
2311           DEBUG "some\nmultiline\nmessage";
2312
2313       and you'll get
2314
2315           2007/04/04 23:23:39 some
2316           2007/04/04 23:23:39 multiline
2317           2007/04/04 23:23:39 message
2318
2319       instead.
2320
2321   I'm on Windows and I'm getting all these 'redefined' messages!
2322       If you're on Windows and are getting warning messages like
2323
2324         Constant subroutine Log::Log4perl::_INTERNAL_DEBUG redefined at
2325           C:/Programme/Perl/lib/constant.pm line 103.
2326         Subroutine import redefined at
2327           C:/Programme/Perl/site/lib/Log/Log4Perl.pm line 69.
2328         Subroutine initialized redefined at
2329           C:/Programme/Perl/site/lib/Log/Log4Perl.pm line 207.
2330
2331       then chances are that you're using 'Log::Log4Perl' (wrong uppercase P)
2332       instead of the correct 'Log::Log4perl'. Perl on Windows doesn't handle
2333       this error well and spits out a slew of confusing warning messages. But
2334       now you know, just use the correct module name and you'll be fine.
2335
2336   Log4perl complains that no initialization happened during shutdown!
2337       If you're using Log4perl log commands in DESTROY methods of your
2338       objects, you might see confusing messages like
2339
2340           Log4perl: Seems like no initialization happened. Forgot to call init()?
2341           Use of uninitialized value in subroutine entry at
2342           /home/y/lib/perl5/site_perl/5.6.1/Log/Log4perl.pm line 134 during global
2343           destruction. (in cleanup) Undefined subroutine &main:: called at
2344           /home/y/lib/perl5/site_perl/5.6.1/Log/Log4perl.pm line 134 during global
2345           destruction.
2346
2347       when the program shuts down. What's going on?
2348
2349       This phenomenon happens if you have circular references in your
2350       objects, which perl can't clean up when an object goes out of scope but
2351       waits until global destruction instead. At this time, however, Log4perl
2352       has already shut down, so you can't use it anymore.
2353
2354       For example, here's a simple class which uses a logger in its DESTROY
2355       method:
2356
2357           package A;
2358           use Log::Log4perl qw(:easy);
2359           sub new { bless {}, shift }
2360           sub DESTROY { DEBUG "Waaah!"; }
2361
2362       Now, if the main program creates a self-referencing object, like in
2363
2364           package main;
2365           use Log::Log4perl qw(:easy);
2366           Log::Log4perl->easy_init($DEBUG);
2367
2368           my $a = A->new();
2369           $a->{selfref} = $a;
2370
2371       then you'll see the error message shown above during global
2372       destruction.  How to tackle this problem?
2373
2374       First, you should clean up your circular references before global
2375       destruction. They will not only cause objects to be destroyed in an
2376       order that's hard to predict, but also eat up memory until the program
2377       shuts down.
2378
2379       So, the program above could easily be fixed by putting
2380
2381           $a->{selfref} = undef;
2382
2383       at the end or in an END handler. If that's hard to do, use weak
2384       references:
2385
2386           package main;
2387           use Scalar::Util qw(weaken);
2388           use Log::Log4perl qw(:easy);
2389           Log::Log4perl->easy_init($DEBUG);
2390
2391           my $a = A->new();
2392           $a->{selfref} = weaken $a;
2393
2394       This allows perl to clean up the circular reference when the object
2395       goes out of scope, and doesn't wait until global destruction.
2396
2397   How can I access POE heap values from Log4perl's layout?
2398       POE is a framework for creating multitasked applications running in a
2399       single process and a single thread. POE's threads equivalents are
2400       'sessions' and since they run quasi-simultaneously, you can't use
2401       Log4perl's global NDC/MDC to hold session-specific data.
2402
2403       However, POE already maintains a data store for every session. It is
2404       called 'heap' and is just a hash storing session-specific data in key-
2405       value pairs.  To access this per-session heap data from a Log4perl
2406       layout, define a custom cspec and reference it with the newly defined
2407       pattern in the layout:
2408
2409           use strict;
2410           use POE;
2411           use Log::Log4perl qw(:easy);
2412
2413           Log::Log4perl->init( \ q{
2414               log4perl.logger = DEBUG, Screen
2415               log4perl.appender.Screen = Log::Log4perl::Appender::Screen
2416               log4perl.appender.Screen.layout = PatternLayout
2417               log4perl.appender.Screen.layout.ConversionPattern = %U %m%n
2418               log4perl.PatternLayout.cspec.U = \
2419                   sub { POE::Kernel->get_active_session->get_heap()->{ user } }
2420           } );
2421
2422           for (qw( Huey Lewey Dewey )) {
2423               POE::Session->create(
2424                   inline_states => {
2425                       _start    => sub {
2426                           $_[HEAP]->{user} = $_;
2427                           POE::Kernel->yield('hello');
2428                       },
2429                       hello     => sub {
2430                           DEBUG "I'm here now";
2431                       }
2432                   }
2433               );
2434           }
2435
2436           POE::Kernel->run();
2437           exit;
2438
2439       The code snippet above defines a new layout placeholder (called 'cspec'
2440       in Log4perl) %U which calls a subroutine, retrieves the active session,
2441       gets its heap and looks up the entry specified ('user').
2442
2443       Starting with Log::Log4perl 1.20, cspecs also support parameters in
2444       curly braces, so you can say
2445
2446           log4perl.appender.Screen.layout.ConversionPattern = %U{user} %U{id} %m%n
2447           log4perl.PatternLayout.cspec.U = \
2448                   sub { POE::Kernel->get_active_session-> \
2449                         get_heap()->{ $_[0]->{curlies} } }
2450
2451       and print the POE session heap entries 'user' and 'id' with every
2452       logged message. For more details on cpecs, read the PatternLayout
2453       manual.
2454
2455   I want to print something unconditionally!
2456       Sometimes it's a script that's supposed to log messages regardless if
2457       Log4perl has been initialized or not. Or there's a logging statement
2458       that's not going to be suppressed under any circumstances -- many
2459       people want to have the final word, make the executive decision,
2460       because it seems like the only logical choice.
2461
2462       But think about it: First off, if a messages is supposed to be printed,
2463       where is it supposed to end up at? STDOUT? STDERR? And are you sure you
2464       want to set in stone that this message needs to be printed, while
2465       someone else might find it annoying and wants to get rid of it?
2466
2467       The truth is, there's always going to be someone who wants to log a
2468       messages at all cost, but also another person who wants to suppress it
2469       with equal vigilance. There's no good way to serve these two
2470       conflicting desires, someone will always want to win at the cost of
2471       leaving the other party disappointed.
2472
2473       So, the best Log4perl offers is the ALWAYS level for a message that
2474       even fires if the system log level is set to $OFF:
2475
2476           use Log::Log4perl qw(:easy);
2477
2478           Log::Log4perl->easy_init( $OFF );
2479           ALWAYS "This gets logged always. Well, almost always";
2480
2481       The logger won't fire, though, if Log4perl hasn't been initialized or
2482       if someone defines a custom log hurdle that's higher than $OFF.
2483
2484       Bottom line: Leave the setting of the logging level to the initial Perl
2485       script -- let their owners decided what they want, no matter how
2486       tempting it may be to decide it for them.
2487
2488   Why doesn't my END handler remove my log file on Win32?
2489       If you have code like
2490
2491           use Log::Log4perl qw( :easy );
2492           Log::Log4perl->easy_init( { level => $DEBUG, file => "my.log" } );
2493           END { unlink "my.log" or die };
2494
2495       then you might be in for a surprise when you're running it on Windows,
2496       because the unlink() call in the END handler will complain that the
2497       file is still in use.
2498
2499       What happens in Perl if you have something like
2500
2501           END { print "first end in main\n"; }
2502           use Module;
2503           END { print "second end in main\n"; }
2504
2505       and
2506
2507           package Module;
2508           END { print "end in module\n"; }
2509           1;
2510
2511       is that you get
2512
2513           second end in main
2514           end in module
2515           first end in main
2516
2517       because perl stacks the END handlers in reverse order in which it
2518       encounters them in the compile phase.
2519
2520       Log4perl defines an END handler that cleans up left-over appenders
2521       (e.g.  file appenders which still hold files open), because those
2522       appenders have circular references and therefore aren't cleaned up
2523       otherwise.
2524
2525       Now if you define an END handler after "use Log::Log4perl", it'll
2526       trigger before Log4perl gets a chance to clean up, which isn't a
2527       problem on Unix where you can delete a file even if some process has a
2528       handle to it open, but it's a problem on Win32, where the OS won't let
2529       you do that.
2530
2531       The solution is easy, just place the END handler before Log4perl gets
2532       loaded, like in
2533
2534           END { unlink "my.log" or die };
2535           use Log::Log4perl qw( :easy );
2536           Log::Log4perl->easy_init( { level => $DEBUG, file => "my.log" } );
2537
2538       which will call the END handlers in the intended order.
2539

SEE ALSO

2541       Log::Log4perl
2542

LICENSE

2544       Copyright 2002-2013 by Mike Schilli <m@perlmeister.com> and Kevin Goess
2545       <cpan@goess.org>.
2546
2547       This library is free software; you can redistribute it and/or modify it
2548       under the same terms as Perl itself.
2549

AUTHOR

2551       Please contribute patches to the project on Github:
2552
2553           http://github.com/mschilli/log4perl
2554
2555       Send bug reports or requests for enhancements to the authors via our
2556
2557       MAILING LIST (questions, bug reports, suggestions/patches):
2558       log4perl-devel@lists.sourceforge.net
2559
2560       Authors (please contact them via the list above, not directly): Mike
2561       Schilli <m@perlmeister.com>, Kevin Goess <cpan@goess.org>
2562
2563       Contributors (in alphabetical order): Ateeq Altaf, Cory Bennett, Jens
2564       Berthold, Jeremy Bopp, Hutton Davidson, Chris R. Donnelly, Matisse
2565       Enzer, Hugh Esco, Anthony Foiani, James FitzGibbon, Carl Franks, Dennis
2566       Gregorovic, Andy Grundman, Paul Harrington, Alexander Hartmaier  David
2567       Hull, Robert Jacobson, Jason Kohles, Jeff Macdonald, Markus Peter,
2568       Brett Rann, Peter Rabbitson, Erik Selberg, Aaron Straup Cope, Lars
2569       Thegler, David Viner, Mac Yang.
2570
2571
2572
2573perl v5.36.0                      2023-01-20                            FAQ(3)
Impressum