1Log::Log4perl(3) User Contributed Perl Documentation Log::Log4perl(3)
2
3
4
6 Log::Log4perl - Log4j implementation for Perl
7
9 # Easy mode if you like it simple ...
10
11 use Log::Log4perl qw(:easy);
12 Log::Log4perl->easy_init($ERROR);
13
14 DEBUG "This doesn't go anywhere";
15 ERROR "This gets logged";
16
17 # ... or standard mode for more features:
18
19 Log::Log4perl::init('/etc/log4perl.conf');
20
21 --or--
22
23 # Check config every 10 secs
24 Log::Log4perl::init_and_watch('/etc/log4perl.conf',10);
25
26 --then--
27
28 $logger = Log::Log4perl->get_logger('house.bedrm.desk.topdrwr');
29
30 $logger->debug('this is a debug message');
31 $logger->info('this is an info message');
32 $logger->warn('etc');
33 $logger->error('..');
34 $logger->fatal('..');
35
36 #####/etc/log4perl.conf###############################
37 log4perl.logger.house = WARN, FileAppndr1
38 log4perl.logger.house.bedroom.desk = DEBUG, FileAppndr1
39
40 log4perl.appender.FileAppndr1 = Log::Log4perl::Appender::File
41 log4perl.appender.FileAppndr1.filename = desk.log
42 log4perl.appender.FileAppndr1.layout = \
43 Log::Log4perl::Layout::SimpleLayout
44 ######################################################
45
47 Log::Log4perl provides a powerful logging API for your application
48
50 Log::Log4perl lets you remote-control and fine-tune the logging behav‐
51 iour of your system from the outside. It implements the widely popular
52 (Java-based) Log4j logging package in pure Perl.
53
54 For a detailed tutorial on Log::Log4perl usage, please read
55
56 http://www.perl.com/pub/a/2002/09/11/log4perl.html
57
58 Logging beats a debugger if you want to know what's going on in your
59 code during runtime. However, traditional logging packages are too
60 static and generate a flood of log messages in your log files that
61 won't help you.
62
63 "Log::Log4perl" is different. It allows you to control the number of
64 logging messages generated at three different levels:
65
66 · At a central location in your system (either in a configuration
67 file or in the startup code) you specify which components (classes,
68 functions) of your system should generate logs.
69
70 · You specify how detailed the logging of these components should be
71 by specifying logging levels.
72
73 · You also specify which so-called appenders you want to feed your
74 log messages to ("Print it to the screen and also append it to
75 /tmp/my.log") and which format ("Write the date first, then the
76 file name and line number, and then the log message") they should
77 be in.
78
79 This is a very powerful and flexible mechanism. You can turn on and off
80 your logs at any time, specify the level of detail and make that depen‐
81 dent on the subsystem that's currently executed.
82
83 Let me give you an example: You might find out that your system has a
84 problem in the "MySystem::Helpers::ScanDir" component. Turning on
85 detailed debugging logs all over the system would generate a flood of
86 useless log messages and bog your system down beyond recognition. With
87 "Log::Log4perl", however, you can tell the system: "Continue to log
88 only severe errors to the log file. Open a second log file, turn on
89 full debug logs in the "MySystem::Helpers::ScanDir" component and dump
90 all messages originating from there into the new log file". And all
91 this is possible by just changing the parameters in a configuration
92 file, which your system can re-read even while it's running!
93
95 The "Log::Log4perl" package can be initialized in two ways: Either via
96 Perl commands or via a "log4j"-style configuration file.
97
98 Initialize via a configuration file
99
100 This is the easiest way to prepare your system for using
101 "Log::Log4perl". Use a configuration file like this:
102
103 ############################################################
104 # A simple root logger with a Log::Log4perl::Appender::File
105 # file appender in Perl.
106 ############################################################
107 log4perl.rootLogger=ERROR, LOGFILE
108
109 log4perl.appender.LOGFILE=Log::Log4perl::Appender::File
110 log4perl.appender.LOGFILE.filename=/var/log/myerrs.log
111 log4perl.appender.LOGFILE.mode=append
112
113 log4perl.appender.LOGFILE.layout=PatternLayout
114 log4perl.appender.LOGFILE.layout.ConversionPattern=[%r] %F %L %c - %m%n
115
116 These lines define your standard logger that's appending severe errors
117 to "/var/log/myerrs.log", using the format
118
119 [millisecs] source-filename line-number class - message newline
120
121 Assuming that this configuration file is saved as "log.conf", you need
122 to read it in in the startup section of your code, using the following
123 commands:
124
125 use Log::Log4perl;
126 Log::Log4perl->init("log.conf");
127
128 After that's done somewhere in the code, you can retrieve logger
129 objects anywhere in the code. Note that there's no need to carry any
130 logger references around with your functions and methods. You can get a
131 logger anytime via a singleton mechanism:
132
133 package My::MegaPackage;
134 use Log::Log4perl;
135
136 sub some_method {
137 my($param) = @_;
138
139 my $log = Log::Log4perl->get_logger("My::MegaPackage");
140
141 $log->debug("Debug message");
142 $log->info("Info message");
143 $log->error("Error message");
144
145 ...
146 }
147
148 With the configuration file above, "Log::Log4perl" will write "Error
149 message" to the specified log file, but won't do anything for the
150 "debug()" and "info()" calls, because the log level has been set to
151 "ERROR" for all components in the first line of configuration file
152 shown above.
153
154 Why "Log::Log4perl->get_logger" and not "Log::Log4perl->new"? We don't
155 want to create a new object every time. Usually in OO-Programming, you
156 create an object once and use the reference to it to call its methods.
157 However, this requires that you pass around the object to all functions
158 and the last thing we want is pollute each and every function/method
159 we're using with a handle to the "Logger":
160
161 sub function { # Brrrr!!
162 my($logger, $some, $other, $parameters) = @_;
163 }
164
165 Instead, if a function/method wants a reference to the logger, it just
166 calls the Logger's static "get_logger($category)" method to obtain a
167 reference to the one and only possible logger object of a certain cate‐
168 gory. That's called a singleton if you're a Gamma fan.
169
170 How does the logger know which messages it is supposed to log and which
171 ones to suppress? "Log::Log4perl" works with inheritance: The config
172 file above didn't specify anything about "My::MegaPackage". And yet,
173 we've defined a logger of the category "My::MegaPackage". In this
174 case, "Log::Log4perl" will walk up the class hierarchy ("My" and then
175 the we're at the root) to figure out if a log level is defined some‐
176 where. In the case above, the log level at the root (root always
177 defines a log level, but not necessarily an appender) defines that the
178 log level is supposed to be "ERROR" -- meaning that DEBUG and INFO mes‐
179 sages are suppressed.
180
181 Log Levels
182
183 There are five predefined log levels: "FATAL", "ERROR", "WARN", "INFO",
184 "DEBUG", and "TRACE" (in descending priority). Your configured logging
185 level has to at least match the priority of the logging message.
186
187 If your configured logging level is "WARN", then messages logged with
188 "info()" and "debug()" message will be suppressed. "fatal()",
189 "error()" and "warn()" will make their way through, because their pri‐
190 ority is higher or equal than the configured setting.
191
192 Instead of calling the methods
193
194 $logger->debug("..."); # Log a debug message
195 $logger->info("..."); # Log a info message
196 $logger->warn("..."); # Log a warn message
197 $logger->error("..."); # Log a error message
198 $logger->fatal("..."); # Log a fatal message
199
200 you could also call the "log()" method with the appropriate level using
201 the constants defined in "Log::Log4perl::Level":
202
203 use Log::Log4perl::Level;
204
205 $logger->log($TRACE, "...");
206 $logger->log($DEBUG, "...");
207 $logger->log($INFO, "...");
208 $logger->log($WARN, "...");
209 $logger->log($ERROR, "...");
210 $logger->log($FATAL, "...");
211
212 But nobody does that, really. Neither does anyone need more logging
213 levels than these predefined ones. If you think you do, I would suggest
214 you look into steering your logging behaviour via the category mecha‐
215 nism.
216
217 If you need to find out if the currently configured logging level would
218 allow a logger's logging statement to go through, use the logger's
219 "is_level()" methods:
220
221 $logger->is_trace() # True if trace messages would go through
222 $logger->is_debug() # True if debug messages would go through
223 $logger->is_info() # True if info messages would go through
224 $logger->is_warn() # True if warn messages would go through
225 $logger->is_error() # True if error messages would go through
226 $logger->is_fatal() # True if fatal messages would go through
227
228 Example: "$logger->is_warn()" returns true if the logger's current
229 level, as derived from either the logger's category (or, in absence of
230 that, one of the logger's parent's level setting) is $WARN, $ERROR or
231 $FATAL.
232
233 Also available are a series of more Java-esque functions which return
234 the same values. These are of the format "isLevelEnabled()", so "$log‐
235 ger->isDebugEnabled()" is synonymous to "$logger->is_debug()".
236
237 These level checking functions will come in handy later, when we want
238 to block unnecessary expensive parameter construction in case the log‐
239 ging level is too low to log the statement anyway, like in:
240
241 if($logger->is_error()) {
242 $logger->error("Erroneous array: @super_long_array");
243 }
244
245 If we had just written
246
247 $logger->error("Erroneous array: @super_long_array");
248
249 then Perl would have interpolated @super_long_array into the string via
250 an expensive operation only to figure out shortly after that the string
251 can be ignored entirely because the configured logging level is lower
252 than $ERROR.
253
254 The to-be-logged message passed to all of the functions described above
255 can consist of an arbitrary number of arguments, which the logging
256 functions just chain together to a single string. Therefore
257
258 $logger->debug("Hello ", "World", "!"); # and
259 $logger->debug("Hello World!");
260
261 are identical.
262
263 Log and die or warn
264
265 Often, when you croak / carp / warn / die, you want to log those mes‐
266 sages. Rather than doing the following:
267
268 $logger->fatal($err) && die($err);
269
270 you can use the following:
271
272 $logger->logwarn();
273 $logger->logdie();
274
275 These print out log messages in the WARN and FATAL level, respectively,
276 and then call the built-in warn() and die() functions. Since there is
277 an ERROR level between WARN and FATAL, there are two additional helper
278 functions in case you'd like to use ERROR for either warn() or die():
279
280 $logger->error_warn();
281 $logger->error_die();
282
283 Finally, there's the Carp functions that do just what the Carp func‐
284 tions do, but with logging:
285
286 $logger->logcarp(); # warn w/ 1-level stack trace
287 $logger->logcluck(); # warn w/ full stack trace
288 $logger->logcroak(); # die w/ 1-level stack trace
289 $logger->logconfess(); # die w/ full stack trace
290
291 Appenders
292
293 If you don't define any appenders, nothing will happen. Appenders will
294 be triggered whenever the configured logging level requires a message
295 to be logged and not suppressed.
296
297 "Log::Log4perl" doesn't define any appenders by default, not even the
298 root logger has one.
299
300 "Log::Log4perl" already comes with a standard set of appenders:
301
302 Log::Log4perl::Appender::Screen
303 Log::Log4perl::Appender::ScreenColoredLevels
304 Log::Log4perl::Appender::File
305 Log::Log4perl::Appender::Socket
306 Log::Log4perl::Appender::DBI
307 Log::Log4perl::Appender::Synchronized
308 Log::Log4perl::Appender::RRDs
309
310 to log to the screen, to files and to databases.
311
312 On CPAN, you can find additional appenders like
313
314 Log::Log4perl::Layout::XMLLayout
315
316 by Guido Carls <gcarls@cpan.org>. It allows for hooking up
317 Log::Log4perl with the graphical Log Analyzer Chainsaw (see "Can I use
318 Log::Log4perl with log4j's Chainsaw?" in Log::Log4perl::FAQ).
319
320 Additional Appenders via Log::Dispatch
321
322 "Log::Log4perl" also supports Dave Rolskys excellent "Log::Dispatch"
323 framework which implements a wide variety of different appenders.
324
325 Here's the list of appender modules currently available via "Log::Dis‐
326 patch":
327
328 Log::Dispatch::ApacheLog
329 Log::Dispatch::DBI (by Tatsuhiko Miyagawa)
330 Log::Dispatch::Email,
331 Log::Dispatch::Email::MailSend,
332 Log::Dispatch::Email::MailSendmail,
333 Log::Dispatch::Email::MIMELite
334 Log::Dispatch::File
335 Log::Dispatch::FileRotate (by Mark Pfeiffer)
336 Log::Dispatch::Handle
337 Log::Dispatch::Screen
338 Log::Dispatch::Syslog
339 Log::Dispatch::Tk (by Dominique Dumont)
340
341 Please note that in order to use any of these additional appenders, you
342 have to fetch Log::Dispatch from CPAN and install it. Also the particu‐
343 lar appender you're using might require installing the particular mod‐
344 ule.
345
346 For additional information on appenders, please check the
347 Log::Log4perl::Appender manual page.
348
349 Appender Example
350
351 Now let's assume that we want to log "info()" or higher prioritized
352 messages in the "Foo::Bar" category to both STDOUT and to a log file,
353 say "test.log". In the initialization section of your system, just
354 define two appenders using the readily available "Log::Log4perl::Appen‐
355 der::File" and "Log::Log4perl::Appender::Screen" modules:
356
357 use Log::Log4perl;
358
359 # Configuration in a string ...
360 my $conf = q(
361 log4perl.category.Foo.Bar = INFO, Logfile, Screen
362
363 log4perl.appender.Logfile = Log::Log4perl::Appender::File
364 log4perl.appender.Logfile.filename = test.log
365 log4perl.appender.Logfile.layout = Log::Log4perl::Layout::PatternLayout
366 log4perl.appender.Logfile.layout.ConversionPattern = [%r] %F %L %m%n
367
368 log4perl.appender.Screen = Log::Log4perl::Appender::Screen
369 log4perl.appender.Screen.stderr = 0
370 log4perl.appender.Screen.layout = Log::Log4perl::Layout::SimpleLayout
371 );
372
373 # ... passed as a reference to init()
374 Log::Log4perl::init( \$conf );
375
376 Once the initialization shown above has happened once, typically in the
377 startup code of your system, just use the defined logger anywhere in
378 your system:
379
380 ##########################
381 # ... in some function ...
382 ##########################
383 my $log = Log::Log4perl::get_logger("Foo::Bar");
384
385 # Logs both to STDOUT and to the file test.log
386 $log->info("Important Info!");
387
388 The "layout" settings specified in the configuration section define the
389 format in which the message is going to be logged by the specified
390 appender. The format shown for the file appender is logging not only
391 the message but also the number of milliseconds since the program has
392 started (%r), the name of the file the call to the logger has happened
393 and the line number there (%F and %L), the message itself (%m) and a
394 OS-specific newline character (%n):
395
396 [187] ./myscript.pl 27 Important Info!
397
398 The screen appender above, on the other hand, uses a "SimpleLayout",
399 which logs the debug level, a hyphen (-) and the log message:
400
401 INFO - Important Info!
402
403 For more detailed info on layout formats, see "Log Layouts".
404
405 In the configuration sample above, we chose to define a category logger
406 ("Foo::Bar"). This will cause only messages originating from this spe‐
407 cific category logger to be logged in the defined format and locations.
408
409 Configuration files
410
411 As shown above, you can define "Log::Log4perl" loggers both from within
412 your Perl code or from configuration files. The latter have the unbeat‐
413 able advantage that you can modify your system's logging behaviour
414 without interfering with the code at all. So even if your code is being
415 run by somebody who's totally oblivious to Perl, they still can adapt
416 the module's logging behaviour to their needs.
417
418 "Log::Log4perl" has been designed to understand "Log4j" configuration
419 files -- as used by the original Java implementation. Instead of reit‐
420 erating the format description in [2], let me just list three examples
421 (also derived from [2]), which should also illustrate how it works:
422
423 log4j.rootLogger=DEBUG, A1
424 log4j.appender.A1=org.apache.log4j.ConsoleAppender
425 log4j.appender.A1.layout=org.apache.log4j.PatternLayout
426 log4j.appender.A1.layout.ConversionPattern=%-4r %-5p %c %x - %m%n
427
428 This enables messages of priority "DEBUG" or higher in the root hierar‐
429 chy and has the system write them to the console. "ConsoleAppender" is
430 a Java appender, but "Log::Log4perl" jumps through a significant number
431 of hoops internally to map these to their corresponding Perl classes,
432 "Log::Log4perl::Appender::Screen" in this case.
433
434 Second example:
435
436 log4perl.rootLogger=DEBUG, A1
437 log4perl.appender.A1=Log::Log4perl::Appender::Screen
438 log4perl.appender.A1.layout=PatternLayout
439 log4perl.appender.A1.layout.ConversionPattern=%d %-5p %c - %m%n
440 log4perl.logger.com.foo=WARN
441
442 This defines two loggers: The root logger and the "com.foo" logger.
443 The root logger is easily triggered by debug-messages, but the
444 "com.foo" logger makes sure that messages issued within the "Com::Foo"
445 component and below are only forwarded to the appender if they're of
446 priority warning or higher.
447
448 Note that the "com.foo" logger doesn't define an appender. Therefore,
449 it will just propagate the message up the hierarchy until the root log‐
450 ger picks it up and forwards it to the one and only appender of the
451 root category, using the format defined for it.
452
453 Third example:
454
455 log4j.rootLogger=debug, stdout, R
456 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
457 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
458 log4j.appender.stdout.layout.ConversionPattern=%5p (%F:%L) - %m%n
459 log4j.appender.R=org.apache.log4j.RollingFileAppender
460 log4j.appender.R.File=example.log
461 log4j.appender.R.layout=org.apache.log4j.PatternLayout
462 log4j.appender.R.layout.ConversionPattern=%p %c - %m%n
463
464 The root logger defines two appenders here: "stdout", which uses
465 "org.apache.log4j.ConsoleAppender" (ultimately mapped by
466 "Log::Log4perl" to "Log::Log4perl::Appender::Screen") to write to the
467 screen. And "R", a "org.apache.log4j.RollingFileAppender" (mapped by
468 "Log::Log4perl" to "Log::Dispatch::FileRotate" with the "File"
469 attribute specifying the log file.
470
471 See Log::Log4perl::Config for more examples and syntax explanations.
472
473 Log Layouts
474
475 If the logging engine passes a message to an appender, because it
476 thinks it should be logged, the appender doesn't just write it out hap‐
477 hazardly. There's ways to tell the appender how to format the message
478 and add all sorts of interesting data to it: The date and time when the
479 event happened, the file, the line number, the debug level of the log‐
480 ger and others.
481
482 There's currently two layouts defined in "Log::Log4perl":
483 "Log::Log4perl::Layout::SimpleLayout" and "Log::Log4perl::Layout::Pat‐
484 ternLayout":
485
486 "Log::Log4perl::SimpleLayout"
487 formats a message in a simple way and just prepends it by the debug
488 level and a hyphen: ""$level - $message", for example "FATAL -
489 Can't open password file".
490
491 "Log::Log4perl::Layout::PatternLayout"
492 on the other hand is very powerful and allows for a very flexible
493 format in "printf"-style. The format string can contain a number of
494 placeholders which will be replaced by the logging engine when it's
495 time to log the message:
496
497 %c Category of the logging event.
498 %C Fully qualified package (or class) name of the caller
499 %d Current date in yyyy/MM/dd hh:mm:ss format
500 %F File where the logging event occurred
501 %H Hostname
502 %l Fully qualified name of the calling method followed by the
503 callers source the file name and line number between
504 parentheses.
505 %L Line number within the file where the log statement was issued
506 %m The message to be logged
507 %M Method or function where the logging request was issued
508 %n Newline (OS-independent)
509 %p Priority of the logging event
510 %P pid of the current process
511 %r Number of milliseconds elapsed from program start to logging
512 event
513 %x The elements of the NDC stack (see below)
514 %X{key} The entry 'key' of the MDC (see below)
515 %% A literal percent (%) sign
516
517 NDC and MDC are explained in "Nested Diagnostic Context (NDC)" and
518 "Mapped Diagnostic Context (MDC)".
519
520 Also, %d can be fine-tuned to display only certain characteristics
521 of a date, according to the SimpleDateFormat in the Java World
522 (http://java.sun.com/j2se/1.3/docs/api/java/text/SimpleDateFor‐
523 mat.html)
524
525 In this way, %d{HH:mm} displays only hours and minutes of the cur‐
526 rent date, while %d{yy, EEEE} displays a two-digit year, followed
527 by a spelled-out (like "Wednesday").
528
529 Similar options are available for shrinking the displayed category
530 or limit file/path components, %F{1} only displays the source file
531 name without any path components while %F logs the full path. %c{2}
532 only logs the last two components of the current category,
533 "Foo::Bar::Baz" becomes "Bar::Baz" and saves space.
534
535 If those placeholders aren't enough, then you can define your own
536 right in the config file like this:
537
538 log4perl.PatternLayout.cspec.U = sub { return "UID $<" }
539
540 See Log::Log4perl::Layout::PatternLayout for further details on
541 customized specifiers.
542
543 Please note that the subroutines you're defining in this way are
544 going to be run in the "main" namespace, so be sure to fully qual‐
545 ify functions and variables if they're located in different pack‐
546 ages.
547
548 SECURITY NOTE: this feature means arbitrary perl code can be embed‐
549 ded in the config file. In the rare case where the people who have
550 access to your config file are different from the people who write
551 your code and shouldn't have execute rights, you might want to call
552
553 Log::Log4perl::Config->allow_code(0);
554
555 before you call init(). Alternatively you can supply a restricted
556 set of Perl opcodes that can be embedded in the config file as
557 described in "Restricting what Opcodes can be in a Perl Hook".
558
559 All placeholders are quantifiable, just like in printf. Following this
560 tradition, "%-20c" will reserve 20 chars for the category and left-jus‐
561 tify it.
562
563 For more details on logging and how to use the flexible and the simple
564 format, check out the original "log4j" website under
565
566 http://jakarta.apache.org/log4j/docs/api/org/apache/log4j/SimpleLayout.html
567 http://jakarta.apache.org/log4j/docs/api/org/apache/log4j/PatternLayout.html
568
569 Penalties
570
571 Logging comes with a price tag. "Log::Log4perl" has been optimized to
572 allow for maximum performance, both with logging enabled and disabled.
573
574 But you need to be aware that there's a small hit every time your code
575 encounters a log statement -- no matter if logging is enabled or not.
576 "Log::Log4perl" has been designed to keep this so low that it will be
577 unnoticable to most applications.
578
579 Here's a couple of tricks which help "Log::Log4perl" to avoid unneces‐
580 sary delays:
581
582 You can save serious time if you're logging something like
583
584 # Expensive in non-debug mode!
585 for (@super_long_array) {
586 $logger->debug("Element: $_\n");
587 }
588
589 and @super_long_array is fairly big, so looping through it is pretty
590 expensive. Only you, the programmer, knows that going through that
591 "for" loop can be skipped entirely if the current logging level for the
592 actual component is higher than "debug". In this case, use this
593 instead:
594
595 # Cheap in non-debug mode!
596 if($logger->is_debug()) {
597 for (@super_long_array) {
598 $logger->debug("Element: $_\n");
599 }
600 }
601
602 If you're afraid that the way you're generating the parameters to the
603 of the logging function is fairly expensive, use closures:
604
605 # Passed as subroutine ref
606 use Data::Dumper;
607 $logger->debug(sub { Dumper($data) } );
608
609 This won't unravel $data via Dumper() unless it's actually needed
610 because it's logged.
611
612 Also, Log::Log4perl lets you specify arguments to logger functions in
613 message output filter syntax:
614
615 $logger->debug("Structure: ",
616 { filter => \&Dumper,
617 value => $someref });
618
619 In this way, shortly before Log::Log4perl sending the message out to
620 any appenders, it will be searching all arguments for hash references
621 and treat them in a special way:
622
623 It will invoke the function given as a reference with the "filter" key
624 ("Data::Dumper::Dumper()") and pass it the value that came with the key
625 named "value" as an argument. The anonymous hash in the call above
626 will be replaced by the return value of the filter function.
627
629 "Log::Log4perl" uses categories to determine if a log statement in a
630 component should be executed or suppressed at the current logging
631 level. Most of the time, these categories are just the classes the log
632 statements are located in:
633
634 package Candy::Twix;
635
636 sub new {
637 my $logger = Log::Log4perl->new("Candy::Twix");
638 $logger->debug("Creating a new Twix bar");
639 bless {}, shift;
640 }
641
642 # ...
643
644 package Candy::Snickers;
645
646 sub new {
647 my $logger = Log::Log4perl->new("Candy.Snickers");
648 $logger->debug("Creating a new Snickers bar");
649 bless {}, shift;
650 }
651
652 # ...
653
654 package main;
655 Log::Log4perl->init("mylogdefs.conf");
656
657 # => "LOG> Creating a new Snickers bar"
658 my $first = Candy::Snickers->new();
659 # => "LOG> Creating a new Twix bar"
660 my $second = Candy::Twix->new();
661
662 Note that you can separate your category hierarchy levels using either
663 dots like in Java (.) or double-colons (::) like in Perl. Both nota‐
664 tions are equivalent and are handled the same way internally.
665
666 However, categories are just there to make use of inheritance: if you
667 invoke a logger in a sub-category, it will bubble up the hierarchy and
668 call the appropriate appenders. Internally, categories are not related
669 to the class hierarchy of the program at all -- they're purely virtual.
670 You can use arbitrary categories -- for example in the following pro‐
671 gram, which isn't oo-style, but procedural:
672
673 sub print_portfolio {
674
675 my $log = Log::Log4perl->new("user.portfolio");
676 $log->debug("Quotes requested: @_");
677
678 for(@_) {
679 print "$_: ", get_quote($_), "\n";
680 }
681 }
682
683 sub get_quote {
684
685 my $log = Log::Log4perl->new("internet.quotesystem");
686 $log->debug("Fetching quote: $_[0]");
687
688 return yahoo_quote($_[0]);
689 }
690
691 The logger in first function, "print_portfolio", is assigned the (vir‐
692 tual) "user.portfolio" category. Depending on the "Log4perl" configura‐
693 tion, this will either call a "user.portfolio" appender, a "user"
694 appender, or an appender assigned to root -- without "user.portfolio"
695 having any relevance to the class system used in the program. The log‐
696 ger in the second function adheres to the "internet.quotesystem" cate‐
697 gory -- again, maybe because it's bundled with other Internet func‐
698 tions, but not because there would be a class of this name somewhere.
699
700 However, be careful, don't go overboard: if you're developing a system
701 in object-oriented style, using the class hierarchy is usually your
702 best choice. Think about the people taking over your code one day: The
703 class hierarchy is probably what they know right up front, so it's easy
704 for them to tune the logging to their needs.
705
706 Turn off a component
707
708 "Log4perl" doesn't only allow you to selectively switch on a category
709 of log messages, you can also use the mechanism to selectively disable
710 logging in certain components whereas logging is kept turned on in
711 higher-level categories. This mechanism comes in handy if you find that
712 while bumping up the logging level of a high-level (i. e. close to
713 root) category, that one component logs more than it should,
714
715 Here's how it works:
716
717 ############################################################
718 # Turn off logging in a lower-level category while keeping
719 # it active in higher-level categories.
720 ############################################################
721 log4perl.rootLogger=DEBUG, LOGFILE
722 log4perl.logger.deep.down.the.hierarchy = ERROR, LOGFILE
723
724 # ... Define appenders ...
725
726 This way, log messages issued from within "Deep::Down::The::Hierarchy"
727 and below will be logged only if they're "ERROR" or worse, while in all
728 other system components even "DEBUG" messages will be logged.
729
730 Return Values
731
732 All logging methods return values indicating if their message actually
733 reached one or more appenders. If the message has been suppressed
734 because of level constraints, "undef" is returned.
735
736 For example,
737
738 my $ret = $logger->info("Message");
739
740 will return "undef" if the system debug level for the current category
741 is not "INFO" or more permissive. If Log::Log4perl forwarded the mes‐
742 sage to one or more appenders, the number of appenders is returned.
743
744 If appenders decide to veto on the message with an appender threshold,
745 the log method's return value will have them excluded. This means that
746 if you've got one appender holding an appender threshold and you're
747 logging a message which passes the system's log level hurdle but not
748 the appender threshold, 0 will be returned by the log function.
749
750 The bottom line is: Logging functions will return a true value if the
751 message made it through to one or more appenders and a false value if
752 it didn't. This allows for constructs like
753
754 $logger->fatal("@_") or print STDERR "@_\n";
755
756 which will ensure that the fatal message isn't lost if the current
757 level is lower than FATAL or printed twice if the level is acceptable
758 but an appender already points to STDERR.
759
760 Pitfalls with Categories
761
762 Be careful with just blindly reusing the system's packages as cate‐
763 gories. If you do, you'll get into trouble with inherited methods.
764 Imagine the following class setup:
765
766 use Log::Log4perl;
767
768 ###########################################
769 package Bar;
770 ###########################################
771 sub new {
772 my($class) = @_;
773 my $logger = Log::Log4perl::get_logger(__PACKAGE__);
774 $logger->debug("Creating instance");
775 bless {}, $class;
776 }
777 ###########################################
778 package Bar::Twix;
779 ###########################################
780 our @ISA = qw(Bar);
781
782 ###########################################
783 package main;
784 ###########################################
785 Log::Log4perl->init(\ qq{
786 log4perl.category.Bar.Twix = DEBUG, Screen
787 log4perl.appender.Screen = Log::Log4perl::Appender::Screen
788 log4perl.appender.Screen.layout = SimpleLayout
789 });
790
791 my $bar = Bar::Twix->new();
792
793 "Bar::Twix" just inherits everything from "Bar", including the con‐
794 structor "new()". Contrary to what you might be thinking at first,
795 this won't log anything. Reason for this is the "get_logger()" call in
796 package "Bar", which will always get a logger of the "Bar" category,
797 even if we call "new()" via the "Bar::Twix" package, which will make
798 perl go up the inheritance tree to actually execute "Bar::new()". Since
799 we've only defined logging behaviour for "Bar::Twix" in the configura‐
800 tion file, nothing will happen.
801
802 This can be fixed by changing the "get_logger()" method in "Bar::new()"
803 to obtain a logger of the category matching the actual class of the
804 object, like in
805
806 # ... in Bar::new() ...
807 my $logger = Log::Log4perl::get_logger($class);
808
809 This way, you'll make sure the logger logs appropriately, no matter if
810 the method is inherited or called directly. "new()" always gets the
811 real class name as an argument and all other methods can determine it
812 via "ref($self)"), so it shouldn't be a problem to get the right class
813 every time.
814
815 Initialize once and only once
816
817 It's important to realize that Log::Log4perl gets initialized once and
818 only once, typically at the start of a program or system. Calling
819 "init()" more than once will cause it to clobber the existing configu‐
820 ration and replace it by the new one.
821
822 If you're in a traditional CGI environment, where every request is han‐
823 deled by a new process, calling "init()" every time is fine. In persis‐
824 tent environments like "mod_perl", however, Log::Log4perl should be
825 initialized either at system startup time (Apache offers startup han‐
826 dlers for that) or via
827
828 # Init or skip if already done
829 Log::Log4perl->init_once($conf_file);
830
831 "init_once()" is identical to "init()", just with the exception that it
832 will leave a potentially existing configuration alone and will only
833 call "init()" if Log::Log4perl hasn't been initialized yet.
834
835 If you're just curious if Log::Log4perl has been initialized yet, the
836 check
837
838 if(Log::Log4perl->initialized()) {
839 # Yes, Log::Log4perl has already been initialized
840 } else {
841 # No, not initialized yet ...
842 }
843
844 can be used.
845
846 If you're afraid that the components of your system are stepping on
847 each other's toes or if you are thinking that different components
848 should initialize Log::Log4perl seperately, try to consolidate your
849 system to use a centralized Log4perl configuration file and use
850 Log4perl's categories to separate your components.
851
852 Custom Filters
853
854 Log4perl allows the use of customized filters in its appenders to con‐
855 trol the output of messages. These filters might grep for certain text
856 chunks in a message, verify that its priority matches or exceeds a cer‐
857 tain level or that this is the 10th time the same message has been sub‐
858 mitted -- and come to a log/no log decision based upon these circum‐
859 stantial facts.
860
861 Check out Log::Log4perl::Filter for detailed instructions on how to use
862 them.
863
864 Performance
865
866 The performance of Log::Log4perl calls obviously depends on a lot of
867 things. But to give you a general idea, here's some rough numbers:
868
869 On a Pentium 4 Linux box at 2.4 GHz, you'll get through
870
871 · 500,000 suppressed log statements per second
872
873 · 30,000 logged messages per second (using an in-memory appender)
874
875 · init_and_watch delay mode: 300,000 suppressed, 30,000 logged.
876 init_and_watch signal mode: 450,000 suppressed, 30,000 logged.
877
878 Numbers depend on the complexity of the Log::Log4perl configuration.
879 For a more detailed benchmark test, check the "docs/bench‐
880 mark.results.txt" document in the Log::Log4perl distribution.
881
883 Here's a collection of useful tricks for the advanced "Log::Log4perl"
884 user. For more, check the the FAQ, either in the distribution
885 (Log::Log4perl::FAQ) or on http://log4perl.sourceforge.net.
886
887 Shortcuts
888
889 When getting an instance of a logger, instead of saying
890
891 use Log::Log4perl;
892 my $logger = Log::Log4perl->get_logger();
893
894 it's often more convenient to import the "get_logger" method from
895 "Log::Log4perl" into the current namespace:
896
897 use Log::Log4perl qw(get_logger);
898 my $logger = get_logger();
899
900 Please note this difference: To obtain the root logger, please use
901 "get_logger("")", call it without parameters ("get_logger()"), you'll
902 get the logger of a category named after the current package.
903 "get_logger()" is equivalent to "get_logger(__PACKAGE__)".
904
905 Alternative initialization
906
907 Instead of having "init()" read in a configuration file by specifying a
908 file name or passing it a reference to an open filehandle
909 ("Log::Log4perl->init( \*FILE )"), you can also pass in a reference to
910 a string, containing the content of the file:
911
912 Log::Log4perl->init( \$config_text );
913
914 Also, if you've got the "name=value" pairs of the configuration in a
915 hash, you can just as well initialize "Log::Log4perl" with a reference
916 to it:
917
918 my %key_value_pairs = (
919 "log4perl.rootLogger" => "ERROR, LOGFILE",
920 "log4perl.appender.LOGFILE" => "Log::Log4perl::Appender::File",
921 ...
922 );
923
924 Log::Log4perl->init( \%key_value_pairs );
925
926 Or also you can use a URL, see below:
927
928 Using LWP to parse URLs
929
930 (This section borrowed from XML::DOM::Parser by T.J. Mather).
931
932 The init() function now also supports URLs, e.g.
933 http://www.erols.com/enno/xsa.xml. It uses LWP to download the file
934 and then calls parse() on the resulting string. By default it will use
935 a LWP::UserAgent that is created as follows:
936
937 use LWP::UserAgent;
938 $LWP_USER_AGENT = LWP::UserAgent->new;
939 $LWP_USER_AGENT->env_proxy;
940
941 Note that env_proxy reads proxy settings from environment variables,
942 which is what I need to do to get thru our firewall. If you want to use
943 a different LWP::UserAgent, you can set it with
944
945 Log::Log4perl::Config::set_LWP_UserAgent($my_agent);
946
947 Currently, LWP is used when the filename (passed to parsefile) starts
948 with one of the following URL schemes: http, https, ftp, wais, gopher,
949 or file (followed by a colon.)
950
951 Don't use this feature with init_and_watch().
952
953 Automatic reloading of changed configuration files
954
955 Instead of just statically initializing Log::Log4perl via
956
957 Log::Log4perl->init($conf_file);
958
959 there's a way to have Log::Log4perl periodically check for changes in
960 the configuration and reload it if necessary:
961
962 Log::Log4perl->init_and_watch($conf_file, $delay);
963
964 In this mode, Log::Log4perl will examine the configuration file
965 $conf_file every $delay seconds for changes via the file's last modifi‐
966 cation timestamp. If the file has been updated, it will be reloaded and
967 replace the current Log::Log4perl configuration.
968
969 The way this works is that with every logger function called (debug(),
970 is_debug(), etc.), Log::Log4perl will check if the delay interval has
971 expired. If so, it will run a -M file check on the configuration file.
972 If its timestamp has been modified, the current configuration will be
973 dumped and new content of the file will be loaded.
974
975 This convenience comes at a price, though: Calling time() with every
976 logging function call, especially the ones that are "suppressed" (!),
977 will slow down these Log4perl calls by about 40%.
978
979 To alleviate this performance hit a bit, "init_and_watch()" can be con‐
980 figured to listen for a Unix signal to reload the configuration
981 instead:
982
983 Log::Log4perl->init_and_watch($conf_file, 'HUP');
984
985 This will set up a signal handler for SIGHUP and reload the configura‐
986 tion if the application receives this signal, e.g. via the "kill" com‐
987 mand:
988
989 kill -HUP pid
990
991 where "pid" is the process ID of the application. This will bring you
992 back to about 85% of Log::Log4perl's normal execution speed for sup‐
993 pressed statements. For details, check out "Performance". For more info
994 on the signal handler, look for "SIGNAL MODE" in Log::Log4perl::Con‐
995 fig::Watch.
996
997 One thing to watch out for: If the configuration file contains a syntax
998 or other fatal error, a running application will stop with "die" if
999 this damaged configuration will be loaded during runtime, triggered
1000 either by a signal or if the delay period expired and the change is
1001 detected. This behaviour might change in the future.
1002
1003 Variable Substitution
1004
1005 To avoid having to retype the same expressions over and over again,
1006 Log::Log4perl's configuration files support simple variable substitu‐
1007 tion. New variables are defined simply by adding
1008
1009 varname = value
1010
1011 lines to the configuration file before using
1012
1013 ${varname}
1014
1015 afterwards to recall the assigned values. Here's an example:
1016
1017 layout_class = Log::Log4perl::Layout::PatternLayout
1018 layout_pattern = %d %F{1} %L> %m %n
1019
1020 log4perl.category.Bar.Twix = WARN, Logfile, Screen
1021
1022 log4perl.appender.Logfile = Log::Log4perl::Appender::File
1023 log4perl.appender.Logfile.filename = test.log
1024 log4perl.appender.Logfile.layout = ${layout_class}
1025 log4perl.appender.Logfile.layout.ConversionPattern = ${layout_pattern}
1026
1027 log4perl.appender.Screen = Log::Log4perl::Appender::Screen
1028 log4perl.appender.Screen.layout = ${layout_class}
1029 log4perl.appender.Screen.layout.ConversionPattern = ${layout_pattern}
1030
1031 This is a convenient way to define two appenders with the same layout
1032 without having to retype the pattern definitions.
1033
1034 Variable substitution via "${varname}" will first try to find an
1035 explicitely defined variable. If that fails, it will check your shell's
1036 environment for a variable of that name. If that also fails, the pro‐
1037 gram will "die()".
1038
1039 Perl Hooks in the Configuration File
1040
1041 If some of the values used in the Log4perl configuration file need to
1042 be dynamically modified by the program, use Perl hooks:
1043
1044 log4perl.appender.File.filename = \
1045 sub { return getLogfileName(); }
1046
1047 Each value starting with the string "sub {..." is interpreted as Perl
1048 code to be executed at the time the application parses the configura‐
1049 tion via "Log::Log4perl::init()". The return value of the subroutine is
1050 used by Log::Log4perl as the configuration value.
1051
1052 The Perl code is executed in the "main" package, functions in other
1053 packages have to be called in fully-qualified notation.
1054
1055 Here's another example, utilizing an environment variable as a username
1056 for a DBI appender:
1057
1058 log4perl.appender.DB.username = \
1059 sub { $ENV{DB_USER_NAME } }
1060
1061 However, please note the difference between these code snippets and
1062 those used for user-defined conversion specifiers as discussed in
1063 Log::Log4perl::Layout::PatternLayout: While the snippets above are run
1064 once when "Log::Log4perl::init()" is called, the conversion specifier
1065 snippets are executed each time a message is rendered according to the
1066 PatternLayout.
1067
1068 SECURITY NOTE: this feature means arbitrary perl code can be embedded
1069 in the config file. In the rare case where the people who have access
1070 to your config file are different from the people who write your code
1071 and shouldn't have execute rights, you might want to set
1072
1073 Log::Log4perl::Config->allow_code(0);
1074
1075 before you call init(). Alternatively you can supply a restricted set
1076 of Perl opcodes that can be embedded in the config file as described in
1077 "Restricting what Opcodes can be in a Perl Hook".
1078
1079 Restricting what Opcodes can be in a Perl Hook
1080
1081 The value you pass to Log::Log4perl::Config->allow_code() determines
1082 whether the code that is embedded in the config file is eval'd unre‐
1083 stricted, or eval'd in a Safe compartment. By default, a value of '1'
1084 is assumed, which does a normal 'eval' without any restrictions. A
1085 value of '0' however prevents any embedded code from being evaluated.
1086
1087 If you would like fine-grained control over what can and cannot be
1088 included in embedded code, then please utilize the following methods:
1089
1090 Log::Log4perl::Config->allow_code( $allow );
1091 Log::Log4perl::Config->allowed_code_ops($op1, $op2, ... );
1092 Log::Log4perl::Config->vars_shared_with_safe_compartment( [ \%vars ⎪ $package, \@vars ] );
1093 Log::Log4perl::Config->allowed_code_ops_convenience_map( [ \%map ⎪ $name, \@mask ] );
1094
1095 Log::Log4perl::Config->allowed_code_ops() takes a list of opcode masks
1096 that are allowed to run in the compartment. The opcode masks must be
1097 specified as described in Opcode:
1098
1099 Log::Log4perl::Config->allowed_code_ops(':subprocess');
1100
1101 This example would allow Perl operations like backticks, system, fork,
1102 and waitpid to be executed in the compartment. Of course, you probably
1103 don't want to use this mask -- it would allow exactly what the Safe
1104 compartment is designed to prevent.
1105
1106 Log::Log4perl::Config->vars_shared_with_safe_compartment() takes the
1107 symbols which should be exported into the Safe compartment before the
1108 code is evaluated. The keys of this hash are the package names that
1109 the symbols are in, and the values are array references to the literal
1110 symbol names. For convenience, the default settings export the '%ENV'
1111 hash from the 'main' package into the compartment:
1112
1113 Log::Log4perl::Config->vars_shared_with_safe_compartment(
1114 main => [ '%ENV' ],
1115 );
1116
1117 Log::Log4perl::Config->allowed_code_ops_convenience_map() is an acces‐
1118 sor method to a map of convenience names to opcode masks. At present,
1119 the following convenience names are defined:
1120
1121 safe = [ ':browse' ]
1122 restrictive = [ ':default' ]
1123
1124 For convenience, if Log::Log4perl::Config->allow_code() is called with
1125 a value which is a key of the map previously defined with
1126 Log::Log4perl::Config->allowed_code_ops_convenience_map(), then the
1127 allowed opcodes are set according to the value defined in the map. If
1128 this is confusing, consider the following:
1129
1130 use Log::Log4perl;
1131
1132 my $config = <<'END';
1133 log4perl.logger = INFO, Main
1134 log4perl.appender.Main = Log::Log4perl::Appender::File
1135 log4perl.appender.Main.filename = \
1136 sub { "example" . getpwuid($<) . ".log" }
1137 log4perl.appender.Main.layout = Log::Log4perl::Layout::SimpleLayout
1138 END
1139
1140 $Log::Log4perl::Config->allow_code('restrictive');
1141 Log::Log4perl->init( \$config ); # will fail
1142 $Log::Log4perl::Config->allow_code('safe');
1143 Log::Log4perl->init( \$config ); # will succeed
1144
1145 The reason that the first call to ->init() fails is because the
1146 'restrictive' name maps to an opcode mask of ':default'. getpwuid() is
1147 not part of ':default', so ->init() fails. The 'safe' name maps to an
1148 opcode mask of ':browse', which allows getpwuid() to run, so ->init()
1149 succeeds.
1150
1151 allowed_code_ops_convenience_map() can be invoked in several ways:
1152
1153 allowed_code_ops_convenience_map()
1154 Returns the entire convenience name map as a hash reference in
1155 scalar context or a hash in list context.
1156
1157 allowed_code_ops_convenience_map( \%map )
1158 Replaces the entire conveniece name map with the supplied hash ref‐
1159 erence.
1160
1161 allowed_code_ops_convenience_map( $name )
1162 Returns the opcode mask for the given convenience name, or undef if
1163 no such name is defined in the map.
1164
1165 allowed_code_ops_convenience_map( $name, \@mask )
1166 Adds the given name/mask pair to the convenience name map. If the
1167 name already exists in the map, it's value is replaced with the new
1168 mask.
1169
1170 as can vars_shared_with_safe_compartment():
1171
1172 vars_shared_with_safe_compartment()
1173 Return the entire map of packages to variables as a hash reference
1174 in scalar context or a hash in list context.
1175
1176 vars_shared_with_safe_compartment( \%packages )
1177 Replaces the entire map of packages to variables with the supplied
1178 hash reference.
1179
1180 vars_shared_with_safe_compartment( $package )
1181 Returns the arrayref of variables to be shared for a specific pack‐
1182 age.
1183
1184 vars_shared_with_safe_compartment( $package, \@vars )
1185 Adds the given package / varlist pair to the map. If the package
1186 already exists in the map, it's value is replaced with the new
1187 arrayref of variable names.
1188
1189 For more information on opcodes and Safe Compartments, see Opcode and
1190 Safe.
1191
1192 Changing the Log Level on a Logger
1193
1194 Log4perl provides some internal functions for quickly adjusting the log
1195 level from within a running Perl program.
1196
1197 Now, some people might argue that you should adjust your levels from
1198 within an external Log4perl configuration file, but Log4perl is every‐
1199 body's darling.
1200
1201 Typically run-time adjusting of levels is done at the beginning, or in
1202 response to some external input (like a "more logging" runtime command
1203 for diagnostics).
1204
1205 You get the log level from a logger object with:
1206
1207 $current_level = $logger->level();
1208
1209 and you may set it with the same method, provided you first imported
1210 the log level constants, with:
1211
1212 use Log::Log4perl::Level;
1213
1214 Then you can set the level on a logger to one of the constants,
1215
1216 $logger->level($ERROR); # one of DEBUG, INFO, WARN, ERROR, FATAL
1217
1218 To increase the level of logging currently being done, use:
1219
1220 $logger->more_logging($delta);
1221
1222 and to decrease it, use:
1223
1224 $logger->less_logging($delta);
1225
1226 $delta must be a positive integer (for now, we may fix this later ;).
1227
1228 There are also two equivalent functions:
1229
1230 $logger->inc_level($delta);
1231 $logger->dec_level($delta);
1232
1233 They're included to allow you a choice in readability. Some folks will
1234 prefer more/less_logging, as they're fairly clear in what they do, and
1235 allow the programmer not to worry too much about what a Level is and
1236 whether a higher Level means more or less logging. However, other folks
1237 who do understand and have lots of code that deals with levels will
1238 probably prefer the inc_level() and dec_level() methods as they want to
1239 work with Levels and not worry about whether that means more or less
1240 logging. :)
1241
1242 That diatribe aside, typically you'll use more_logging() or inc_level()
1243 as such:
1244
1245 my $v = 0; # default level of verbosity.
1246
1247 GetOptions("v+" => \$v, ...);
1248
1249 $logger->more_logging($v); # inc logging level once for each -v in ARGV
1250
1251 Custom Log Levels
1252
1253 First off, let me tell you that creating custom levels is heavily dep‐
1254 recated by the log4j folks. Indeed, instead of creating additional lev‐
1255 els on top of the predefined DEBUG, INFO, WARN, ERROR and FATAL, you
1256 should use categories to control the amount of logging smartly, based
1257 on the location of the log-active code in the system.
1258
1259 Nevertheless, Log4perl provides a nice way to create custom levels via
1260 the create_custom_level() routine function. However, this must be done
1261 before the first call to init() or get_logger(). Say you want to create
1262 a NOTIFY logging level that comes after WARN (and thus before INFO).
1263 You'd do such as follows:
1264
1265 use Log::Log4perl;
1266 use Log::Log4perl::Level;
1267
1268 Log::Log4perl::Logger::create_custom_level("NOTIFY", "WARN");
1269
1270 And that's it! create_custom_level() creates the following functions /
1271 variables for level FOO:
1272
1273 $FOO_INT # integer to use in toLevel()
1274 $logger->foo() # log function to log if level = FOO
1275 $logger->is_foo() # true if current level is >= FOO
1276
1277 These levels can also be used in your config file, but note that your
1278 config file probably won't be portable to another log4perl or log4j
1279 environment unless you've made the appropriate mods there too.
1280
1281 System-wide log levels
1282
1283 As a fairly drastic measure to decrease (or increase) the logging level
1284 all over the system with one single configuration option, use the
1285 "threshold" keyword in the Log4perl configuration file:
1286
1287 log4perl.threshold = ERROR
1288
1289 sets the system-wide (or hierarchy-wide according to the log4j documen‐
1290 tation) to ERROR and therefore deprives every logger in the system of
1291 the right to log lower-prio messages.
1292
1293 Easy Mode
1294
1295 For teaching purposes (especially for [1]), I've put ":easy" mode into
1296 "Log::Log4perl", which just initializes a single root logger with a
1297 defined priority and a screen appender including some nice standard
1298 layout:
1299
1300 ### Initialization Section
1301 use Log::Log4perl qw(:easy);
1302 Log::Log4perl->easy_init($ERROR); # Set priority of root logger to ERROR
1303
1304 ### Application Section
1305 my $logger = get_logger();
1306 $logger->fatal("This will get logged.");
1307 $logger->debug("This won't.");
1308
1309 This will dump something like
1310
1311 2002/08/04 11:43:09 ERROR> script.pl:16 main::function - This will get logged.
1312
1313 to the screen. While this has been proven to work well familiarizing
1314 people with "Log::Logperl" slowly, effectively avoiding to clobber them
1315 over the head with a plethora of different knobs to fiddle with (cate‐
1316 gories, appenders, levels, layout), the overall mission of
1317 "Log::Log4perl" is to let people use categories right from the start to
1318 get used to the concept. So, let's keep this one fairly hidden in the
1319 man page (congrats on reading this far :).
1320
1321 Stealth loggers
1322
1323 Sometimes, people are lazy. If you're whipping up a 50-line script and
1324 want the comfort of Log::Log4perl without having the burden of carrying
1325 a separate log4perl.conf file or a 5-liner defining that you want to
1326 append your log statements to a file, you can use the following fea‐
1327 tures:
1328
1329 use Log::Log4perl qw(:easy);
1330
1331 Log::Log4perl->easy_init( { level => $DEBUG,
1332 file => ">>test.log" } );
1333
1334 # Logs to test.log via stealth logger
1335 DEBUG("Debug this!");
1336 INFO("Info this!");
1337 WARN("Warn this!");
1338 ERROR("Error this!");
1339
1340 some_function();
1341
1342 sub some_function {
1343 # Same here
1344 FATAL("Fatal this!");
1345 }
1346
1347 In ":easy" mode, "Log::Log4perl" will instantiate a stealth logger
1348 named $_default_logger and import it into the current package. Also, it
1349 will introduce the convenience functions "DEBUG()", "INFO()", "WARN()",
1350 "ERROR()" and "FATAL()" into the package namespace, which take argu‐
1351 ments and forward them to "_default_logger->debug()", "_default_log‐
1352 ger->info()" and so on.
1353
1354 The "easy_init" method can be called with a single level value to cre‐
1355 ate a STDERR appender and a root logger as in
1356
1357 Log::Log4perl->easy_init($DEBUG);
1358
1359 or, as shown below (and in the example above) with a reference to a
1360 hash, specifying values for "level" (the logger's priority), "file"
1361 (the appender's data sink), "category" (the logger's category> and
1362 "layout" for the appender's pattern layout specification. All key-
1363 value pairs are optional, they default to $DEBUG for "level", "STDERR"
1364 for "file", "" (root category) for "category" and "%d %m%n" for "lay‐
1365 out":
1366
1367 Log::Log4perl->easy_init( { level => $DEBUG,
1368 file => ">test.log",
1369 category => "Bar::Twix",
1370 layout => '%F{1}-%L-%M: %m%n' } );
1371
1372 The "file" parameter takes file names preceded by ">" (overwrite) and
1373 ">>" (append) as arguments. This will cause "Log::Log4perl::Appen‐
1374 der::File" appenders to be created behind the scenes. Also the keywords
1375 "STDOUT" and "STDERR" (no ">" or ">>") are recognized, which will uti‐
1376 lize and configure "Log::Log4perl::Appender::Screen" appropriately.
1377
1378 If a file appender receives Unicode strings, use
1379
1380 file => ":utf8> test.log"
1381
1382 to establish a utf8 line discpline on the file, otherwise you'll get a
1383 'wide character in print' warning message and probably not what you'd
1384 expect as output.
1385
1386 The stealth loggers can be used in different packages, you just need to
1387 make sure you're calling the "use" function in every package you're
1388 using "Log::Log4perl"'s easy services:
1389
1390 package Bar::Twix;
1391 use Log::Log4perl qw(:easy);
1392 sub eat { DEBUG("Twix mjam"); }
1393
1394 package Bar::Mars;
1395 use Log::Log4perl qw(:easy);
1396 sub eat { INFO("Mars mjam"); }
1397
1398 package main;
1399
1400 use Log::Log4perl qw(:easy);
1401
1402 Log::Log4perl->easy_init( { level => $DEBUG,
1403 file => ">>test.log",
1404 category => "Bar::Twix",
1405 layout => '%F{1}-%L-%M: %m%n' },
1406 { level => $DEBUG,
1407 file => "STDOUT",
1408 category => "Bar::Mars",
1409 layout => '%m%n' },
1410 );
1411 Bar::Twix::eat();
1412 Bar::Mars::eat();
1413
1414 As shown above, "easy_init()" will take any number of different logger
1415 definitions as hash references.
1416
1417 Also, stealth loggers feature the functions "LOGWARN()", "LOGDIE()",
1418 and "LOGEXIT()", combining a logging request with a subsequent Perl
1419 warn() or die() or exit() statement. So, for example
1420
1421 if($all_is_lost) {
1422 LOGDIE("Terrible Problem");
1423 }
1424
1425 will log the message if the package's logger is at least "FATAL" but
1426 "die()" (including the traditional output to STDERR) in any case after‐
1427 wards.
1428
1429 See "Log and die or warn" for the similar "logdie()" and "logwarn()"
1430 functions of regular (i.e non-stealth) loggers.
1431
1432 Similarily, "LOGCARP()", "LOGCLUCK()", "LOGCROAK()", and "LOGCONFESS()"
1433 are provided in ":easy" mode, facilitating the use of "logcarp()",
1434 "logcluck()", "logcroak()", and "logconfess()" with stealth loggers.
1435
1436 When using Log::Log4perl in easy mode, please make sure you understand
1437 the implications of "Pitfalls with Categories".
1438
1439 By the way, these convenience functions perform exactly as fast as the
1440 standard Log::Log4perl logger methods, there's no performance penalty
1441 whatsoever.
1442
1443 Nested Diagnostic Context (NDC)
1444
1445 If you find that your application could use a global (thread-specific)
1446 data stack which your loggers throughout the system have easy access
1447 to, use Nested Diagnostic Contexts (NDCs). Also check out "Mapped Diag‐
1448 nostic Context (MDC)", this might turn out to be even more useful.
1449
1450 For example, when handling a request of a web client, it's probably
1451 useful to have the user's IP address available in all log statements
1452 within code dealing with this particular request. Instead of passing
1453 this piece of data around between your application functions, you can
1454 just use the global (but thread-specific) NDC mechanism. It allows you
1455 to push data pieces (scalars usually) onto its stack via
1456
1457 Log::Log4perl::NDC->push("San");
1458 Log::Log4perl::NDC->push("Francisco");
1459
1460 and have your loggers retrieve them again via the "%x" placeholder in
1461 the PatternLayout. With the stack values above and a PatternLayout for‐
1462 mat like "%x %m%n", the call
1463
1464 $logger->debug("rocks");
1465
1466 will end up as
1467
1468 San Francisco rocks
1469
1470 in the log appender.
1471
1472 The stack mechanism allows for nested structures. Just make sure that
1473 at the end of the request, you either decrease the stack one by one by
1474 calling
1475
1476 Log::Log4perl::NDC->pop();
1477 Log::Log4perl::NDC->pop();
1478
1479 or clear out the entire NDC stack by calling
1480
1481 Log::Log4perl::NDC->remove();
1482
1483 Even if you should forget to do that, "Log::Log4perl" won't grow the
1484 stack indefinitely, but limit it to a maximum, defined in
1485 "Log::Log4perl::NDC" (currently 5). A call to "push()" on a full stack
1486 will just replace the topmost element by the new value.
1487
1488 Again, the stack is always available via the "%x" placeholder in the
1489 Log::Log4perl::Layout::PatternLayout class whenever a logger fires. It
1490 will replace "%x" by the blank-separated list of the values on the
1491 stack. It does that by just calling
1492
1493 Log::Log4perl::NDC->get();
1494
1495 internally. See details on how this standard log4j feature is imple‐
1496 mented in Log::Log4perl::NDC.
1497
1498 Mapped Diagnostic Context (MDC)
1499
1500 Just like the previously discussed NDC stores thread-specific informa‐
1501 tion in a stack structure, the MDC implements a hash table to store
1502 key/value pairs in.
1503
1504 The static method
1505
1506 Log::Log4perl::MDC->put($key, $value);
1507
1508 stores $value under a key $key, with which it can be retrieved later
1509 (possibly in a totally different part of the system) by calling the
1510 "get" method:
1511
1512 my $value = Log::Log4perl::MDC->get($key);
1513
1514 If no value has been stored previously under $key, the "get" method
1515 will return "undef".
1516
1517 Typically, MDC values are retrieved later on via the "%X{...}" place‐
1518 holder in "Log::Log4perl::Layout::PatternLayout". If the "get()" method
1519 returns "undef", the placeholder will expand to the string "[undef]".
1520
1521 An application taking a web request might store the remote host like
1522
1523 Log::Log4perl::MDC->put("remote_host", $r->headers("HOST"));
1524
1525 at its beginning and if the appender's layout looks something like
1526
1527 log4perl.appender.Logfile.layout.ConversionPattern = %X{remote_host}: %m%n
1528
1529 then a log statement like
1530
1531 DEBUG("Content delivered");
1532
1533 will log something like
1534
1535 adsl-63.dsl.snf.pacbell.net: Content delivered
1536
1537 later on in the program.
1538
1539 For details, please check Log::Log4perl::MDC.
1540
1541 Resurrecting hidden Log4perl Statements
1542
1543 Sometimes scripts need to be deployed in environments without having
1544 Log::Log4perl installed yet. On the other hand, you dont't want to live
1545 without your Log4perl statements -- they're gonna come in handy later.
1546
1547 So, just deploy your script with Log4perl statements commented out with
1548 the pattern "###l4p", like in
1549
1550 ###l4p DEBUG "It works!";
1551 # ...
1552 ###l4p INFO "Really!";
1553
1554 If Log::Log4perl is available, use the ":resurrect" tag to have
1555 Log4perl resurrect those burried statements before the script starts
1556 running:
1557
1558 use Log::Log4perl qw(:resurrect :easy);
1559
1560 ###l4p Log::Log4perl->easy_init($DEBUG);
1561 ###l4p DEBUG "It works!";
1562 # ...
1563 ###l4p INFO "Really!";
1564
1565 This will have a source filter kick in and indeed print
1566
1567 2004/11/18 22:08:46 It works!
1568 2004/11/18 22:08:46 Really!
1569
1570 In environments lacking Log::Log4perl, just comment out the first line
1571 and the script will run nevertheless (but of course without logging):
1572
1573 # use Log::Log4perl qw(:resurrect :easy);
1574
1575 ###l4p Log::Log4perl->easy_init($DEBUG);
1576 ###l4p DEBUG "It works!";
1577 # ...
1578 ###l4p INFO "Really!";
1579
1580 because everything's a regular comment now. Alternatively, put the
1581 magic Log::Log4perl comment resurrection line into your shell's
1582 PERL5OPT environment variable, e.g. for bash:
1583
1584 set PERL5OPT=-MLog::Log4perl=:resurrect,:easy
1585 export PERL5OPT
1586
1587 This will awaken the giant within an otherwise silent script like the
1588 following:
1589
1590 #!/usr/bin/perl
1591
1592 ###l4p Log::Log4perl->easy_init($DEBUG);
1593 ###l4p DEBUG "It works!";
1594
1595 Access defined appenders
1596
1597 All appenders defined in the configuration file or via Perl code can be
1598 retrieved by the "appender_by_name()" class method. This comes in handy
1599 if you want to manipulate or query appender properties after the
1600 Log4perl configuration has been loaded via "init()".
1601
1602 Note that internally, Log::Log4perl uses the "Log::Log4perl::Appender"
1603 wrapper class to control the real appenders (like
1604 "Log::Log4perl::Appender::File" or "Log::Dispatch::FileRotate"). The
1605 "Log::Log4perl::Appender" class has an "appender" attribute, pointing
1606 to the real appender.
1607
1608 The reason for this is that external appenders like "Log::Dis‐
1609 patch::FileRotate" don't support all of Log::Log4perl's appender con‐
1610 trol mechanisms (like appender thresholds).
1611
1612 The previously mentioned method "appender_by_name()" returns a refer‐
1613 rence to the real appender object. If you want access to the wrapper
1614 class (e.g. if you want to modify the appender's threshold), use the
1615 hash $Log::Log4perl::Logger::APPENDER_BY_NAME{...} instead, which holds
1616 references all appender wrapper objects.
1617
1618 Modify appender thresholds
1619
1620 To conveniently adjust appender thresholds (e.g. because a script uses
1621 more_logging()), use
1622
1623 # decrease thresholds of all appenders
1624 Log::Log4perl->appender_thresholds_adjust(-1);
1625
1626 This will decrease the thresholds of all appenders in the system by one
1627 level, i.e. WARN becomes INFO, INFO becomes DEBUG, etc. To only modify
1628 selected ones, use
1629
1630 # decrease thresholds of all appenders
1631 Log::Log4perl->appender_thresholds_adjust(-1, ['AppName1', ...]);
1632
1633 and pass the names of affected appenders in a ref to an array.
1634
1636 Initializing Log::Log4perl can certainly also be done from within Perl.
1637 At last, this is what "Log::Log4perl::Config" does behind the scenes.
1638 Log::Log4perl's configuration file parsers are using a publically
1639 available API to set up Log::Log4perl's categories, appenders and lay‐
1640 outs.
1641
1642 Here's an example on how to configure two appenders with the same lay‐
1643 out in Perl, without using a configuration file at all:
1644
1645 ########################
1646 # Initialization section
1647 ########################
1648 use Log::Log4perl;
1649 use Log::Log4perl::Layout;
1650 use Log::Log4perl::Level;
1651
1652 # Define a category logger
1653 my $log = Log::Log4perl->get_logger("Foo::Bar");
1654
1655 # Define a layout
1656 my $layout = Log::Log4perl::Layout::PatternLayout->new("[%r] %F %L %m%n");
1657
1658 # Define a file appender
1659 my $file_appender = Log::Log4perl::Appender->new(
1660 "Log::Log4perl::Appender::File",
1661 name => "filelog",
1662 filename => "/tmp/my.log");
1663
1664 # Define a stdout appender
1665 my $stdout_appender = Log::Log4perl::Appender->new(
1666 "Log::Log4perl::Appender::Screen",
1667 name => "screenlog",
1668 stderr => 0);
1669
1670 # Have both appenders use the same layout (could be different)
1671 $stdout_appender->layout($layout);
1672 $file_appender->layout($layout);
1673
1674 $log->add_appender($stdout_appender);
1675 $log->add_appender($file_appender);
1676 $log->level($INFO);
1677
1678 Please note the class of the appender object is passed as a string to
1679 "Log::Log4perl::Appender" in the first argument. Behind the scenes,
1680 "Log::Log4perl::Appender" will create the necessary
1681 "Log::Log4perl::Appender::*" (or "Log::Dispatch::*") object and pass
1682 along the name value pairs we provided to "Log::Log4perl::Appen‐
1683 der->new()" after the first argument.
1684
1685 The "name" value is optional and if you don't provide one,
1686 "Log::Log4perl::Appender->new()" will create a unique one for you. The
1687 names and values of additional parameters are dependent on the require‐
1688 ments of the particular appender class and can be looked up in their
1689 manual pages.
1690
1691 A side note: In case you're wondering if "Log::Log4perl::Appen‐
1692 der->new()" will also take care of the "min_level" argument to the
1693 "Log::Dispatch::*" constructors called behind the scenes -- yes, it
1694 does. This is because we want the "Log::Dispatch" objects to blindly
1695 log everything we send them ("debug" is their lowest setting) because
1696 we in "Log::Log4perl" want to call the shots and decide on when and
1697 what to log.
1698
1699 The call to the appender's layout() method specifies the format (as a
1700 previously created "Log::Log4perl::Layout::PatternLayout" object) in
1701 which the message is being logged in the specified appender. If you
1702 don't specify a layout, the logger will fall back to
1703 "Log::Log4perl::SimpleLayout", which logs the debug level, a hyphen (-)
1704 and the log message.
1705
1706 Layouts are objects, here's how you create them:
1707
1708 # Create a simple layout
1709 my $simple = Log::Log4perl::SimpleLayout();
1710
1711 # create a flexible layout:
1712 # ("yyyy/MM/dd hh:mm:ss (file:lineno)> message\n")
1713 my $pattern = Log::Log4perl::Layout::PatternLayout("%d (%F:%L)> %m%n");
1714
1715 Every appender has exactly one layout assigned to it. You assign the
1716 layout to the appender using the appender's "layout()" object:
1717
1718 my $app = Log::Log4perl::Appender->new(
1719 "Log::Log4perl::Appender::Screen",
1720 name => "screenlog",
1721 stderr => 0);
1722
1723 # Assign the previously defined flexible layout
1724 $app->layout($pattern);
1725
1726 # Add the appender to a previously defined logger
1727 $logger->add_appender($app);
1728
1729 # ... and you're good to go!
1730 $logger->debug("Blah");
1731 # => "2002/07/10 23:55:35 (test.pl:207)> Blah\n"
1732
1733 It's also possible to remove appenders from a logger:
1734
1735 $logger->remove_appender($appender_name);
1736
1737 will remove an appender, specified by name, from a given logger.
1738 Please note that this does not remove an appender from the system.
1739
1740 To eradicate an appender from the system, you need to call
1741 "Log::Log4perl->eradicate_appender($appender_name)" which will first
1742 remove the appender from every logger in the system and then will
1743 delete all references Log4perl holds to it.
1744
1746 Tatsuhiko Miyagawa's "Log::Dispatch::Config" is a very clever simpli‐
1747 fied logger implementation, covering some of the log4j functionality.
1748 Among the things that "Log::Log4perl" can but "Log::Dispatch::Config"
1749 can't are:
1750
1751 · You can't assign categories to loggers. For small systems that's
1752 fine, but if you can't turn off and on detailed logging in only a
1753 tiny subsystem of your environment, you're missing out on a majorly
1754 useful log4j feature.
1755
1756 · Defining appender thresholds. Important if you want to solve prob‐
1757 lems like "log all messages of level FATAL to STDERR, plus log all
1758 DEBUG messages in "Foo::Bar" to a log file". If you don't have
1759 appenders thresholds, there's no way to prevent cluttering STDERR
1760 with DEBUG messages.
1761
1762 · PatternLayout specifications in accordance with the standard (e.g.
1763 "%d{HH:mm}").
1764
1765 Bottom line: Log::Dispatch::Config is fine for small systems with sim‐
1766 ple logging requirements. However, if you're designing a system with
1767 lots of subsystems which you need to control independantly, you'll love
1768 the features of "Log::Log4perl", which is equally easy to use.
1769
1771 If you don't use "Log::Log4perl" as described above, but from a wrapper
1772 class (like your own Logging class which in turn uses "Log::Log4perl"),
1773 the pattern layout will generate wrong data for %F, %C, %L and the
1774 like. Reason for this is that "Log::Log4perl"'s loggers assume a
1775 static caller depth to the application that's using them. If you're
1776 using one (or more) wrapper classes, "Log::Log4perl" will indicate
1777 where your logger classes called the loggers, not where your applica‐
1778 tion called your wrapper, which is probably what you want in this case.
1779 But don't dispair, there's a solution: Just increase the value of
1780 $Log::Log4perl::caller_depth (defaults to 0) by one for every wrapper
1781 that's in between your application and "Log::Log4perl", then
1782 "Log::Log4perl" will compensate for the difference.
1783
1785 The following methods are only of use if you want to peek/poke in the
1786 internals of Log::Log4perl. Be careful not to disrupt its inner work‐
1787 ings.
1788
1789 "Log::Log4perl->appenders()"
1790 To find out which appenders are currently defined (not only for a
1791 particular logger, but overall), a "appenders()" method is avail‐
1792 able to return a reference to a hash mapping appender names to
1793 their Log::Log4perl::Appender object references.
1794
1796 infiltrate_lwp()
1797 The famous LWP::UserAgent module isn't Log::Log4perl-enabled.
1798 Often, though, especially when tracing Web-related problems, it
1799 would be helpful to get some insight on what's happening inside
1800 LWP::UserAgent. Ideally, LWP::UserAgent would even play along in
1801 the Log::Log4perl framework.
1802
1803 A call to "Log::Log4perl->infiltrate_lwp()" does exactly this. In
1804 a very rude way, it pulls the rug from under LWP::UserAgent and
1805 transforms its "debug/conn" messages into "debug()" calls of log‐
1806 gers of the category "LWP::UserAgent". Similarily, "LWP::UserA‐
1807 gent"'s "trace" messages are turned into "Log::Log4perl"'s "info()"
1808 method calls.
1809
1810 Suppressing 'duplicate' LOGDIE messages
1811 If a script with a simple Log4perl configuration uses logdie() to
1812 catch errors and stop processing, as in
1813
1814 use Log::Log4perl qw(:easy) ;
1815 Log::Log4perl->easy_init($DEBUG);
1816
1817 shaky_function() or LOGDIE "It failed!";
1818
1819 there's a cosmetic problem: The message gets printed twice:
1820
1821 2005/07/10 18:37:14 It failed!
1822 It failed! at ./t line 12
1823
1824 The obvious solution is to use LOGEXIT() instead of LOGDIE(), but
1825 there's also a special tag for Log4perl that suppresses the second
1826 message:
1827
1828 use Log::Log4perl qw(:no_extra_logdie_message);
1829
1830 This causes logdie() and logcroak() to call exit() instead of
1831 die(). To modify the script exit code in these occasions, set the
1832 variable $Log::Log4perl::LOGEXIT_CODE to the desired value, the
1833 default is 1.
1834
1836 A simple example to cut-and-paste and get started:
1837
1838 use Log::Log4perl qw(get_logger);
1839
1840 my $conf = q(
1841 log4perl.category.Bar.Twix = WARN, Logfile
1842 log4perl.appender.Logfile = Log::Log4perl::Appender::File
1843 log4perl.appender.Logfile.filename = test.log
1844 log4perl.appender.Logfile.layout = \
1845 Log::Log4perl::Layout::PatternLayout
1846 log4perl.appender.Logfile.layout.ConversionPattern = %d %F{1} %L> %m %n
1847 );
1848
1849 Log::Log4perl::init(\$conf);
1850
1851 my $logger = get_logger("Bar::Twix");
1852 $logger->error("Blah");
1853
1854 This will log something like
1855
1856 2002/09/19 23:48:15 t1 25> Blah
1857
1858 to the log file "test.log", which Log4perl will append to or create it
1859 if it doesn't exist already.
1860
1862 If you want to use external appenders provided with "Log::Dispatch",
1863 you need to install "Log::Dispatch" (2.00 or better) from CPAN, which
1864 itself depends on "Attribute-Handlers" and "Params-Validate". And a lot
1865 of other modules, that's the reason why we're now shipping
1866 Log::Log4perl with its own standard appenders and only if you wish to
1867 use additional ones, you'll have to go through the "Log::Dispatch"
1868 installation process.
1869
1870 Log::Log4perl needs "Test::More", "Test::Harness" and "File::Spec", but
1871 they already come with fairly recent versions of perl. If not, every‐
1872 thing's automatically fetched from CPAN if you're using the CPAN shell
1873 (CPAN.pm), because they're listed as dependencies.
1874
1875 "Time::HiRes" (1.20 or better) is required only if you need the fine-
1876 grained time stamps of the %r parameter in "Log::Log4perl::Layout::Pat‐
1877 ternLayout".
1878
1879 Manual installation works as usual with
1880
1881 perl Makefile.PL
1882 make
1883 make test
1884 make install
1885
1886 If you're running Windows (98, 2000, NT, XP etc.), and you're too lazy
1887 to rummage through all of Log-Log4perl's dependencies, don't despair:
1888 We're providing a PPM package which installs easily with your Actives‐
1889 tate Perl. Check "how_can_i_install_log__log4perl_on_microsoft_windows"
1890 in Log::Log4perl::FAQ for details.
1891
1893 Log::Log4perl is still being actively developed. We will always make
1894 sure the test suite (approx. 500 cases) will pass, but there might
1895 still be bugs. please check http://log4perl.sourceforge.net for the
1896 latest release. The api has reached a mature state, we will not change
1897 it unless for a good reason.
1898
1899 Bug reports and feedback are always welcome, just email them to our
1900 mailing list shown in the AUTHORS section. We're usually addressing
1901 them immediately.
1902
1904 [1] Michael Schilli, "Retire your debugger, log smartly with
1905 Log::Log4perl!", Tutorial on perl.com, 09/2002,
1906 http://www.perl.com/pub/a/2002/09/11/log4perl.html
1907
1908 [2] Ceki Gülcü, "Short introduction to log4j",
1909 http://jakarta.apache.org/log4j/docs/manual.html
1910
1911 [3] Vipan Singla, "Don't Use System.out.println! Use Log4j.",
1912 http://www.vipan.com/htdocs/log4jhelp.html
1913
1914 [4] The Log::Log4perl project home page: http://log4perl.source‐
1915 forge.net
1916
1918 Log::Log4perl::Config, Log::Log4perl::Appender, Log::Log4perl::Lay‐
1919 out::PatternLayout, Log::Log4perl::Layout::SimpleLayout,
1920 Log::Log4perl::Level, Log::Log4perl::JavaMap Log::Log4perl::NDC,
1921
1923 Please send bug reports or requests for enhancements to the authors via
1924 our
1925
1926 MAILING LIST (questions, bug reports, suggestions/patches):
1927 log4perl-devel@lists.sourceforge.net
1928
1929 Authors (please contact them via the list above, not directly)
1930 Mike Schilli <m@perlmeister.com>
1931 Kevin Goess <cpan@goess.org>
1932
1933 Contributors (in alphabetical order):
1934 Ateeq Altaf, Cory Bennett, Jeremy Bopp, Hutton Davidson, Chris R.
1935 Donnelly, Matisse Enzer, Hugh Esco, James FitzGibbon, Carl Franks,
1936 Dennis Gregorovic, Paul Harrington, David Hull, Robert Jacobson,
1937 Jeff Macdonald, Markus Peter, Brett Rann, Erik Selberg, Aaron
1938 Straup Cope, Lars Thegler, David Viner, Mac Yang.
1939
1941 Copyright 2002-2007 by Mike Schilli <m@perlmeister.com> and Kevin Goess
1942 <cpan@goess.org>.
1943
1944 This library is free software; you can redistribute it and/or modify it
1945 under the same terms as Perl itself.
1946
1947
1948
1949perl v5.8.8 2002-07-10 Log::Log4perl(3)