[slf4j-user] Per-web-app logging with jars on the server's classpath

Jacob Kjome hoju at visi.com
Thu Mar 15 07:37:21 CET 2007


I thought of one other thing.  The ContextJNDISelector looks up JNDI 
resources relative to "java:comp/env/".  It occurs to me that in 
Weblogic, you need to remap these in "WEB-INF/weblogic.xml" in order 
to make the entries available within the "java:comp/env/" 
namespace.  For instance...

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE weblogic-web-app
   PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN"
   "http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd">
<weblogic-web-app>
         <reference-descriptor>
                 <resource-description>
                   <res-ref-name>
                     log4j/context-name
                   </res-ref-name>
                   <jndi-name>
                     log4j/context-name
                   </jndi-name>
                 </resource-description>
                 <resource-description>
                   <res-ref-name>
                     log4j/configuration-resource
                   </res-ref-name>
                   <jndi-name>
                     log4j/configuration-resource
                   </jndi-name>
                 </resource-description>
         </reference-descriptor>
</weblogic-web-app>

I'm not 100% positive this is necessary (or correct) for this 
situation?  I know it's necessary to map local ref names defined in 
web.xml to JNDI names defined in server config, such as when looking 
up DataSources.  If what I suggested in my last email doesn't quite 
work, try adding the above to the mix and see if it makes a difference.

