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