3.6. Using your own log4j.xml file - Log4j RepositorySelector
Another way to achieve this is to write a custom
RepositorySelector
that changes how the LogManager gets a logger. Using this technique, Logger.getLogger()
will return a different logger based on the context class loader. Each context class loader has its own configuration set up with its own log4j.xml
file.
/* * JBoss, Home of Professional Open Source * Copyright 2005, JBoss Inc., and individual contributors as indicated * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.repositoryselectorexample; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.log4j.Hierarchy; import org.apache.log4j.Level; import org.apache.log4j.LogManager; import org.apache.log4j.spi.LoggerRepository; import org.apache.log4j.spi.RepositorySelector; import org.apache.log4j.spi.RootCategory; import org.apache.log4j.xml.DOMConfigurator; import org.w3c.dom.Document; /** * This RepositorySelector is for use with web applications. * It assumes that your log4j.xml file is in the WEB-INF directory. * @author Stan Silvert */ public class MyRepositorySelector implements RepositorySelector { private static boolean initialized = false; // This object is used for the guard because it doesn't get // recycled when the application is redeployed. private static Object guard = LogManager.getRootLogger(); private static Map repositories = new HashMap(); private static LoggerRepository defaultRepository; /** * Register your web-app with this repository selector. */ public static synchronized void init(ServletConfig config) throws ServletException { if( !initialized ) // set the global RepositorySelector { defaultRepository = LogManager.getLoggerRepository(); RepositorySelector theSelector = new MyRepositorySelector(); LogManager.setRepositorySelector(theSelector, guard); initialized = true; } Hierarchy hierarchy = new Hierarchy(new RootCategory(Level.DEBUG)); loadLog4JConfig(config, hierarchy); ClassLoader loader = Thread.currentThread().getContextClassLoader(); repositories.put(loader, hierarchy); } // load log4j.xml from WEB-INF private static void loadLog4JConfig(ServletConfig config, Hierarchy hierarchy) throws ServletException { try { String log4jFile = "/WEB-INF/log4j.xml"; InputStream log4JConfig = config.getServletContext().getResourceAsStream(log4jFile); Document doc = DocumentBuilderFactory.newInstance() .newDocumentBuilder() .parse(log4JConfig); DOMConfigurator conf = new DOMConfigurator(); conf.doConfigure(doc.getDocumentElement(), hierarchy); } catch (Exception e) { throw new ServletException(e); } } private MyRepositorySelector() { } public LoggerRepository getLoggerRepository() { ClassLoader loader = Thread.currentThread().getContextClassLoader(); LoggerRepository repository = (LoggerRepository)repositories.get(loader); if (repository == null) { return defaultRepository; } else { return repository; } } }