I'm using log4j to log application code for several websites, 
each of which has at least one WebApp, and some of which have 
more than one.  I'm configuring log4j with an initialization 
servlet (that also does a few other things) from a properties 
file using .configureAndWatch(java.io.File).  I'd like to allow 
each webapp to have its own log4j configuration.  The typical 
configuration I am using logs to the console with the site name 
and webapp name prepended, logs a similar format to a 
RollingFileAppender with the file name determined by the site 
name, and a SMTPAppender for error notification.

All of these are working fine, with one small exception... 
the configuration of the last properties file loaded is used for 
all debug output.  For example, I am expecting to see:

[www.domainname.com] log message
[www.someothername.com] some other log message
[www.athirddomain.com] yet another log message

Instead, I'm seeing:
[www.domainname.com] log message
[www.domainname.com] some other log message
[www.domainname.com] yet another log message

I am using a large amount of common code across these webapps,
so I can't just separate configurations by class name.

Presently, I'm putting the log4j.jar file in the WEB-INF/lib for
each webapp, and the properties file is in WEB-INF/properties 
(eg, not one of the standard log4j locations).  I'm using 
log4j-1.2.8; I've seen this problem on both Tomcat 4.1.24 and 
5.0.19.  

I found that when I put the log4j.properties file in 
WEB-INF/classes/log4j.properties it didn't seem to be found at 
all, which is why I moved to this method.  I suspect that if the 
log4j code had already initialized itself from somewhere 
(perhaps for tomcat internal use?) it wouldn't need to look in 
specific webapp classpaths and thus wouldn't pick up the 
configuration.

A bit of googling ran across the class below, which fixes the 
problem, except that you have to initialize log4j with that 
class, and you can only do so once; subsequent initializations
(eg, with the same initializer servlet in multiple webapps) 
either throw ugly errors or could be easily overwritten by any 
webapp that disagreed with the idea and wanted to do something 
else.

http://cvs.apache.org/viewcvs.cgi/jakarta-log4j-sandbox/src/java/org/apache/log4j/selector/ContextClassLoaderSelector.java?rev=1.7&view=markup

Since I had already written a Valve for something else and had 
sample code handy, I wrote a Valve to initialize log4j with a 
similar policy.  This works and has solved my problem, but leaves 
me with three questions:

1) Is this the way it's supposed to work?  (If so, someone should 
fix the log4j documentation).

2) If it's supposed to work this way, then it seems to me that 
setting the log4j policy to use separate heirarchies by classpath 
should be the default policy.  I can't think of any reason why 
one webapp's logging configuration should be able to alter any 
other webapp's logging.  Am I wrong?

3) If I'm right about 2, is there a better way to do it than a 
valve?  Using a valve means I can drop the addition into an 
existing configuration, but it seems exceedingly awkward to run 
all requests through an extra layer just to get a class loaded 
and initialized once-and-only-once with no webapp dependencies.  
Is there a better construct for this sort of thing?

4) If there's interest I'd gladly contribute the valve to the 
apache codebase so others can just modify their server.xml rather 
than writing code; is there any interest in doing that?

-- 
Matthew Hunter ([EMAIL PROTECTED])
Public Key: http://matthew.infodancer.org/public_key.txt
Homepage: http://matthew.infodancer.org/index.jsp
Politics: http://www.triggerfinger.org/index.jsp

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to