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

I wish I could do something like this:

$logger1 = get_logger("C1"); $logger1->debug("debug1!"); $logger2 = get_logger("C1", "C2"); $logger2->debug("debug2!");

"debug2" should only be printed if C1 and C2 is at DEBUG level. But "debug1" should be printed regardless of C2 setting. So basically I want a multiple category mechanism. I want to print out variable dumps in a function in a module but only if I enable debugging "for that module" (=C1) and I enable "variable dumping" (=C2). I sometimes even want to single out debugging setting "for only that function" (=C3).

Replies are listed 'Best First'.
Re: Log4perl "multiple categories"?
by dgaramond2 (Monk) on Mar 02, 2006 at 02:26 UTC
    Oh BTW, what do people use the logging categories for usually. Modules/class names only?
      This entry only address the question of category construction and usage, not the OP's question of several active categories. I need to think about that some more.

      my usual retrieval of the logging instance is

      my $logger = get_logger((caller(0))[3]);

      so my log entries usually look like

      2006/03/02 14::55::53 DataMatrix.Encoders.asciiEncoder - DEBUG - data is 99ABC00

      Pattern in log.conf for the layout for me is usually
      %d %c - %p - %m%n
      or datetime category - level - message newline

      Creating the category this way means the category is the fully qualified name of the current function/method. I usually dont include the line numbe, because it just makes the log line longer, and my functions/methods are usually between 5-20 lines

      This means I can activate the logger in a single function in a package with the following config line

      log4perl.logger.path.to.package.function=DEBUG,CONSOLE

      I can activate every logger in a package with

      log4perl.logger.path.to.package=DEBUG,CONSOLE

      And I can activate the logging in the entire application with

      log4perl.logger=DEBUG,CONSOLE

      I can even activate a highly specific logger deep in a function this way

      sub complexFunction { my (%args) = @_; ... # deep inside some complex code { # create a new scope my $logger - get_logger((caller(0))[3] . "::complexBit"); ... $logger->debug("enzyme experiencing toxic reation..."); ... } # close scope, leaving that logger behind

      Match that with a config file directive like this

      log4perl.logger.path.to.package.function.complexBit=DEBUG,COMLPEXFILE

      and you can comment out this line to not see this logging, or uncomment to activate it. This technique is especially powerful if the deep logger is inside several loops, and its quite voluminous.

      If you start the application with that line in the log config commented out, you wont see anything. If your initialisation of Log4 perl is by using

      Log::Log4perl->init_and_watch('path/to/config', $delay);

      then you can start the app, and uncomment the line, wait $delay seconds for the logging to start, comment out the line again and wait upto $delay seconds for it to stop again. Or you could setup a signal handler to toggle the activation of a logging category in response to you sending a SIGUSR1 to the applications process - we've used this technique when debugging DBI SQL problems. Application normally has quiencent logging, but we can activate logging for a single running instance of that application by sending it a signal. Better than all the logging starting for your running processes that share a config file!

      ...reality must take precedence over public relations, for nature cannot be fooled. - R P Feynmann

Re: Log4perl "multiple categories"?
by ikegami (Patriarch) on Mar 02, 2006 at 03:58 UTC
    I'm not familiar with Log4perl, but it sounds like this could easily be done by subclassing and overriding.