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

Mark Stralka mstralka at gmail.com
Sat Mar 17 15:37:14 CET 2007


Jacob Kjome <hoju <at> visi.com> writes:
> 
> You should use the System property if you can.  If you have to use the
> programmatic call, you'll need to change it slightly.  Your "guard" object is
> null.  If you are doing this in every webapp, it is possible that you are
> simply re-setting the logger repository selector for every single call to
> setRepositorySelector().  The theory is that, because the "guard" object is
> null, a null value on successive calls matches the existing guard and allows
> the repository selector to be reset, which is what the "guard" was meant to
> prevent.  I suggest you pass in something like "new Object()".  This will act
> as a guard that no successive call will be able to replicate and, therefore,
> the repository selector will be set once with no chance of being re-set later,
> which is what you want.

> 
> 
> Good.  It's good that you built from source.  Your question is not clear,
> though.  Did you mean "what is the utility for" or "what is the utility *of*"? 
> If the former, I pointed you to it in the link above.  If the latter, the
> utility is the ability to clean up resources that are no longer needed.  If
> your application gets undeployed, what's the point in keeping the logger
> repository there?  It serves no purpose and can be thought of as a memory leak.
>  If the app is deployed again, it will re-created.  If you are not concerned
> about the cleanup, then you don't need to bother with this, but the utility is
> there for your use if you care.
> 

Jake, I did some testing and have determined that logging to separate files
works when I use Log4j.jar directly, but when I use JCL and SLF4j
(jcl104-over-slf4j-1.3.0.jar, slf4j-api-1.3.0.jar, and slf4j-log4j12-1.3.0.jar),
the log entries only write to appA.log.  This is obviously a problem because my
real framework extends Spring, which uses JCL internally.

Here's what I did:
Created 3 new Eclipse projects: myframework, appA, and appB.
-myframework contains only one servlet: com.myframework.web.HelloServlet.
-myframework.jar is deployed on weblogic's classpath, along with log4j.jar
-appA and appB are identical, except appA's log4j_webapp.properties file sets:
log4j.logger.com.myframework=debug
and appB's file sets:
log4j.logger.com.myframework=warn.
-appA and appB both have the JNDI log4j env-entries and the "log4j/context-name"
is set to appA for appA, appB for appB.

Weblogic starts with -Dlog4j.repositorySelector=JNDI

When I configure HelloServlet to use Log4j directly logging works fine:
package com.myframework.web;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

public class HelloServlet extends HttpServlet {
	private Logger logger = Logger.getLogger(getClass());
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
		logger.debug("entering doGet()");
		logger.info("info 1");
		logger.warn("warn 1");
		logger.debug("leaving doGet()");
		PrintWriter out = response.getWriter();
		out.println("Hello World");
	}
}

When I configure HelloServlet to use JCL over SLF4j - it only writes to appA.log
for both apps:
package com.myframework.web;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class HelloServlet extends HttpServlet {
	private Log logger = LogFactory.getLog(getClass());
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
		logger.debug("entering doGet()");
		logger.info("info 1");
		logger.warn("warn 1");
		logger.debug("leaving doGet()");
		PrintWriter out = response.getWriter();
		out.println("Hello World");
	}
}

I'm going to look through SLF4j's implementation of the JCL interfaces to see if
I can just change the JCL interfaces to use Log4j directly... do you think
that's correct?

Thanks again




More information about the slf4j-user mailing list