You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by Matthew Hunter <ma...@infodancer.org> on 2004/04/05 18:44:59 UTC

Re: Log4j classpath merging?

On Tue, Mar 30, 2004 at 02:24:49PM +0200, Ceki G?lc? <ce...@qos.ch> wrote:
> We have just added new code to log4j in order to provide a complete
> solution to the problem you are describing.

I glanced over the ContextJNDISelector and the accompanying 
examples.  It does look like it is solving the same problem, and 
in a fairly clean way.  However, according to the INSTALL.txt 
file, it will require log4j 1.3, which isn't out yet.  Thus, it 
doesn't effectively solve my problem.

Of course, "people other than me" have the same problem with 
any solution I contribute, so that's a wash, leaving mainly the 
documentation issue.

> >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).
> 
> What part of log4j documentation should be fixed?
> It is not clear to me what you mean by "is the way it's supposed to work?". 
> However, the fact that class loading issues are problematic has been known 
> for quite a while.

The documentation at the link below claims that if you place the 
log4j.properties under the WEB-INF/classes directory of each 
web-app, that file will be used to initialize the log4j system 
separately for each webapp.  That does not appear to be the case 
for the version of Tomcat 4.0 that I tested; instead, either no 
initializations are loaded, or if a webapp forces the issue (eg, 
by calling configureAndWatch() on a properties file) that 
configuration overrides the configuration for ALL webapps.  

http://logging.apache.org/log4j/docs/manual.html

This documentation may well have been correct for earlier 
versions of Tomcat.  

I was mainly directing "Is this how it is supposed to work?" at 
Tomcat developers, who presumably should be establishing a 
completely separate classloader for each webapp.  In other words, 
I see this as more of a Tomcat problem than a log4j problem, but 
I could be wrong about that -- I'm hardly an expert on the 
internal workings of either one, much less both.

> >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?
> Having separate hierarchies for each web-app is certainly a reasonable 
> policy. However, we are still testing the various implementation of this 
> policy and cannot make it "default" before through testing.

That's certainly reasonable, but then the documentation should 
say that the feature isn't working yet, or doesn't work on 
certain versions, I would think.

> >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?
> 
> What does the valve do? I'd be interested to study in the code.

The only thing the valve does is initialize log4j with the 
ContextClassLoaderSelector when Tomcat itself is initialized 
(and hence initializes the valve).  This ensures that even with
separate classloaders we have a once-and-once-only initialization
of the log4j selector that occurs before any of the webapps have 
a chance to confuse the issue.

The class is located temporarily at:

http://www.infodancer.org/software/Log4jSeparatorValve.java

Note that at the present it depends on a version of 
ContextClassLoaderSelector within the same package, so I don't 
have the external dependency, but no significant changes were 
made otherwise.  That version is here:

http://www.infodancer.org/software/ContextClassLoaderSelector.java

It would be trivial to make the selector class parameterizable.

For the valve to work it must be able to find the log4j classes; 
dropping them in common/lib seems simplest.  There should 
also be a configuration file in server/classes/log4j.properties
to control how Tomcat's internal logging works.  

The config file needs this line:
<Valve className="org.infodancer.servlet.Log4jSeparatorValve" />

It must be noted that this code is very raw, not very well 
tested, and certainly not release-quality.  However, it's working 
for me at the moment.

> >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?
> Please do. We should perhaps continue this discussion in log4j-dev@logging.

I've redirected it there.  

While I'm perfectly willing to contribute this, I haven't done 
any apache contributions before and have absolutely no idea what 
hoops need to be jumped through.  And of course there's no point 
if this particular problem can be solved in a cleaner way, as 
the JNDI class seems to do.  If there's interest, I'll do a bit 
of cleaning and polishing on this solution and contribute it; 
just point me in the right direction.  

-- 
Matthew Hunter (matthew@infodancer.org)
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: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org


Re: Log4j classpath merging?

Posted by Jacob Kjome <ho...@visi.com>.
At 12:40 PM 4/5/2004 -0500, you wrote:
>On Mon, Apr 05, 2004 at 05:32:29PM +0000, Jacob Kjome <ho...@visi.com> wrote:
> > See the version in logging-log4j-sandbox.  Check out the tag mark 
> 0_2_ALPHA (or
> > something like that).  It will work with Logj4-1.2.8.  I have been 
> using it for
> > quite a while now with perfect separation of container and multiple webapp
> > logging under most any appserver.
>
>I'll wait for 1.3 rather than mess with what I have working right
>now, but as soon as 1.3 is ready I'll give it a try.

Sure.  If you have something that works and only need it to work in Tomcat, 
then what you have should do the job.

Just to be clear, when I mentioned the 1.2 compatible repository selector 
implementation, I meant the ContextJNDISelector which is no longer in the 
HEAD of logging-logj4-sandbox, but still is in the 0_2_ALPHA tagged version 
of CVS.  I would avoid the ContextClassLoaderSelector that is still in the 
sandbox.


Jake


>--
>Matthew Hunter (matthew@infodancer.org)
>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: log4j-dev-unsubscribe@logging.apache.org
>For additional commands, e-mail: log4j-dev-help@logging.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org


