home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / FAQ.pm < prev    next >
Encoding:
Perl POD Document  |  2003-05-03  |  50.4 KB  |  1,376 lines

  1. 1;
  2.  
  3. __END__
  4.  
  5. =head1 NAME
  6.  
  7. Log::Log4perl::FAQ - Frequently Asked Questions on Log::Log4perl
  8.  
  9. =head1 DESCRIPTION
  10.  
  11. This FAQ shows a wide variety of 
  12. commonly encountered logging tasks and how to solve them 
  13. in the most elegant way with Log::Log4perl. Most of the time, this will
  14. be just a matter of smartly configuring your Log::Log4perl configuration files.
  15.  
  16. This document is supposed to grow week by week as the latest
  17. "Log::Log4perl recipe of the week" hits the Log::Log4perl mailing list
  18. at C<log4perl-devel@lists.sourceforge.net>.
  19.  
  20. =head2 How can I simply log all my ERROR messages to a file?
  21.  
  22. After pulling in the C<Log::Log4perl> module, just initialize its
  23. behaviour by passing in a configuration to its C<init> method as a string
  24. reference. Then, obtain a logger instance and write out a message
  25. with its C<error()> method:
  26.  
  27.     use Log::Log4perl qw(get_logger);
  28.  
  29.         # Define configuration
  30.     my $conf = q(
  31.         log4perl.logger                    = ERROR, FileApp
  32.         log4perl.appender.FileApp          = Log::Dispatch::File
  33.         log4perl.appender.FileApp.filename = test.log
  34.         log4perl.appender.FileApp.layout   = PatternLayout
  35.         log4perl.appender.FileApp.layout.ConversionPattern = %d> %m%n
  36.     );
  37.  
  38.         # Initialize logging behaviour
  39.     Log::Log4perl->init( \$conf );
  40.  
  41.         # Obtain a logger instance
  42.     my $logger = get_logger("Bar::Twix");
  43.     $logger->error("Oh my, a dreadful error!");
  44.     $logger->warn("Oh my, a dreadful warning!");
  45.  
  46. This will append something like
  47.  
  48.     2002/10/29 20:11:55> Oh my, a dreadful error!
  49.  
  50. to the log file C<test.log>. How does this all work? 
  51.  
  52. While the Log::Log4perl C<init()> method typically 
  53. takes the name of a configuration file as its input parameter like
  54. in
  55.  
  56.     Log::Log4perl->init( "/path/mylog.conf" );
  57.  
  58. the example above shows how to pass in a configuration as text in a 
  59. scalar reference.
  60.  
  61. The configuration as shown
  62. defines a logger of the root category, which has an appender of type 
  63. C<Log::Dispatch::File> attached. The line
  64.  
  65.     log4perl.logger = ERROR, FileApp
  66.  
  67. doesn't list a category, defining a root logger. Compare that with
  68.  
  69.     log4perl.logger.Bar.Twix = ERROR, FileApp
  70.  
  71. which would define a logger for the category C<Bar::Twix>,
  72. showing probably different behaviour. C<FileApp> on
  73. the right side of the assignment is
  74. an arbitrarily defined variable name, which is only used to somehow 
  75. reference an appender defined later on.
  76.  
  77. Appender settings in the configuration are defined as follows:
  78.  
  79.     log4perl.appender.FileApp          = Log::Dispatch::File
  80.     log4perl.appender.FileApp.filename = test.log
  81.  
  82. It selects the file appender of the C<Log::Dispatch> hierarchy, 
  83. which is tricked by Log::Log4perl into thinking that it should append to the
  84. file C<test.log> if it already exists. If we wanted to overwrite
  85. a potentially existing file, we would have to explicitly set the
  86. appropriate C<Log::Dispatch::File> parameter C<mode>:
  87.  
  88.     log4perl.appender.FileApp          = Log::Dispatch::File
  89.     log4perl.appender.FileApp.filename = test.log
  90.     log4perl.appender.FileApp.mode     = write
  91.  
  92. Also, the configuration defines a PatternLayout format, adding
  93. the nicely formatted current date and time, an arrow (E<gt>) and
  94. a space before the messages, which is then followed by a newline:
  95.  
  96.     log4perl.appender.FileApp.layout   = PatternLayout
  97.     log4perl.appender.FileApp.layout.ConversionPattern = %d> %m%n
  98.  
  99. Obtaining a logger instance and actually logging something is typically
  100. done in a different system part as the Log::Log4perl initialisation section,
  101. but in this example, it's just done right after init for the 
  102. sake of compactness:
  103.  
  104.         # Obtain a logger instance
  105.     my $logger = get_logger("Bar::Twix");
  106.     $logger->error("Oh my, a dreadful error!");
  107.  
  108. This retrieves an instance of the logger of the category C<Bar::Twix>, 
  109. which, as all other categories, inherits behaviour from the root logger if no
  110. other loggers are defined in the initialization section. 
  111.  
  112. The C<error()>
  113. method fires up a message, which the root logger catches. Its
  114. priority is equal to
  115. or higher than the root logger's priority (ERROR), which causes the root logger
  116. to forward it to its attached appender. By contrast, the following
  117.  
  118.     $logger->warn("Oh my, a dreadful warning!");
  119.  
  120. doesn't make it through, because the root logger sports a higher setting
  121. (ERROR and up) than the WARN priority of the message.
  122.  
  123. =head2 How can I install Log::Log4perl on Microsoft Windows?
  124.  
  125. Log::Log4perl is fully supported on the Win32 platform. It has been tested 
  126. with Activestate perl 5.6.1 under Windows 98 and rumor has it that it
  127. also runs smoothly on all other major flavors (Windows NT, 2000, XP, etc.).
  128.  
  129. It also runs nicely with ActiveState 5.8.0, and, believe me, 
  130. we had to jump through some major hoops for that.
  131.  
  132. Typically, Win32 systems don't have the C<make> utility installed,
  133. so the standard C<perl Makefile.PL; make install> on the downloadable
  134. distribution won't work. But don't despair, there's a very easy solution!
  135.  
  136. The C<Log::Log4perl> homepage provides a so-called PPD file for ActiveState's
  137. C<ppm> installer, which comes with ActiveState perl by default.
  138.  
  139. =over 4
  140.  
  141. =item Install on ActiveState 5.6.*
  142.  
  143. The DOS command line
  144.  
  145.     ppm install "http://log4perl.sourceforge.net/ppm/Log-Log4perl.ppd"
  146.  
  147. will contact the Log4perl homepage, download the latest
  148. C<Log::Log4perl>
  149. distribution and install it. If your ActiveState installation
  150. lacks any of the modules C<Log::Log4perl> depends upon, C<ppm> will 
  151. automatically contact ActivateState and download them from their CPAN-like
  152. repository.
  153.  
  154. =item Install on ActiveState 5.8.*
  155.  
  156. ActiveState's "Programmer's Package Manager" can be called from
  157. Window's Start Menu:
  158. Start-E<gt>Programs->E<gt>ActiveState ActivePerl 5.8E<gt>Perl Package Manager
  159. will invoke ppm. Since Log::Log4perl hasn't made it yet into the standard
  160. ActiveState repository (and you probably don't want their outdated packages
  161. anyway), just tell ppm the first time you call it to add the Log4perl 
  162. repository
  163.  
  164.     ppm> repository add http://log4perl.sourceforge.net/ppm
  165.  
  166. Then, just tell it to install Log::Log4perl and it will resolve all
  167. dependencies automatically and fetch them from log4perl.sourceforge.net
  168. if it can't find them in the main archives:
  169.  
  170.     ppm> install Log::Log4perl
  171.  
  172. =back
  173.  
  174. That's it! Afterwards, just create a Perl script like
  175.  
  176.     use Log::Log4perl qw(:easy);
  177.     Log::Log4perl->easy_init($DEBUG);
  178.  
  179.     my $logger = get_logger("Twix::Bar");
  180.     $logger->debug("Watch me!");
  181.  
  182. and run it. It should print something like 
  183.  
  184.     2002/11/06 01:22:05 Watch me!
  185.  
  186. If you find that something doesn't work, please let us know at
  187. log4perl-devel@lists.sourceforge.net -- we'll apprechiate it. Have fun!
  188.  
  189. =head2 What's the easiest way to use Log4perl?
  190.  
  191. If you just want to get all the comfort of logging, without much
  192. overhead, use I<Stealth Loggers>. If you use Log::Log4perl in 
  193. C<:easy> mode like
  194.  
  195.     use Log::Log4perl qw(:easy);
  196.  
  197. you'll have the following functions available in the current package:
  198.  
  199.     DEBUG("message");
  200.     INFO("message");
  201.     WARN("message");
  202.     ERROR("message");
  203.     FATAL("message");
  204.  
  205. Just make sure that every package of your code where you're using them in
  206. pulls in C<use Log::Log4perl qw(:easy)> first, then you're set.
  207. Every stealth logger's category will be equivalent to the name of the
  208. package it's located in.
  209.  
  210. These stealth loggers
  211. will be absolutely silent until you initialize Log::Log4perl in 
  212. your main program with either 
  213.  
  214.         # Define any Log4perl behaviour
  215.     Log::Log4perl->init("foo.conf");
  216.  
  217. (using a full-blown Log4perl config file) or the super-easy method
  218.  
  219.         # Just log to STDERR
  220.     Log::Log4perl->easy_init($DEBUG);
  221.  
  222. or the parameter-style method with a complexity somewhat in between:
  223.  
  224.         # Append to a log file
  225.     Log::Log4perl->easy_init( { level   => $DEBUG,
  226.                                 file    => ">>test.log" } );
  227.  
  228. For more info, please check out L<Log::Log4perl/"Stealth Loggers">.
  229.  
  230. =head2 How can I include global (thread-specific) data in my log messages?
  231.  
  232. Say, you're writing a web application and want all your
  233. log messages to include the current client's IP address. Most certainly,
  234. you don't want to include it in each and every log message like in
  235.  
  236.     $logger->debug( $r->connection->remote_ip,
  237.                     " Retrieving user data from DB" );
  238.  
  239. do you? Instead, you want to set it in a global data structure and
  240. have Log::Log4perl include it automatically via a PatternLayout setting
  241. in the configuration file:
  242.  
  243.     log4perl.appender.FileApp.layout.ConversionPattern = %X{ip} %m%n
  244.  
  245. The conversion specifier C<%X{ip}> references an entry under the key
  246. C<ip> in the global C<MDC> (mapped diagnostic context) table, which 
  247. you've set once via
  248.  
  249.     Log::Log4perl::MDC->put("ip", $r->connection->remote_ip);
  250.  
  251. at the start of the request handler. Note that this is a
  252. I<static> (class) method, there's no logger object involved.
  253. You can use this method with as many key/value pairs as you like as long
  254. as you reference them under different names.
  255.  
  256. The mappings are stored in a global hash table within Log::Log4perl.
  257. Luckily, because the thread
  258. model in 5.8.0 doesn't share global variables between threads unless
  259. they're explicitly marked as such, there's no problem with multi-threaded
  260. environments.
  261.  
  262. For more details on the MDC, please refer to 
  263. L<Log::Log4perl/"Mapped Diagnostic Context (MDC)"> and
  264. L<Log::Log4perl::MDC>.
  265.  
  266. =head2 My application is already logging to a file. How can I duplicate all messages to also go to the screen?
  267.  
  268. Assuming that you already have a Log4perl configuration file like
  269.  
  270.     log4perl.logger                    = DEBUG, FileApp
  271.  
  272.     log4perl.appender.FileApp          = Log::Dispatch::File
  273.     log4perl.appender.FileApp.filename = test.log
  274.     log4perl.appender.FileApp.layout   = PatternLayout
  275.     log4perl.appender.FileApp.layout.ConversionPattern = %d> %m%n
  276.  
  277. and log statements all over your code,
  278. it's very easy with Log4perl to have the same messages both printed to
  279. the logfile and the screen. No reason to change your code, of course, 
  280. just add another appender to the configuration file and you're done:
  281.  
  282.     log4perl.logger                    = DEBUG, FileApp, ScreenApp
  283.  
  284.     log4perl.appender.FileApp          = Log::Dispatch::File
  285.     log4perl.appender.FileApp.filename = test.log
  286.     log4perl.appender.FileApp.layout   = PatternLayout
  287.     log4perl.appender.FileApp.layout.ConversionPattern = %d> %m%n
  288.  
  289.     log4perl.appender.ScreenApp          = Log::Dispatch::Screen
  290.     log4perl.appender.ScreenApp.stderr   = 0
  291.     log4perl.appender.ScreenApp.layout   = PatternLayout
  292.     log4perl.appender.ScreenApp.layout.ConversionPattern = %d> %m%n
  293.  
  294. The configuration file above is assuming that both appenders are
  295. active in the same logger hierarchy, in this case the C<root> category.
  296. But even if you've got file loggers defined in several parts of your system,
  297. belonging to different logger categories,
  298. each logging to different files, you can gobble up all logged messages
  299. by defining a root logger with a screen appender, which would duplicate 
  300. messages from all your file loggers to the screen due to Log4perl's 
  301. appender inheritance. Check 
  302.  
  303.     http://www.perl.com/pub/a/2002/09/11/log4perl.html
  304.  
  305. for details. Have fun!
  306.  
  307. =head2 How can I make sure my application logs a message when it dies unexpectedly?
  308.  
  309. Whenever you encounter a fatal error in your application, instead of saying
  310. something like
  311.  
  312.     open FILE, "<blah" or die "Can't open blah -- bailing out!";
  313.  
  314. just use Log::Log4perl's fatal functions instead:
  315.  
  316.     my $log = get_logger("Some::Package");
  317.     open FILE, "<blah" or $log->logdie("Can't open blah -- bailing out!");
  318.  
  319. This will both log the message with priority FATAL according to your current
  320. Log::Log4perl configuration and then call Perl's C<die()> 
  321. afterwards to terminate the program. It works the same with 
  322. stealth loggers (see L<Log::Log4perl/"Stealth Loggers">), 
  323. all you need to do is call
  324.  
  325.     use Log::Log4perl qw(:easy);
  326.     open FILE, "<blah" or LOGDIE "Can't open blah -- bailing out!";
  327.  
  328. What can you do if you're using some library which doesn't use Log::Log4perl
  329. and calls C<die()> internally if something goes wrong? Use a
  330. C<$SIG{__DIE__}> pseudo signal handler
  331.  
  332.     use Log::Log4perl qw(get_logger);
  333.  
  334.     $SIG{__DIE__} = sub {
  335.         $Log::Log4perl::caller_depth++;
  336.         my $logger = get_logger("");
  337.         $logger->fatal(@_);
  338.         exit 1;
  339.     };
  340.  
  341. This will catch every C<die()>-Exception of your
  342. application or the modules it uses. It
  343. will fetch a root logger and pass on the C<die()>-Message to it.
  344. If you make sure you've configured with a root logger like this:
  345.  
  346.     Log::Log4perl->init(\q{
  347.         log4perl.category         = FATAL, Logfile
  348.         log4perl.appender.Logfile = Log::Dispatch::File
  349.         log4perl.appender.Logfile.filename = fatal_errors.log
  350.         log4perl.appender.Logfile.layout = \
  351.                    Log::Log4perl::Layout::PatternLayout
  352.         log4perl.appender.Logfile.layout.ConversionPattern = %F{1}-%L (%M)> %m%n
  353.     });
  354.  
  355. then all C<die()> messages will be routed to a file properly. The line
  356.  
  357.      $Log::Log4perl::caller_depth++;
  358.  
  359. in the pseudo signal handler above merits a more detailed explanation. With
  360. the setup above, if a module calls C<die()> in one of its functions, 
  361. the fatal message will be logged in the signal handler and not in the
  362. original function -- which will cause the %F, %L and %M placeholders
  363. in the pattern layout to be replaced by the filename, the line number
  364. and the function/method name of the signal handler, not the error-throwing
  365. module. To adjust this, Log::Log4perl has the C<$caller_depth> variable, 
  366. which defaults to 0, but can be set to positive integer values
  367. to offset the caller level. Increasing
  368. it by one will cause it to log the calling function's parameters, not
  369. the ones of the signal handler. 
  370. See L<Log::Log4perl/"Using Log::Log4perl from wrapper classes"> for more
  371. details.
  372.  
  373. =head2 How can I hook up the LWP library with Log::Log4perl?
  374.  
  375. Or, to put it more generally: How can you utilize a third-party
  376. library's embedded logging and debug statements in Log::Log4perl? 
  377. How can you make them print
  378. to configurable appenders, turn them on and off, just as if they 
  379. were regular Log::Log4perl logging statements?
  380.  
  381. The easiest solution is to map the third-party library logging statements
  382. to Log::Log4perl's stealth loggers via a typeglob assignment.
  383.  
  384. As an example, let's take LWP, one of the most popular Perl modules, 
  385. which makes handling WWW requests and responses a breeze.
  386. Internally, LWP uses its own logging and debugging system, 
  387. utilizing the following calls 
  388. inside the LWP code (from the LWP::Debug man page):
  389.  
  390.         # Function tracing
  391.     LWP::Debug::trace('send()');
  392.  
  393.         # High-granular state in functions
  394.     LWP::Debug::debug('url ok');
  395.  
  396.         # Data going over the wire
  397.     LWP::Debug::conns("read $n bytes: $data");
  398.  
  399. First, let's assign Log::Log4perl priorities 
  400. to these functions: I'd suggest that
  401. C<debug()> messages have priority C<INFO>, 
  402. C<trace()> uses C<DEBUG> and C<conns()> also logs with C<DEBUG> -- 
  403. although your mileage may certainly vary.
  404.  
  405. Now, in order to transpartently hook up LWP::Debug with Log::Log4perl,
  406. all we have to do is say
  407.  
  408.     package LWP::Debug;
  409.     use Log::Log4perl qw(:easy);
  410.  
  411.     *trace = *INFO;
  412.     *conns = *DEBUG;
  413.     *debug = *DEBUG;
  414.  
  415.     package main;
  416.     # ... go on with your regular program ...
  417.  
  418. at the beginning of our program. In this way, every time the, say, 
  419. C<LWP::UserAgent> module calls C<LWP::Debug::trace()>, it will implicitely 
  420. call INFO(), which is the C<info()> method of a stealth logger defined for
  421. the Log::Log4perl category C<LWP::Debug>. Is this cool or what?
  422.  
  423. Here's a complete program:
  424.  
  425.     use LWP::UserAgent;
  426.     use HTTP::Request::Common;
  427.     use Log::Log4perl qw(:easy);
  428.  
  429.     Log::Log4perl->easy_init(
  430.         { category => "LWP::Debug",
  431.           level    => $DEBUG,
  432.           layout   => "%r %p %M-%L %m%n",
  433.         });
  434.  
  435.     package LWP::Debug;
  436.     use Log::Log4perl qw(:easy);
  437.     *trace = *INFO;
  438.     *conns = *DEBUG;
  439.     *debug = *DEBUG;
  440.  
  441.     package main;
  442.     my $ua = LWP::UserAgent->new();
  443.     my $resp = $ua->request(GET "http://amazon.com");
  444.  
  445.     if($resp->is_success()) {
  446.         print "Success: Received ", 
  447.               length($resp->content()), "\n";
  448.     } else {
  449.         print "Error: ", $resp->code(), "\n";
  450.     }
  451.  
  452. This will generate the following output on STDERR:
  453.  
  454.     174 INFO LWP::UserAgent::new-164 ()
  455.     208 INFO LWP::UserAgent::request-436 ()
  456.     211 INFO LWP::UserAgent::send_request-294 GET http://amazon.com
  457.     212 DEBUG LWP::UserAgent::_need_proxy-1123 Not proxied
  458.     405 INFO LWP::Protocol::http::request-122 ()
  459.     859 DEBUG LWP::Protocol::collect-206 read 233 bytes
  460.     863 DEBUG LWP::UserAgent::request-443 Simple response: Found
  461.     869 INFO LWP::UserAgent::request-436 ()
  462.     871 INFO LWP::UserAgent::send_request-294 
  463.      GET http://www.amazon.com:80/exec/obidos/gateway_redirect
  464.     872 DEBUG LWP::UserAgent::_need_proxy-1123 Not proxied
  465.     873 INFO LWP::Protocol::http::request-122 ()
  466.     1016 DEBUG LWP::UserAgent::request-443 Simple response: Found
  467.     1020 INFO LWP::UserAgent::request-436 ()
  468.     1022 INFO LWP::UserAgent::send_request-294 
  469.      GET http://www.amazon.com/exec/obidos/subst/home/home.html/
  470.     1023 DEBUG LWP::UserAgent::_need_proxy-1123 Not proxied
  471.     1024 INFO LWP::Protocol::http::request-122 ()
  472.     1382 DEBUG LWP::Protocol::collect-206 read 632 bytes
  473.     ...
  474.     2605 DEBUG LWP::Protocol::collect-206 read 77 bytes
  475.     2607 DEBUG LWP::UserAgent::request-443 Simple response: OK
  476.     Success: Received 42584
  477.  
  478. Of course, in this way, the embedded logging and debug statements within
  479. LWP can be utilized in any Log::Log4perl way you can think of. You can
  480. have them sent to different appenders, block them based on the
  481. category and everything else Log::Log4perl has to offer.
  482.  
  483. Only drawback of this method: Steering logging behaviour via category 
  484. is always based on the C<LWP::Debug> package. Although the logging
  485. statements reflect the package name of the issuing module properly, 
  486. the stealth loggers in C<LWP::Debug> are all of the category C<LWP::Debug>.
  487. This implies that you can't control the logging behaviour based on the
  488. package that's I<initiating> a log request (e.g. LWP::UserAgent) but only
  489. based on the package that's actually I<executing> the logging statement, 
  490. C<LWP::Debug> in this case.
  491.  
  492. To work around this conundrum, we need to write a wrapper function and
  493. plant it into the C<LWP::Debug> package. It will determine the caller and
  494. create a logger bound to a category with the same name as the caller's
  495. package:
  496.  
  497.     package LWP::Debug;
  498.  
  499.     use Log::Log4perl qw(:levels get_logger);
  500.  
  501.     sub l4p_wrapper {
  502.         my($prio, @message) = @_;
  503.         $Log::Log4perl::caller_depth += 2;
  504.         get_logger(caller(1))->log($prio, @message);
  505.         $Log::Log4perl::caller_depth -= 2;
  506.     }
  507.  
  508.     no warnings 'redefine';
  509.     *trace = sub { l4p_wrapper($INFO, @_); };
  510.     *debug = *conns = sub { l4p_wrapper($DEBUG, @_); };
  511.  
  512.     package main;
  513.     # ... go on with your main program ...
  514.  
  515. This is less performant than the previous approach, because every
  516. log request will request a reference to a logger first, then call
  517. the wrapper, which will in turn call the appropriate log function.
  518.  
  519. This hierarchy shift has to be compensated for by increasing
  520. C<$Log::Log4perl::caller_depth> by 2 before calling the log function
  521. and decreasing it by 2 right afterwards. Also, the C<l4p_wrapper>
  522. function shown above calls C<caller(1)> which determines the name
  523. of the package I<two> levels down the calling hierarchy (and 
  524. therefore compensates for both the wrapper function and the
  525. anonymous subroutine calling it).
  526.  
  527. C<no warnings 'redefine'> suppresses a warning Perl would generate
  528. otherwise
  529. upon redefining C<LWP::Debug>'s C<trace()>, C<debug()> and C<conns()>
  530. functions. In case you use a perl prior to 5.6.x, you need
  531. to manipulate C<$^W> instead.
  532.  
  533. =head2 What if I need dynamic values in a static Log4perl configuration file?
  534.  
  535. Say, your application uses Log::Log4perl for logging and 
  536. therefore comes with a Log4perl configuration file, specifying the logging
  537. behaviour.
  538. But, you also want it to take command line parameters to set values
  539. like the name of the log file.
  540. How can you have
  541. both a static Log4perl configuration file and a dynamic command line
  542. interface?
  543.  
  544. As of Log::Log4perl 0.28, every value in the configuration file
  545. can be specified as a I<Perl hook>. So, instead of saying
  546.  
  547.     log4perl.appender.Logfile.filename = test.log
  548.  
  549. you could just as well have a Perl subroutine deliver the value
  550. dynamically:
  551.  
  552.     log4perl.appender.Logfile.filename = sub { logfile(); };
  553.  
  554. given that C<logfile()> is a valid function in your C<main> package
  555. returning a string containing the path to the log file.
  556.  
  557. Or, think about using the value of an environment variable:
  558.  
  559.     log4perl.appender.DBI.user = sub { $ENV{USERNAME} };
  560.  
  561. When C<Log::Log4perl-E<gt>init()> parses the configuration
  562. file, it will notice the assignment above because of its
  563. C<sub {...}> pattern and treat it in a special way:
  564. It will evaluate the subroutine (which can contain
  565. arbitrary Perl code) and take its return value as the right side
  566. of the assignment.
  567.  
  568. A typical application would be called like this on the command line:
  569.  
  570.     app                # log file is "test.log"
  571.     app -l mylog.txt   # log file is "mylog.txt"
  572.  
  573. Here's some sample code implementing the command line interface above:
  574.  
  575.     use Log::Log4perl qw(get_logger);
  576.     use Getopt::Std;
  577.  
  578.     getopt('l:', \our %OPTS);
  579.  
  580.     my $conf = q(
  581.     log4perl.category.Bar.Twix         = WARN, Logfile
  582.     log4perl.appender.Logfile          = Log::Dispatch::File
  583.     log4perl.appender.Logfile.filename = sub { logfile(); };
  584.     log4perl.appender.Logfile.layout   = SimpleLayout
  585.     );
  586.  
  587.     Log::Log4perl::init(\$conf);
  588.  
  589.     my $logger = get_logger("Bar::Twix");
  590.     $logger->error("Blah");
  591.  
  592.     ###########################################
  593.     sub logfile {
  594.     ###########################################
  595.         if(exists $OPTS{l}) {
  596.             return $OPTS{l};
  597.         } else {
  598.             return "test.log";
  599.         }
  600.     }
  601.  
  602. Every Perl hook may contain arbitrary perl code,
  603. just make sure to fully qualify eventual variable names
  604. (e.g. C<%main::OPTS> instead of C<%OPTS>).
  605.  
  606. B<SECURITY NOTE>: this feature means arbitrary perl code
  607. can be embedded in the config file.  In the rare case
  608. where the people who have access to your config file
  609. are different from the people who write your code and
  610. shouldn't have execute rights, you might want to call
  611.  
  612.     $Log::Log4perl::Config->allow_code(0);
  613.  
  614. before you call init(). This will prevent Log::Log4perl from
  615. executing I<any> Perl code in the config file (including
  616. code for custom conversion specifiers 
  617. (see L<Log::Log4perl::Layout::PatternLayout/"Custom cspecs">).
  618.  
  619. =head2 How can I roll over my logfiles automatically at midnight?
  620.  
  621. Long-running applications tend to produce ever-increasing logfiles.
  622. For backup and cleanup purposes, however, it is often desirable to move
  623. the current logfile to a different location from time to time and
  624. start writing a new one.
  625.  
  626. This is a non-trivial task, because it has to happen in sync with 
  627. the logging system in order not to lose any messages in the process.
  628.  
  629. Luckily, I<Mark Pfeiffer>'s C<Log::Dispatch::FileRotate> appender
  630. works well with Log::Log4perl to rotate your logfiles in a variety of ways.
  631. All you have to do is specify it in your Log::Log4perl configuration file
  632. and your logfiles will be rotated automatically.
  633.  
  634. You can choose between rolling based on a maximum size ("roll if greater
  635. than 10 MB") or based on a date pattern ("roll everyday at midnight").
  636. In both cases, C<Log::Dispatch::FileRotate> allows you to define a 
  637. number C<max> of saved files to keep around until it starts overwriting
  638. the oldest ones. If you set the C<max> parameter to 2 and the name of
  639. your logfile is C<test.log>, C<Log::Dispatch::FileRotate> will
  640. move C<test.log> to C<test.log.1> on the first rollover. On the second
  641. rollover, it will move C<test.log.1> to C<test.log.2> and then C<test.log>
  642. to C<test.log.1>. On the third rollover, it will move C<test.log.1> to 
  643. C<test.log.2> (therefore discarding the old C<test.log.2>) and 
  644. C<test.log> to C<test.log.1>. And so forth. This way, there's always 
  645. going to be a maximum of 2 saved log files around.
  646.  
  647. Here's an example of a Log::Log4perl configuration file, defining a
  648. daily rollover at midnight (date pattern C<yyyy-MM-dd>), keeping
  649. a maximum of 5 saved logfiles around:
  650.  
  651.     log4perl.category         = WARN, Logfile
  652.     log4perl.appender.Logfile = Log::Dispatch::FileRotate
  653.     log4perl.appender.Logfile.filename    = test.log
  654.     log4perl.appender.Logfile.max         = 5
  655.     log4perl.appender.Logfile.DatePattern = yyyy-MM-dd
  656.     log4perl.appender.Logfile.TZ          = PST
  657.     log4perl.appender.Logfile.layout = \
  658.         Log::Log4perl::Layout::PatternLayout 
  659.     log4perl.appender.Logfile.layout.ConversionPattern = %d %m %n 
  660.  
  661. Please see the C<Log::Dispatch::FileRotate> documentation for details.
  662. C<Log::Dispatch::FileRotate> is available on CPAN.
  663.  
  664. =head2 What's the easiest way to turn off all logging, even with a lengthy Log4perl configuration file?
  665.  
  666. In addition to category-based levels and appender thresholds,
  667. Log::Log4perl supports system-wide logging thresholds. This is the 
  668. minimum level the system will require of any logging events in order for them 
  669. to make it through to any configured appenders.
  670.  
  671. For example, putting the line
  672.  
  673.     log4perl.threshold = ERROR
  674.  
  675. anywhere in your configuration file will limit any output to any appender
  676. to events with priority of ERROR or higher (ERROR or FATAL that is). 
  677.  
  678. However, in order to suppress all logging entirely, you need to use a
  679. priority that's higher than FATAL: It is simply called C<OFF>, and it is never
  680. used by any logger. By definition, it is higher than the highest 
  681. defined logger level.
  682.  
  683. Therefore, if you keep the line
  684.  
  685.     log4perl.threshold = OFF
  686.  
  687. somewhere in your Log::Log4perl configuration, the system will be quiet
  688. as a graveyard. If you deactivate the line (e.g. by commenting it out), 
  689. the system will, upon config reload, snap back to normal operation, providing 
  690. logging messages according to the rest of the configuration file again.
  691.  
  692. =head2 I keep getting duplicate log messages! What's wrong?
  693.  
  694. Having several settings for related categories in the Log4perl 
  695. configuration file sometimes leads to a phenomenon called 
  696. "message duplication". It can be very confusing at first,
  697. but if thought through properly, it turns out that Log4perl behaves
  698. as advertised. But, don't despair, of course there's a number of 
  699. ways to avoid message duplication in your logs.
  700.  
  701. Here's a sample Log4perl configuration file that produces the
  702. phenomenon:
  703.  
  704.     log4perl.logger.Cat        = ERROR, Screen
  705.     log4perl.logger.Cat.Subcat = WARN, Screen
  706.  
  707.     log4perl.appender.Screen   = Log::Dispatch::Screen
  708.     log4perl.appender.Screen.layout = SimpleLayout
  709.  
  710. It defines two loggers, one for category C<Cat> and one for
  711. C<Cat::Subcat>, which is obviously a subcategory of C<Cat>.
  712. The parent logger has a priority setting of ERROR, the child
  713. is set to the lower C<WARN> level.
  714.  
  715. Now imagine the following code in your program:
  716.  
  717.     my $logger = get_logger("Cat.Subcat");
  718.     $logger->warn("Warning!");
  719.  
  720. What do you think will happen? An unexperienced Log4perl user
  721. might think: "Well, the message is being sent with level WARN, so the 
  722. C<Cat::Subcat> logger will accept it and forward it to the 
  723. attached C<Screen> appender. Then, the message will percolate up 
  724. the logger hierarchy, find
  725. the C<Cat> logger, which will suppress the message because of its
  726. ERROR setting."
  727. But, perhaps surprisingly, what you'll get with the
  728. code snippet above is not one but two log messages written 
  729. to the screen:
  730.  
  731.     WARN - Warning!
  732.     WARN - Warning!
  733.  
  734. What happened? The culprit is that once the logger C<Cat::Subcat> 
  735. decides to fire, it will forward the message I<unconditionally> 
  736. to all directly or indirectly attached appenders. The C<Cat> logger 
  737. will never be asked if it wants the message or not -- the message 
  738. will just be pushed through to the appender attached to C<Cat>.
  739.  
  740. One way to prevent the message from bubbling up the logger
  741. hierarchy is to set the C<additivity> flag of the subordinate logger to
  742. C<0>:
  743.  
  744.     log4perl.logger.Cat            = ERROR, Screen
  745.     log4perl.logger.Cat.Subcat     = WARN, Screen
  746.     log4perl.additivity.Cat.Subcat = 0
  747.  
  748.     log4perl.appender.Screen   = Log::Dispatch::Screen
  749.     log4perl.appender.Screen.layout = SimpleLayout
  750.  
  751. The message will now be accepted by the C<Cat::Subcat> logger,
  752. forwarded to its appender, but then C<Cat::Subcat> will suppress
  753. any further action. While this setting avoids duplicate messages
  754. as seen before, it is often not the desired behaviour. Messages
  755. percolating up the hierarchy are a useful Log4perl feature.
  756.  
  757. If you're defining I<different> appenders for the two loggers,
  758. one other option is to define an appender threshold for the
  759. higher-level appender. Typically it is set to be 
  760. equal to the logger's level setting:
  761.  
  762.     log4perl.logger.Cat           = ERROR, Screen1
  763.     log4perl.logger.Cat.Subcat    = WARN, Screen2
  764.  
  765.     log4perl.appender.Screen1   = Log::Dispatch::Screen
  766.     log4perl.appender.Screen1.layout = SimpleLayout
  767.     log4perl.appender.Screen1.Threshold = ERROR
  768.  
  769.     log4perl.appender.Screen2   = Log::Dispatch::Screen
  770.     log4perl.appender.Screen2.layout = SimpleLayout
  771.  
  772. Since the C<Screen1> appender now blocks every message with
  773. a priority less than ERROR, even if the logger in charge
  774. lets it through, the message percolating up the hierarchy is
  775. being blocked at the last minute and I<not> appended to C<Screen1>.
  776.  
  777. So far, we've been operating well within the boundaries of the 
  778. Log4j standard, which Log4perl adheres to. However, if 
  779. you would really, really like to use a single appender 
  780. and keep the message percolation intact without having to deal
  781. with message duplication, there's a non-standard solution for you:
  782.  
  783.     log4perl.logger.Cat        = ERROR, Screen
  784.     log4perl.logger.Cat.Subcat = WARN, Screen
  785.  
  786.     log4perl.appender.Screen   = Log::Dispatch::Screen
  787.     log4perl.appender.Screen.layout = SimpleLayout
  788.  
  789.     log4perl.oneMessagePerAppender = 1
  790.  
  791. The C<oneMessagePerAppender> flag will suppress duplicate messages
  792. to the same appender. Again, that's non-standard. But way cool :).
  793.  
  794. =head2 How can I configure Log::Log4perl to send me email if something happens?
  795.  
  796. Some incidents require immediate action. You can't wait until someone
  797. checks the log files, you need to get notified on your pager right away.
  798.  
  799. The easiest way to do that is by using the C<Log::Dispatch::Email::MailSend>
  800. module as an appender. It comes with the C<Log::Dispatch> bundle and
  801. allows you to specify recipient and subject of outgoing emails in the Log4perl
  802. configuration file:
  803.  
  804.     log4perl.category = FATAL, Mailer
  805.     log4perl.appender.Mailer         = Log::Dispatch::Email::MailSend
  806.     log4perl.appender.Mailer.to      = drone@pageme.net
  807.     log4perl.appender.Mailer.subject = Something's broken!
  808.     log4perl.appender.Mailer.layout  = SimpleLayout
  809.  
  810. The message of every log incident this appender gets
  811. will then be forwarded to the given
  812. email address. Check the C<Log::Dispatch::Email::MailSend> documentation
  813. for details. And please make sure there's not a flood of email messages 
  814. sent out by your application, filling up the receipient's inbox.
  815.  
  816. =head2 How can I write my own appender?
  817.  
  818. First off, there's a lot of Log4perl-compatible appenders already
  819. available on CPAN: Just run a search for C<Log::Dispatch> on 
  820. http://search.cpan.org and chances are that what you're looking for 
  821. has already been developed, debugged and been used successfully 
  822. in production -- no need for you to reinvent the wheel.
  823.  
  824. Also, Log::Log4perl ships with a nifty database appender named
  825. Log::Log4perl::Appender::DBI -- check it out if talking to databases is your
  826. desire.
  827.  
  828. But if you're up for a truly exotic task, you might have to write
  829. an appender yourself. That's very easy -- it takes no longer
  830. than a couple of minutes for the basic framework.
  831.  
  832. Say, we wanted to create an appender of the class
  833. C<Log::Dispatch::ColorScreen>, which logs messages
  834. to the screen in a configurable color. Just create a new class 
  835. in C<Log/Dispatch/ColorScreen.pm> and let it inherit from the base 
  836. class C<Log::Dispatch::Output>:
  837.  
  838.     package Log::Dispatch::ColorScreen;
  839.  
  840.     use Log::Dispatch::Output;
  841.     use base qw( Log::Dispatch::Output );
  842.  
  843. Now let's assume that your Log::Log4perl
  844. configuration file C<test.conf> looks like this:
  845.  
  846.     log4perl.logger = INFO, ColorApp
  847.  
  848.     log4perl.appender.ColorApp=Log::Dispatch::ColorScreen
  849.     log4perl.appender.ColorApp.color=blue
  850.  
  851.     log4perl.appender.ColorApp.layout = PatternLayout
  852.     log4perl.appender.ColorApp.layout.ConversionPattern=%d %m %n
  853.  
  854. This will cause Log::Log4perl on C<init()> to look for a class
  855. Log::Dispatch::ColorScreen and call its constructor new(). Let's add
  856. new() to Log/Dispatch/ColorScreen.pm:
  857.  
  858.     sub new {
  859.         my($class, %options) = @_;
  860.     
  861.         my $self = { %options };
  862.         bless $self, $class;
  863.     
  864.         $self->_basic_init( %options );
  865.     
  866.         return $self;
  867.     }
  868.  
  869. To initialize this appender, Log::Log4perl will call 
  870. and pass all attributes of the appender as defined in the configuration
  871. file to the constructor as name/value pairs (in this case just one):
  872.  
  873.     Log::Dispatch::ColorScreen->new(color => "blue");
  874.  
  875. The new() method listed above stores the contents of the
  876. %options hash in the object's
  877. instance data hash (referred to by $self)
  878. and calls C<_basic_init> with all name/value
  879. pairs to initialize the appender in the Log::Dispatch world.
  880. That's all for initializing a new appender with Log::Log4perl.
  881.  
  882. Second, Log::Dispatch::ColorScreen needs to expose a 
  883. C<log_message()> method, which will be called by Log::Log4perl 
  884. every time it thinks the appender should fire. Along with the
  885. object reference (as usual in Perl's object world), log_message()
  886. will receive a list of name/value pairs, of which only the one
  887. under the key C<message> shall be of interest for now since it is the
  888. message string to be logged. At this point, Log::Log4perl has already taken
  889. care of joining the message to be a single string.
  890.  
  891. For our special appender Log::Dispatch::ColorScreen, 
  892. we're using the Term::ANSIColor module
  893. to colorize the output:
  894.  
  895.     use Term::ANSIColor;
  896.  
  897.     sub log_message {
  898.         my($self, %params) = @_;
  899.     
  900.         print colored($params{message},
  901.                       $self->{color});
  902.     }
  903.  
  904. The color (as configured in the Log::Log4perl configuration file) 
  905. is available as $self-E<gt>{color} in the appender object. Don't
  906. forget to return
  907.  
  908.     1;
  909.  
  910. at the end of ColorScreen.pm and you're done. Install the new appender
  911. somewhere where perl can find it (like Log/Dispatch/ColorScreen.pm)
  912. and try it with a test script like 
  913.  
  914.     use Log::Log4perl qw(:easy);
  915.     Log::Log4perl->init("test.conf");
  916.     ERROR("blah");
  917.  
  918. to see the new colored output. Is this cool or what?
  919.  
  920. =head2 How can I drill down on references before logging them?
  921.  
  922. If you've got a reference to a nested structure or object, then 
  923. you probably don't want to log it as C<HASH(0x81141d4)> but rather
  924. dump it as something like
  925.  
  926.     $VAR1 = {
  927.               'a' => 'b',
  928.               'd' => 'e'
  929.             };
  930.  
  931. via a module like Data::Dumper. While it's syntactically correct to say
  932.  
  933.     $logger->debug(Data::Dumper::Dumper($ref));
  934.  
  935. this call imposes a huge performance penalty on your application
  936. if the message is suppressed by Log::Log4perl, because Data::Dumper
  937. will perform its expensive operations in any case, because it doesn't
  938. know that its output will be thrown away immediately.
  939.  
  940. As of Log::Log4perl 0.28, there's a better way: Use the 
  941. message output filter format as in
  942.  
  943.     $logger->debug( {filter => \&Data::Dumper::Dumper,
  944.                      value  => $ref} );
  945.  
  946. and Log::Log4perl won't call the filter function unless the message really
  947. gets written out to an appender. Just make sure to pass the whole slew as a
  948. reference to a hash specifying a filter function (as a sub reference)
  949. under the key C<filter> and the value to be passed to the filter function in
  950. C<value>). 
  951. When it comes to logging, Log::Log4perl will call the filter function,
  952. pass the C<value> as an argument and log the return value.
  953. Saves you serious cycles.
  954.  
  955. =head2 How can I collect all FATAL messages in an extra log file?
  956.  
  957. Suppose you have employed Log4perl all over your system and you've already
  958. activated logging in various subsystems. On top of that, without disrupting
  959. any other settings, how can you collect all FATAL messages all over the system
  960. and send them to a separate log file? 
  961.  
  962. If you define a root logger like this:
  963.  
  964.     log4perl.logger                  = FATAL, File
  965.     log4perl.appender.File           = Log::Dispatch::File
  966.     log4perl.appender.File.filename  = /tmp/fatal.txt
  967.     log4perl.appender.File.layout    = PatternLayout
  968.     log4perl.appender.File.layout.ConversionPattern= %d %m %n
  969.         # !!! Something's missing ...
  970.  
  971. you'll be surprised to not only receive all FATAL messages
  972. issued anywhere in the system,
  973. but also everything else -- gazillions of 
  974. ERROR, WARN, INFO and even DEBUG messages will end up in
  975. your fatal.txt logfile!
  976. Reason for this is Log4perl's (or better: Log4j's) appender additivity. 
  977. Once a 
  978. lower-level logger decides to fire, the message is going to be forwarded
  979. to all appenders upstream -- without further priority checks with their
  980. attached loggers.
  981.  
  982. There's a way to prevent this, however: If your appender defines a
  983. minimum threshold, only messages of this priority or higher are going
  984. to be logged. So, just add
  985.  
  986.     log4perl.appender.File.Threshold = FATAL 
  987.  
  988. to the configuration above, and you'll get what you wanted in the 
  989. first place: An overall system FATAL message collector.
  990.  
  991. =head2 How can I bundle several log messages into one?
  992.  
  993. Would you like to tally the messages arriving at your appender and
  994. dump out a summary once they're exceeding a certain threshold?
  995. So that something like
  996.  
  997.     $logger->error("Blah");
  998.     $logger->error("Blah");
  999.     $logger->error("Blah");
  1000.  
  1001. won't be logged as 
  1002.  
  1003.     Blah
  1004.     Blah
  1005.     Blah
  1006.  
  1007. but as
  1008.  
  1009.     [3] Blah
  1010.  
  1011. instead? If you'd like to hold off on logging a message until it has been
  1012. sent a couple of times, you can roll that out by creating a buffered 
  1013. appender.
  1014.  
  1015. Let's define a new appender like
  1016.  
  1017.     package Log::Dispatch::Tally;
  1018.     use Log::Dispatch::Output;
  1019.     use base qw( Log::Dispatch::Output );
  1020.  
  1021.     sub new {
  1022.         my($class, %options) = @_;
  1023.     
  1024.         my $self = { maxcount => 5,
  1025.                      %options
  1026.                    };
  1027.     
  1028.         bless $self, $class;
  1029.     
  1030.         $self->_basic_init( %options );
  1031.     
  1032.         $self->{last_message}        = "";
  1033.         $self->{last_message_count}  = 0;
  1034.     
  1035.         return $self;
  1036.     }
  1037.  
  1038. with two additional instance variables C<last_message> and 
  1039. C<last_message_count>, storing the content of the last message sent
  1040. and a counter of how many times this has happened. Also, it features
  1041. a configuration parameter C<maxcount> which defaults to 5 in the
  1042. snippet above but can be set in the Log4perl configuration file like this:
  1043.  
  1044.     log4perl.logger = INFO, A
  1045.     log4perl.appender.A=Log::Dispatch::Tally
  1046.     log4perl.appender.A.maxcount = 3
  1047.  
  1048. The main tallying logic lies in the appender's C<log_message> method,
  1049. which is called every time Log4perl thinks a message needs to get logged
  1050. by our appender:
  1051.  
  1052.     sub log_message {
  1053.         my($self, %params) = @_;
  1054.  
  1055.             # Message changed? Print buffer.
  1056.         if($self->{last_message} and
  1057.            $params{message} ne $self->{last_message}) {
  1058.             print "[$self->{last_message_count}]: " .
  1059.                   "$self->{last_message}";
  1060.             $self->{last_message_count} = 1;
  1061.             $self->{last_message} = $params{message};
  1062.             return;
  1063.         }
  1064.  
  1065.         $self->{last_message_count}++;
  1066.         $self->{last_message} = $params{message};
  1067.  
  1068.             # Threshold exceeded? Print, reset counter
  1069.         if($self->{last_message_count} >= 
  1070.            $self->{maxcount}) {
  1071.             print "[$self->{last_message_count}]: " .
  1072.                   "$params{message}";
  1073.             $self->{last_message_count} = 0;
  1074.             $self->{last_message}       = "";
  1075.             return;
  1076.         }
  1077.     }
  1078.  
  1079. We basically just check if the oncoming message in C<$param{message}>
  1080. is equal to what we've saved before in the C<last_message> instance
  1081. variable. If so, we're increasing C<last_message_count>.
  1082. We print the message in two cases: If the new message is different
  1083. than the buffered one, because then we need to dump the old stuff
  1084. and store the new. Or, if the counter exceeds the threshold, as
  1085. defined by the C<maxcount> configuration parameter.
  1086.  
  1087. Please note that the appender always gets the fully rendered message and
  1088. just compares it as a whole -- so if there's a date/timestamp in there,
  1089. that might confuse your logic. You can work around this by specifying
  1090. %m %n as a layout and add the date later on in the appender. Or, make
  1091. the comparison smart enough to omit the date.
  1092.  
  1093. At last, don't forget what happens if the program is being shut down.
  1094. If there's still messages in the buffer, they should be printed out
  1095. at that point. That's easy to do in the appender's DESTROY method,
  1096. which gets called at object destruction time:
  1097.  
  1098.     sub DESTROY {
  1099.         my($self) = @_;
  1100.  
  1101.         if($self->{last_message_count}) {
  1102.             print "[$self->{last_message_count}]: " .
  1103.                   "$self->{last_message}";
  1104.             return;
  1105.         }
  1106.     }
  1107.  
  1108. This will ensure that none of the buffered messages are lost. 
  1109. Happy buffering!
  1110.  
  1111. =head2 I want to log ERROR and WARN messages to different files! How can I do that?
  1112.  
  1113. Let's assume you wanted to have each logging statement written to a
  1114. different file, based on the statement's priority. Messages with priority
  1115. C<WARN> are supposed to go to C</tmp/app.warn>, events prioritized
  1116. as C<ERROR> should end up in C</tmp/app.error>.
  1117.  
  1118. Now, if you define two appenders C<AppWarn> and C<AppError>
  1119. and assign them both to the root logger,
  1120. messages bubbling up from any loggers below will be logged by both
  1121. appenders because of Log4perl's message propagation feature. If you limit
  1122. their exposure via the appender threshold mechanism and set 
  1123. C<AppWarn>'s threshold to C<WARN> and C<AppError>'s to C<ERROR>, you'll
  1124. still get C<ERROR> messages in C<AppWarn>, because C<AppWarn>'s C<WARN>
  1125. setting will just filter out messages with a I<lower> priority than
  1126. C<WARN> -- C<ERROR> is higher and will be allowed to pass through.
  1127.  
  1128. What we need for this is a Log4perl I<Custom Filter>, available with 
  1129. Log::Log4perl 0.30.
  1130.  
  1131. Both appenders need to verify that
  1132. the priority of the oncoming messages exactly I<matches> the priority 
  1133. the appender is supposed to log messages of. To accomplish this task,
  1134. let's define two custom filters, C<MatchError> and C<MatchWarn>, which,
  1135. when attached to their appenders, will limit messages passed on to them
  1136. to those matching a given priority: 
  1137.  
  1138.     log4perl.logger = WARN, AppWarn, AppError
  1139.  
  1140.         # Filter to match level ERROR
  1141.     log4perl.filter.MatchError = Log::Log4perl::Filter::LevelMatch
  1142.     log4perl.filter.MatchError.LevelToMatch  = ERROR
  1143.     log4perl.filter.MatchError.AcceptOnMatch = true
  1144.  
  1145.         # Filter to match level WARN
  1146.     log4perl.filter.MatchWarn  = Log::Log4perl::Filter::LevelMatch
  1147.     log4perl.filter.MatchWarn.LevelToMatch  = WARN
  1148.     log4perl.filter.MatchWarn.AcceptOnMatch = true
  1149.  
  1150.         # Error appender
  1151.     log4perl.appender.AppError = Log::Dispatch::File
  1152.     log4perl.appender.AppError.filename = /tmp/app.err
  1153.     log4perl.appender.AppError.layout   = SimpleLayout
  1154.     log4perl.appender.AppError.Filter   = MatchError
  1155.  
  1156.         # Warning appender
  1157.     log4perl.appender.AppWarn = Log::Dispatch::File
  1158.     log4perl.appender.AppWarn.filename = /tmp/app.warn
  1159.     log4perl.appender.AppWarn.layout   = SimpleLayout
  1160.     log4perl.appender.AppWarn.Filter   = MatchWarn
  1161.  
  1162. The appenders C<AppWarn> and C<AppError> defined above are logging to C</tmp/app.warn> and
  1163. C</tmp/app.err> respectively and have the custom filters C<MatchWarn> and C<MatchError>
  1164. attached.
  1165. This setup will direct all WARN messages, issued anywhere in the system, to /tmp/app.warn (and 
  1166. ERROR messages to /tmp/app.error) -- without any overlaps.
  1167.  
  1168. =head2 On our server farm, Log::Log4perl configuration files differ slightly from host to host. Can I roll them all into one?
  1169.  
  1170. You sure can, because Log::Log4perl allows you to specify attribute values 
  1171. dynamically. Let's say that one of your appenders expects the host's IP address
  1172. as one of its attributes. Now, you could certainly roll out different 
  1173. configuration files for every host and specify the value like
  1174.  
  1175.     log4perl.appender.MyAppender    = Log::Dispatch::SomeAppender
  1176.     log4perl.appender.MyAppender.ip = 10.0.0.127
  1177.  
  1178. but that's a maintenance nightmare. Instead, you can have Log::Log4perl 
  1179. figure out the IP address at configuration time and set the appender's
  1180. value correctly:
  1181.  
  1182.         # Set the IP address dynamically
  1183.     log4perl.appender.MyAppender    = Log::Dispatch::SomeAppender
  1184.     log4perl.appender.MyAppender.ip = sub { \
  1185.        use Sys::Hostname; \
  1186.        use Socket; \
  1187.        return inet_ntoa(scalar gethostbyname hostname); \
  1188.     }
  1189.  
  1190. If Log::Log4perl detects that an attribute value starts with something like
  1191. C<"sub {...">, it will interpret it as a perl subroutine which is to be executed
  1192. once at configuration time (not runtime!) and its return value is
  1193. to be used as the attribute value. This comes in handy
  1194. for rolling out applications whichs Log::Log4perl configuration files
  1195. show small host-specific differences, because you can deploy the unmodified
  1196. application distribution on all instances of the server farm.
  1197.  
  1198. =head2 Log4perl doesn't interpret my backslashes correctly!
  1199.  
  1200. If you're using Log4perl's feature to specify the configuration as a
  1201. string in your program (as opposed to a separate configuration file),
  1202. chances are that you've written it like this:
  1203.  
  1204.     # *** WRONG! ***
  1205.  
  1206.     Log::Log4perl->init( \ <<END_HERE);
  1207.         log4perl.logger = WARN, A1
  1208.         log4perl.appender.A1 = Log::Dispatch::Screen
  1209.         log4perl.appender.A1.layout = \
  1210.             Log::Log4perl::Layout::PatternLayout
  1211.         log4perl.appender.A1.layout.ConversionPattern = %m%n
  1212.     END_HERE
  1213.  
  1214.     # *** WRONG! ***
  1215.  
  1216. and you're getting the following error message:
  1217.  
  1218.     Layout not specified for appender A1 at .../Config.pm line 342.
  1219.  
  1220. What's wrong? The problem is that you're using a here-document with
  1221. substitution enabled (C<E<lt>E<lt>END_HERE>) and that Perl won't 
  1222. interpret backslashes at line-ends as continuation characters but 
  1223. will essentially throw them out. So, in the code above, the layout line
  1224. will look like
  1225.  
  1226.     log4perl.appender.A1.layout =
  1227.  
  1228. to Log::Log4perl which causes it to report an error. To interpret the backslash
  1229. at the end of the line correctly as a line-continuation character, use
  1230. the non-interpreting mode of the here-document like in 
  1231.  
  1232.     # *** RIGHT! ***
  1233.  
  1234.     Log::Log4perl->init( \ <<'END_HERE');
  1235.         log4perl.logger = WARN, A1
  1236.         log4perl.appender.A1 = Log::Dispatch::Screen
  1237.         log4perl.appender.A1.layout = \
  1238.             Log::Log4perl::Layout::PatternLayout
  1239.         log4perl.appender.A1.layout.ConversionPattern = %m%n
  1240.     END_HERE
  1241.  
  1242.     # *** RIGHT! ***
  1243.  
  1244. (note the single quotes around C<'END_HERE'>) or use C<q{...}> 
  1245. instead of a here-document and Perl will treat the backslashes at 
  1246. line-end as intended.
  1247.  
  1248. =head2 I want to suppress certain messages based on their content!
  1249.  
  1250. Let's assume you've plastered all your functions with Log4perl 
  1251. statements like
  1252.  
  1253.     sub some_func {
  1254.  
  1255.         INFO("Begin of function");
  1256.  
  1257.         # ... Stuff happens here ...
  1258.  
  1259.         INFO("End of function");
  1260.     }
  1261.  
  1262. to issue two log messages, one at the beginning and one at the end of
  1263. each function. Now you want to suppress the message at the beginning
  1264. and only keep the one at the end, what can you do? You can't use the category
  1265. mechanism, because both messages are issued from the same package.
  1266.  
  1267. Log::Log4perl's custom filters (0.30 or better) provide an interface for the 
  1268. Log4perl user to step in right before a message gets logged and decide if 
  1269. it should be written out or suppressed, based on the message content or other
  1270. parameters:
  1271.  
  1272.     use Log::Log4perl qw(:easy);
  1273.     
  1274.     Log::Log4perl::init( \ <<'EOT' );
  1275.         log4perl.logger             = INFO, A1
  1276.         log4perl.appender.A1        = Log::Dispatch::Screen
  1277.         log4perl.appender.A1.layout = \
  1278.             Log::Log4perl::Layout::PatternLayout
  1279.         log4perl.appender.A1.layout.ConversionPattern = %m%n
  1280.     
  1281.         log4perl.filter.M1 = Log::Log4perl::Filter::StringMatch
  1282.         log4perl.filter.M1.StringToMatch = Begin
  1283.         log4perl.filter.M1.AcceptOnMatch = false
  1284.     
  1285.         log4perl.appender.A1.Filter = M1
  1286. EOT
  1287.  
  1288. The last four statements in the configuration above are defining a custom 
  1289. filter C<M1> of type C<Log::Log4perl::Filter::StringMatch>, which comes with 
  1290. Log4perl right out of the box and allows you to define a text pattern to match
  1291. (as a perl regular expression) and a flag C<AcceptOnMatch> indicating
  1292. if a match is supposed to suppress the message or let it pass through.
  1293.  
  1294. The last line then assigns this filter to the C<A1> appender, which will
  1295. call it every time it receives a message to be logged and throw all
  1296. messages out I<not> matching the regular expression C<Begin>.
  1297.  
  1298. Instead of using the standard C<Log::Log4perl::Filter::StringMatch> filter,
  1299. you can define your own, simply using a perl subroutine:
  1300.  
  1301.     log4perl.filter.ExcludeBegin  = sub { !/Begin/ }
  1302.     log4perl.appender.A1.Filter   = ExcludeBegin
  1303.  
  1304. For details on custom filters, check L<Log::Log4perl::Filter>.
  1305.  
  1306. =head2 My new module uses Log4perl -- but what happens if the calling program didn't configure it?
  1307.  
  1308. If a Perl module uses Log::Log4perl, it will typically rely on the
  1309. calling program to initialize it. If it is using Log::Log4perl in C<:easy>
  1310. mode, like in 
  1311.  
  1312.     package MyMod;
  1313.     use Log::Log4perl qw(:easy);
  1314.  
  1315.     sub foo {
  1316.         DEBUG("In foo");
  1317.     }
  1318.     
  1319.     1;
  1320.  
  1321. and the calling program doesn't initialize Log::Log4perl at all (e.g. because
  1322. it has no clue that it's available), Log::Log4perl will silently
  1323. ignore all logging messages. However, if the module is using Log::Log4perl 
  1324. in regular mode like in
  1325.  
  1326.     package MyMod;
  1327.     use Log::Log4perl qw(get_logger);
  1328.  
  1329.     sub foo {
  1330.         my $logger = get_logger("");
  1331.         $logger->debug("blah");
  1332.     }
  1333.  
  1334.     1;
  1335.  
  1336. and the main program is just using the module like in
  1337.  
  1338.     use MyMode;
  1339.     MyMode::foo();
  1340.  
  1341. then Log::Log4perl will also ignore all logging messages but
  1342. issue a warning like
  1343.  
  1344.     Log4perl: Seems like no initialization happened. 
  1345.     Forgot to call init()?
  1346.  
  1347. (only once!) to remind novice users to not forget to initialize 
  1348. the logging system before using it. 
  1349. However, if you want to suppress this message, just
  1350. add the C<:nowarn> target to the module's C<use Log::Log4perl> call:
  1351.  
  1352.     use Log::Log4perl qw(get_logger :nowarn);
  1353.  
  1354. This will have Log::Log4perl silently ignore all logging statements if
  1355. no initialization has taken place. 
  1356.  
  1357. If the module wants to figure out if some other program part has 
  1358. already initialized Log::Log4perl, it can do so by calling
  1359.  
  1360.     Log::Log4perl::initialized()
  1361.  
  1362. which will return a true value in case Log::Log4perl has been initialized 
  1363. and a false value if not.
  1364.  
  1365. =cut
  1366.  
  1367. =head1 SEE ALSO
  1368.  
  1369. Log::Log4perl
  1370.  
  1371. =head1 AUTHOR
  1372.  
  1373. Mike Schilli, E<lt>log4perl@perlmeister.comE<gt>
  1374.  
  1375. =cut
  1376.