water has asked for the wisdom of the Perl Monks concerning the following question:

Having trouble with a config file for Log::Log4Perl. Here's what I am trying to accomplish: Here's what I have so far. (It doesn't work -- only the error log is created.)
log4perl.logger = DEBUG, FD, S log4perl.logger = INFO, FI log4perl.logger = ERROR, FE log4perl.appender.S = Log::Log4perl::Appender::Screen log4perl.appender.S.stderr = 0 log4perl.appender.S.layout = Log::Log4perl::Layout::SimpleLayout log4perl.appender.FD=Log::Log4perl::Appender::File log4perl.appender.FD.filename=/home/perl_logs/debug.log log4perl.appender.FD.mode=append log4perl.appender.FD.layout = Log::Log4perl::Layout::PatternLayout log4perl.appender.FD.layout.ConversionPattern = %d %p: %m %F{1}(%L) +%n log4perl.appender.FI=Log::Log4perl::Appender::File log4perl.appender.FI.filename= log4perl.appender.File.filename = \ sub {my $p = $0; $p =~ s{(\w+)\.\w+$}{/home/perl_logs/$1.txt}; ret +urn $p;} log4perl.appender.FI.mode=append log4perl.appender.FI.layout = Log::Log4perl::Layout::PatternLayout log4perl.appender.FW.layout.ConversionPattern = %d %p -- %m %n log4perl.appender.FE=Log::Log4perl::Appender::File log4perl.appender.FE.filename=/home/perl_logs/fatal.log log4perl.appender.FE.mode=append log4perl.appender.FE.layout = Log::Log4perl::Layout::PatternLayout log4perl.appender.FE.layout.ConversionPattern = %d %p: %m %F{1}(%L) +%n
I put a simple wrapper around Log::Log4Perl like this
package MyLog; use strict; use warnings FATAL => qw( all ); use Carp::Assert; use Data::Dumper; use base qw(Exporter); use vars qw(@EXPORT); @EXPORT = qw(get_logger $INFO $DEBUG $WARN $ERROR $FATAL); use Log::Log4perl qw(:levels); BEGIN { Log::Log4perl->init('/home/foo/log4perl-conf.txt'); } sub get_logger { Log::Log4perl::get_logger(@_); } 1;
Thanks for any suggestions...

water

You could not step twice into the same river; for other waters are ever flowing on to you. -- Heraclitus

Replies are listed 'Best First'.
Re: help with Log::Log4perl config file
by holo (Monk) on May 30, 2004 at 08:47 UTC

    These are your instructions to Log4perl:

    log4perl.logger = DEBUG, FD, S

    Attach debug log level to debug.log and STDOUT.
    Set log level to debug.

    log4perl.logger = INFO,  FI

    Attach info log level to $0-log.txt.
    Set log level to info (no longer debug)

    log4perl.logger = ERROR, FE

    Attach error log level to fatal.log
    Set log level to error (debug and info are ignored)

    You can select the log level and different behaviours for different log levels. You are setting up three different behaviours and selecting the ERROR log level -- DEBUG and INFO are not being used. Try changing the order of the frist three lines and see what happens -- the last one should always apply.

    Some other points:

    log4perl.appender.FI.filename= log4perl.appender.File.filename = \ sub {my $p = $0; $p =~ s{(\w+)\.\w+$}{/home/perl_logs/$1.txt}; ret +urn $p;}

    Should probably be:

    log4perl.appender.FI.filename= \ sub {my $p = $0; $p =~ s{(\w+)\.\w+$}{/home/perl_logs/$1.txt}; ret +urn $p;}

    and a typo at the line that says:

    log4perl.appender.FW.layout.ConversionPattern = %d %p --  %m %n

    should probably read:

    log4perl.appender.FI.layout.ConversionPattern = %d %p -- %m %n ^^

    Hope that helps

      Thanks for catching the cut-n-paste typos. Yes, I see the last root logger setup prevails. However, I still don't see from reading the docs how to have a suite of programs sharing a common debug log, having their own info log, and sharing a common error log. And sure, logs can and should grab messages from higher levels -- eg debug log can and should log infos, warns, errors, fatals, etc.

      Why are we trying to do this? When debugging, we set  $logger->level($DEBUG); in a script, or in a module, or both, as needed. This produces lots of output. Once things are working, we raise the level to $INFO. We log major program events at the info level ("Now initializing...", "Now working...", "Now complete."). We log fatal errors, and program startups, in the error log. (Think the apache log, which captures major events like errors and restarts). To see if all is well, scan the error log. To get details on a script, scan the script-specific info log. To debug, turn on the debugging level and stare and the debug log. (The debug log is common because the bug tracking might cross several modules.)

      So, trying to do this and not understanding the docs:

      how may a suite of programs and mods share a common debug log, each program have their own info log, and all share a common error log?

      Thanks

        The docs are there to help you. The way I see it, it does not seem possible to accomplish what you need without using different classes. You could create three different bogus classes to cater for debug, info and error.

        Take a look at the examples in Log::Log4perl::Config.

        I think you need this:

        log4perl.logger.Proj.Module1.d = DEBUG, A1 log4perl.logger.Proj.Module1.i = INFO, A2 log4perl.logger.Proj.Module1.e = ERROR, A3 # and define A1, A2, A3, etc...

        Then in your code,

        package Proj.Module1; # ... my $dlogger = get_logger(__PACKAGE__ . ".d"); my $dlogger = get_logger(__PACKAGE__ . ".d"); my $elogger = get_logger(__PACKAGE__ . ".e");

        This is the best method I can think of but, of course, I stand to be corrected.

Re: help with Log::Log4perl config file
by saintmike (Vicar) on May 30, 2004 at 23:16 UTC
    As mentioned in the FAQ, the best way to handle this is using Log4perl's custom filters. Here's a configuration that should fit your needs:
    log4perl.logger = DEBUG, AppScreen, AppDebug, AppProcSpec, AppError log4perl.filter.DebugAndUp = Log::Log4perl::Filter::LevelRange log4perl.filter.DebugAndUp.LevelMin = DEBUG log4perl.filter.DebugAndUp.LevelMax = FATAL log4perl.filter.InfoAndUp = Log::Log4perl::Filter::LevelRange log4perl.filter.InfoAndUp.LevelMin = INFO log4perl.filter.InfoAndUp.LevelMax = FATAL log4perl.filter.ErrorAndUp = Log::Log4perl::Filter::LevelRange log4perl.filter.ErrorAndUp.LevelMin = ERROR log4perl.filter.ErrorAndUp.LevelMax = FATAL log4perl.appender.AppScreen = Log::Log4perl::Appender::Screen log4perl.appender.AppScreen.Filter = DebugAndUp log4perl.appender.AppScreen.layout = SimpleLayout log4perl.appender.AppDebug = Log::Log4perl::Appender::File log4perl.appender.AppDebug.filename = debug.log log4perl.appender.AppDebug.layout = SimpleLayout log4perl.appender.AppProcSpec = Log::Log4perl::Appender::File log4perl.appender.AppProcSpec.filename = sub { $0 . "-info.log" } log4perl.appender.AppProcSpec.layout = SimpleLayout log4perl.appender.AppProcSpec.Filter = InfoAndUp log4perl.appender.AppError = Log::Log4perl::Appender::File log4perl.appender.AppError.filename = error.log log4perl.appender.AppError.layout = SimpleLayout log4perl.appender.AppError.Filter = ErrorAndUp