Please report back on whether any of this worked (or didn't) so we 
can document it in the Wiki.


Jake

At 12:07 PM 3/15/2007, you wrote:
 >
 >What are you doing to install the repository selector?  Are you doing it
 >programatically or via the System property?  For instance, here's the System
 >property to set in Weblogic's startup script...
 >
 >-Dlog4j.repositorySelector=JNDI
 >OR
 >-Dlog4j.repositorySelector=com.mycompany.MyCustomSelector
 >
 >Oh, and I presume your "log4j_webapp.properties" is sitting in the default
 >package in the classpath of the webapp, such as in the "WEB-INF/classes"
 >directory, right?  Or, you can also have it on the System classpath 
if you want
 >all apps to use the same config file.  It uses the context class 
loader, so it
 >should attempt to look it up first in the classloader from which 
the thread was
 >initiated and fall back to the system classloader via standard classloader
 >delegation.
 >
 >BTW, there's also a utility for removing logger repository for an app when it
 >shuts down, though I'm not sure it's yet included in the latest 1.3alpha jar
 >available for download, but is in the SVN source [1].  We really 
need to create
 >another alpha release to pick up changes over the last, well..., a
 >little over a
 >year.  For this reason, I actually suggest that you build Log4j-1.3 
from source
 >instead of using the existing downloadable binary.
 >
 >[1]
 >http://svn.apache.org/viewvc/logging/log4j/trunk/src/java/org/apache/l
 >og4j/selector/servlet/ContextDetachingSCL.java
 >
 >Jake
 >
 >Quoting Mark Stralka <mstralka at gmail.com>:
 >
 >> Jacob Kjome <hoju <at> visi.com> writes:
 >>
 >> >
 >> >
 >> > Your repository selector is based on classloader, right?  Doesn't
 >> > JBoss use a "Unified Classloader" strategy?  That is, every app
 >> > running on the server uses the same classloader?  That is, unless it
 >> > is configured otherwise.  If this is truly the case, then you
 >> > repository selector will not separate logger repositories under
 >> > JBoss.  And I strongly recommend you avoid Classloader-based
 >> > repository selectors.  You'd be better off using a JNDI-based
 >> > repository selector.  If you use Log4j 1.3, one is already available
 >> > [1].  If not, you can grab the one from the sandbox [2].  Note that a
 >> > Classloader-based version exists there, but you should ignore that
 >> > and look at the ContextJNDISelector.  Can you try this out and see if
 >> > it works for you?
 >> >
 >> > [1]
 >> >
 >>
 >http://logging.apache.org/log4j/docs/api-1.3/org/apache/log4j/selector
 >/ContextJNDISelector.html
 >> > [2]
 >> >
 >>
 >http://svn.apache.org/viewvc/logging/sandbox/log4j/log4j_sandbox/tags/
 >LOG4J_SANDBOX_ALPHA3/src/java/org/apache/log4j/selector/
 >> >
 >> > Jake
 >> >
 >>
 >> Hi Jake,
 >> I upgraded to 1.3alpha8 and implemented the ContextJNDISelector as you
 >> suggested
 >> but I'm still having problems.  To clarify, we're using Weblogic 
8.1 SP4, not
 >> JBoss - I only named the file JbossAppRepositorySelector because 
that was the
 >> name of the file I got from their wiki.
 >>
 >> I think the challenge with the way we're implementing logging is 
that most of
 >> our JAR files are loaded on Weblogic's classpath, and we need 
each web app to
 >> be
 >> able to write log entries for classes in those JARs to its own log file.
 >>
 >> The LogManager.repositorySelector is a static variable, which I 
think is only
 >> loaded once by Weblogic since it's on the server's classpath
 >>
 >> Weblogic classpath:
 >> myframework.jar (our custom code)
 >> --Includes:
 >> ----com.myframework.web.StartupListener (extends Spring's
 >> ContextLoaderListener)
 >> ----com.myframework.web.UserFormController (and other various classes)
 >> ----com.myframework.service.XyzManager (business layer)
 >> ----com.myframework.dao.XyzDao (data layer)
 >> spring.jar
 >> log4j.jar (now v1.3alpha8)
 >> slf4j*.jar
 >> jcl104-over-slf4j-1.3.0.jar
 >> other JARs
 >>
 >> Each Web App (appA, appB, etc - we have dozens of WAR files):
 >> Uses Spring to configure the classes from myframework.jar (which is NOT in
 >> WEB-INF/lib)
 >> Uses com.myframework.web.UserFormController and needs to write 
log entries to
 >> its own file (appA.log, appB.log, etc)
 >> Each WAR has its own "log4j_webapp.properties" in WEB-INF/classes
 >>
 >> web.xml:
 >> <listener>
 >>   <listener-class>
 >>      com.myframework.web.StartupListener
 >>   </listener-class>
 >> </listener>
 >> ...
 >> <env-entry>
 >>      <description>Logging Setup</description>
 >>      <env-entry-name>log4j/context-name</env-entry-name>
 >>      <env-entry-value>appA (or appB, appC, etc)</env-entry-value>
 >>      <env-entry-type>java.lang.String</env-entry-type>
 >> </env-entry>
 >> <env-entry>
 >>      <description>Logging Setup</description>
 >>      <env-entry-name>log4j/configuration-resource</env-entry-name>
 >>      <env-entry-value>log4j_webapp.properties</env-entry-value>
 >>      <env-entry-type>java.lang.String</env-entry-type>
 >> </env-entry>
 >>
 >> When I start Weblogic with several WARs deployed, all the log 
entries for the
 >> common classes from myframework.jar (which is most of them) only 
get written
 >> to
 >> the log file for the WAR that was loaded first alphabetically (appA.log
 >> usually).  appB.log, appC.log, etc get created but they're always empty.
 >>
 >> I guess an alternative to separate log files would be to somehow inject the
 >> webapp's name into any logging message that is written to one 
common log file
 >> -
 >> I'm not sure how to do that given that most of the classes are in
 >> myframework.jar and would have to somehow lookup the webapp that 
is currently
 >> using it.
 >> Thanks again for any suggestions or insight
 >>
 >> _______________________________________________
 >> user mailing list
 >> user at slf4j.org
 >> http://www.slf4j.org/mailman/listinfo/user
 >>
 >
 >
 >
 >_______________________________________________
 >user mailing list
 >user at slf4j.org
 >http://www.slf4j.org/mailman/listinfo/user




More information about the slf4j-user mailing list