Re: Log4j classpath merging?

Posted by Matthew Hunter <ma...@infodancer.org>.
On Mon, Apr 05, 2004 at 05:32:29PM +0000, Jacob Kjome <ho...@visi.com> wrote:
> See the version in logging-log4j-sandbox.  Check out the tag mark 0_2_ALPHA (or
> something like that).  It will work with Logj4-1.2.8.  I have been using it for
> quite a while now with perfect separation of container and multiple webapp
> logging under most any appserver.

I'll wait for 1.3 rather than mess with what I have working right 
now, but as soon as 1.3 is ready I'll give it a try.

-- 
Matthew Hunter (matthew@infodancer.org)
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: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org


Re: Log4j classpath merging?

Posted by Jacob Kjome <ho...@visi.com>.
See the version in logging-log4j-sandbox.  Check out the tag mark 0_2_ALPHA (or
something like that).  It will work with Logj4-1.2.8.  I have been using it for
quite a while now with perfect separation of container and multiple webapp
logging under most any appserver.


Jake

Quoting Matthew Hunter <ma...@infodancer.org>:

> On Tue, Mar 30, 2004 at 02:24:49PM +0200, Ceki G?lc? <ce...@qos.ch> wrote:
> > We have just added new code to log4j in order to provide a complete
> > solution to the problem you are describing.
> 
> I glanced over the ContextJNDISelector and the accompanying
> examples.  It does look like it is solving the same problem, and
> in a fairly clean way.  However, according to the INSTALL.txt
> file, it will require log4j 1.3, which isn't out yet.  Thus, it
> doesn't effectively solve my problem.
> 
> Of course, "people other than me" have the same problem with
> any solution I contribute, so that's a wash, leaving mainly the
> documentation issue.
> 
> > >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).
> >
> > What part of log4j documentation should be fixed?
> > It is not clear to me what you mean by "is the way it's supposed to work?".
> > However, the fact that class loading issues are problematic has been known
> > for quite a while.
> 
> The documentation at the link below claims that if you place the
> log4j.properties under the WEB-INF/classes directory of each
> web-app, that file will be used to initialize the log4j system
> separately for each webapp.  That does not appear to be the case
> for the version of Tomcat 4.0 that I tested; instead, either no
> initializations are loaded, or if a webapp forces the issue (eg,
> by calling configureAndWatch() on a properties file) that
> configuration overrides the configuration for ALL webapps.
> 
> http://logging.apache.org/log4j/docs/manual.html
> 
> This documentation may well have been correct for earlier
> versions of Tomcat.
> 
> I was mainly directing "Is this how it is supposed to work?" at
> Tomcat developers, who presumably should be establishing a
> completely separate classloader for each webapp.  In other words,
> I see this as more of a Tomcat problem than a log4j problem, but
> I could be wrong about that -- I'm hardly an expert on the
> internal workings of either one, much less both.
> 
> > >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?
> > Having separate hierarchies for each web-app is certainly a reasonable
> > policy. However, we are still testing the various implementation of this
> > policy and cannot make it "default" before through testing.
> 
> That's certainly reasonable, but then the documentation should
> say that the feature isn't working yet, or doesn't work on
> certain versions, I would think.
> 
> > >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?
> >
> > What does the valve do? I'd be interested to study in the code.
> 
> The only thing the valve does is initialize log4j with the
> ContextClassLoaderSelector when Tomcat itself is initialized
> (and hence initializes the valve).  This ensures that even with
> separate classloaders we have a once-and-once-only initialization
> of the log4j selector that occurs before any of the webapps have
> a chance to confuse the issue.
> 
> The class is located temporarily at:
> 
> http://www.infodancer.org/software/Log4jSeparatorValve.java
> 
> Note that at the present it depends on a version of
> ContextClassLoaderSelector within the same package, so I don't
> have the external dependency, but no significant changes were
> made otherwise.  That version is here:
> 
> http://www.infodancer.org/software/ContextClassLoaderSelector.java
> 
> It would be trivial to make the selector class parameterizable.
> 
> For the valve to work it must be able to find the log4j classes;
> dropping them in common/lib seems simplest.  There should
> also be a configuration file in server/classes/log4j.properties
> to control how Tomcat's internal logging works.
> 
> The config file needs this line:
> <Valve className="org.infodancer.servlet.Log4jSeparatorValve" />
> 
> It must be noted that this code is very raw, not very well
> tested, and certainly not release-quality.  However, it's working
> for me at the moment.
> 
> > >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?
> > Please do. We should perhaps continue this discussion in log4j-dev@logging.
> 
> I've redirected it there.
> 
> While I'm perfectly willing to contribute this, I haven't done
> any apache contributions before and have absolutely no idea what
> hoops need to be jumped through.  And of course there's no point
> if this particular problem can be solved in a cleaner way, as
> the JNDI class seems to do.  If there's interest, I'll do a bit
> of cleaning and polishing on this solution and contribute it;
> just point me in the right direction.
> 
> --
> Matthew Hunter (matthew@infodancer.org)
> 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: log4j-dev-unsubscribe@logging.apache.org
> For additional commands, e-mail: log4j-dev-help@logging.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org