Mike Schilli wrote:
>> The trigger for the problem turned out to be a 'use' call in the eval'ed
>> code that loaded a library which internally called easy_init() (yet
>> specifying the INFO logging level).
> 
> That's very confusing and should be avoided at all cost.
> We discourage people from doing that...

You are correct. The man page does discourage initializing the logger in
multiple places, and it was an oversight that this code did that.

It came about because the $logger object doesn't actually convey the
full state, so when serialized and passed to a remote method, the remote
logging reverts to default logging settings.

To work around that, a Log4perl subclass was created, with it's own
init() that applies the application's stock preferences via a call to
easy_init(), and then that subclass is invoked both from the main
program and from the class that is executed remotely.

(On a side note, I had to rewrite easy_init() in order to make it
subclass friendly. We can discuss that further in a separate thread, if
interested.)

The presence of the Log4perl subclass in the project made it all too
convenient to invoke Log4perl that way from a library. I've corrected
the library to use Log::Log4perl->get_logger($class) to obtain its
logger instead, and I've updated the documentation of our Log4perl
subclass to warn against its use in all but the main program.

(Most libraries in the project get their logger passed to them from the
main code, and don't make use of categories.)

I'm still puzzled why the original logger object was rendered useless
(such that it wouldn't even log fatal messages). The call to easy_init()
does reset the logger, but my code also configured it to INFO logging
level. Did it reset the old logger and create a new object, which then
only the library code saw, while the main code saw the reset logger?


> That library wasn't using 'normal Log4perl methods'...

I get your point, but I consider easy_init() to be a normal method. With
Perl it is almost always possible to monkey with the private namespace
of a module, but it suggests bad design if using the provided API makes
it possible for one library to stomp on another.

I assume that this practice of maintaining global state in Log4perl came
about because it is convenient to be able to call get_logger() as a
class method, rather than having the application pass an object around.
But it seems that it would be way better if Log4perl was internally
designed to store all state in instance variables, and leave it to the
application developer to decide whether they want to pass around
objects, or dedicate a global variable to it.


> But you're bringing up an interesting topic: What would be a good
> approach to allow a library to meddle with Log4perl's settings, in the
> absence or even presence of a previous initialization?

When I fixed the library code to use Log::Log4perl->get_logger($class),
my first attempt was actually to pass a logger object to the library,
and call $logger->get_logger($class), assuming get_logger($class) would
clone $logger, set the category, and return a new logger. Instead it
fails in Log::Log4perl->_new() when it tries to bless the already
blessed object.

Ultimately I want a method I can call from my libraries where I can pass
in a $logger parameter. The method then looks to see if $logger is set
to anything, and if it is, clones it, sets the category, and returns the
object. If not, it creates a new logger object for that category, and
applies the logger settings I've specified somewhere. And, either code
path should have absolutely no impact on any existing logger objects in
use elsewhere in the code.

As mentioned above, we also have the need to capture the full state in
the $logger object, so it can be serialized, and used remotely.

 -Tom

------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1,  ECMAScript5, and DOM L2 & L3.
Spend less time writing and  rewriting code and more time creating great
experiences on the web. Be a part of the beta today
http://p.sf.net/sfu/msIE9-sfdev2dev
_______________________________________________
log4perl-devel mailing list
log4perl-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/log4perl-devel

Reply via email to