[slf4j-user] Per-web-app logging with jars on the server's classpath
Mark Stralka
mstralka at gmail.com
Tue Mar 13 12:15:55 CET 2007
Jacob Kjome <hoju <at> visi.com> writes:
>
>
> It doesn't much matter what the config file looks like, but what your
> custom repository selector is doing. Clearly it isn't working,
> otherwise you'd have separate logger repositories and no cross-talk
> between application-specific logger repositories. So, what does your
> implementation look like? How it the repository selector
> installed?. How are you configuring each repository? Where are your
> config files? Where's Log4j?
>
> Jake
>
> At 06:59 PM 3/12/2007, you wrote:
> >We have a custom web framework packaged into a jar file
> (myframework.jar) that
> >is used by 50 web applications deployed as WAR files on Weblogic 8.1 SP4.
> >myframework.jar uses the Spring framework internally (which uses commons
> >logging API), so we must continue to use SLF4J's jcl104-over-slf4j-1.3.0.jar
> >for the foreseeable future. None of these web apps use EJBs and I want to
> >avoid them.
> >
> >myframework.jar, log4j.jar, slf4j*.jar spring.jar, and dozens of other 3rd
> >party dependencies are loaded on Weblogic's server classpath.
> >myframework.jar is under continual development by my team and we can't
> >redeploy every WAR file with the new version of libraries in WEB-INF/lib -
> >so we have to load myframework and other JARs on weblogic's classpath.
> >Each web app has very few Java classes of its own - most are Spring-injected
> >from myframework.jar.
> >
> >This has proven to be an interesting puzzle because we want each web app to
> >write to its own log file (appA.log, appB.log, etc), but be able to record
> >log entries from classes inside myframework.jar, spring.jar, etc for
> >debugging purposes.
> >
> >I bought the Log4J book, read Chapter 8, and followed the JBoss instructions
> >here http://wiki.jboss.org/wiki/Wiki.jsp?page=Log4jRepositorySelector
> >to create a custom RepositorySelector (which loads
> /WEB-INF/log4j.properties),
> >and modified myframework's StartupListener to initialize this
> >RepositorySelector in each web app's web.xml.
> >
> >The problem is that when I start weblogic with several webapps (appA.war,
> >appB.war, appC.war, etc), all log entries are written to appA.log, even
> >though each application has its own WEB-INF/log4j.properties (albeit they
> >are currently all the same, except for the "log4j.appender.file.File" value).
> >
> >Am I doing something wrong to keep JAR files at the server level but let
> >each web app write to its own log file? Thank you
> >
> >Here is appA's log4j.properties file:
> >log4j.rootLogger=warn, file
> >
> >### direct messages to file <app name>.log ###
> >log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
> >log4j.appender.file.DatePattern='.'yyyy-MM-dd
> >#Each app should go to its own log file but they are not
> >log4j.appender.file.File=c:/logs/appA.log
> >log4j.appender.file.layout=org.apache.log4j.PatternLayout
> >log4j.appender.file.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss,SSS}
> >%5p %C{1} - %m%n
> >
> >log4j.logger.org.apache.struts=error
> >log4j.logger.org.apache.commons=error
> >log4j.logger.org.apache.jcs=error
> >log4j.logger.org.springframework=error
> >log4j.logger.org.hibernate=error
> >log4j.logger.org.acegisecurity=error
> >
> >#Make sure you turn logging off before deploying to staging or production.
> >log4j.logger.com.myframework.core=debug
> >
> >_______________________________________________
> >user mailing list
> >user <at> slf4j.org
> >http://www.slf4j.org/mailman/listinfo/user
>
public class JbossAppRepositorySelector implements RepositorySelector {
private static boolean initialized = false;
private static Object guard = LogManager.getRootLogger();
private static Map repositories = new HashMap();
private static LoggerRepository defaultRepository;
public static synchronized void init(ServletConfig servletConfig)
throws ServletException {
init(servletConfig.getServletContext());
}
public static synchronized void init(ServletContext servletContext)
throws ServletException {
if (!initialized) // set the global RepositorySelector
{
defaultRepository = LogManager.getLoggerRepository();
RepositorySelector theSelector = new JbossAppRepositorySelector();
LogManager.setRepositorySelector(theSelector, guard);
initialized = true;
}
Hierarchy hierarchy = new Hierarchy(new RootCategory(Level.DEBUG));
loadLog4JConfig(servletContext, hierarchy);
ClassLoader loader = Thread.currentThread().getContextClassLoader();
repositories.put(loader, hierarchy);
}
public static synchronized void removeFromRepository() {
repositories.remove(Thread.currentThread().getContextClassLoader());
}
// load log4j.xml from WEB-INF
private static void loadLog4JConfig(ServletContext servletContext,
Hierarchy hierarchy) throws ServletException {
String log4jFile = null;
InputStream log4JConfig = null;
Properties properties = new Properties();
PropertyConfigurator conf = new PropertyConfigurator();
try {
log4jFile = "/WEB-INF/log4j_webapp.properties";
log4JConfig = servletContext.getResourceAsStream(log4jFile);
properties.load(log4JConfig);
conf.doConfigure(properties, hierarchy);
} catch (Exception e) {
throw new ServletException(e);
}
}
private JbossAppRepositorySelector() {
}
public LoggerRepository getLoggerRepository() {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
LoggerRepository repository = (LoggerRepository) repositories.get(loader);
if (repository == null) {
return defaultRepository;
} else {
return repository;
}
}
}
com.myframework.web.StartupListener:
public void contextInitialized(ServletContextEvent event) {
...
JbossAppRepositorySelector.init(event.getServletContext());
...
}
More information about the slf4j-user
mailing list