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