Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Log::Log4Perl best practices

by water (Deacon)
on May 31, 2004 at 22:06 UTC ( [id://357854]=perlquestion: print w/replies, xml ) Need Help??

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

At work we're examining Log::Log4perl as a logging system (as my previous post indicates). As I evaluate the module, I get the sense I'm not using it well, as I feel it wants to spread like kudzu through our entire project. I want to put a wrapper around it, but am not sure how to do that, as it is a singleton.
Here's why it seems like kudzu. Each script is starting out with something like this
use Log::Log4perl qw(:levels); Log::Log4perl::init('/home/code/log4perl-conf.txt'); my $logger = Log::Log4perl->get_logger($0); $SIG{__DIE__} = sub {$Log::Log4perl::caller_depth++; $logger->fatal('f +atal: ', @_); die @_;};
then each module needs to start out with
use Log::Log4perl qw(:levels); my $logger = Log::Log4perl->get_logger(__PACKAGE__); $logger->level($DEBUG);
Should there be this much overhead? When I see all this repeated code, I don't like it. This adds 4 lines to each program (not a big deal) but it also adds 4 lines to each .t script (?!?!) and 2 lines to module...
surely it shouldn't require this much repeated code?

Thanks for any ideas

water

Replies are listed 'Best First'.
Re: Log::Log4Perl best practices
by Joost (Canon) on May 31, 2004 at 22:14 UTC
    then each module needs to start out with

    use Log::Log4perl qw(:levels); my $logger = Log::Log4perl->get_logger(__PACKAGE__); $logger->level($DEBUG);
    Well, it's still one line less than log4j :-)

    I'm not sure you're supposed to set your own log-level inside the code since one of the strong points of Log4perl is that you can change log-levels using the config files while the program is running...

    Anyway, you could make your own wrapper module and mess around with import and caller to let it be used like this:

    use Mylog; #... $LOG->warn("bla"); # $LOG is presumably a package global
    or even
    use MyLog 'debug'; $LOG->warn("stuff");

    Joost.

Re: Log::Log4Perl best practices
by saintmike (Vicar) on Jun 01, 2004 at 00:22 UTC
    Should there be this much overhead? When I see all this repeated code, I don't like it. This adds 4 lines to each program (not a big deal) but it also adds 4 lines to each .t script (?!?!) and 2 lines to module...surely it shouldn't require this much repeated code?
    Log::Log4perl can be used in different ways, just pick the one that suits you:

    For simple scripts, people like using :easy mode. This approach is also discussed in this FAQ and uses

    • a simplified init method without a configuration file and
    • logging functions instead of objects/method calls
    Here's an example:
    use Log::Log4perl qw(:easy); Log::Log4perl->easy_init( { level => $DEBUG, file => ">>test.log" } ); DEBUG("Debug this!");
    Calling DEBUG() instead of obtaining a logger reference via get_logger($category) and then calling $logger->debug() is what Log4perl calls using stealth loggers. Stealth loggers are also recommended to be used in modules, just say
    package MyPackage; use Log::Log4perl qw(:easy); sub method { DEBUG "Doing something!"; }
    and you've got full-fledged logging in place. Stealth loggers use Log4perl categories equal to the current package. Performance stays the same.

    The main program is responsible for calling init() or easy_init(). If it doesn't, Log::Log4perl will keep sleeping.

    As for spreading like Kudzu through your application, that's a common issue with logging systems. Log::Log4perl reduces the exposure by not requiring to pass a handler around, but provides a singleton mechanism.

    However, ideally, logging would be completely orthogonal to your application logic. You may have heard of aspect oriented programming (AOP), that's how it's done. Log4perl might provide a way to do that in the future.

      If the modules use stealth logging,
      package MyPackage; use Log::Log4perl qw(:easy); sub method { DEBUG "Doing something!"; }
      How does the main driver turn debugging on an off?
      use Log::Log4perl qw(:levels); Log::Log4perl->init("/home/mycode/log4perl-conf.txt"); my $logger = Log::Log4perl->get_logger; $logger->level($DEBUG);
      is not "seen" by the module.

      Or am I just not getting it by trying to set levels in my code, rather than in the conf file? I don't envision using the 'change logging level while code is running' feature, and it seems more direct to me to set the log level in the code, rather than in the conf file. I'm really just using the conf file for appender & filter specification, it seems.

      Thanks for any clarification. Mike, your advice has been great, thanks.

Re: Log::Log4Perl best practices
by bl0rf (Pilgrim) on Jun 01, 2004 at 00:43 UTC
    Try putting
    use Log::Log4perl qw(:levels); Log::Log4perl::init('/home/code/log4perl-conf.txt'); my $logger = Log::Log4perl->get_logger($0); $SIG{__DIE__} = sub {$Log::Log4perl::caller_depth++; $logger->fatal('f +atal: ', @_); die @_;};
    into a separate module, that doesn't have a separate package. Then include only that module in your scripts, this should reduce the extra code to a single use..blah.. statement.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://357854]
Approved by adrianh
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2024-04-16 14:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found