Hi Jake, I actually read through the Log4j CVS ContextClassLoaderSelector and servlet specific package java files. They were very helpful and documented extremely well.
Forgive me if I'm just re-stating the obvious. If I understand it right, the init method of InitServlet is called by the container. This is called once per context start-up right? This method performs the initializeLog4j task which sets the RepositorySelector by creating a new instance of ContextClassLoaderSelector, if one is not already created. Having done that, it will load the log4j properties or xml file associated with the context. Only 1 instance of the ContextClassLoaderSelector is created and set using LogManager so that we can track each Hierarchy based on the context classloader. I believe I do all of that, however I do not manually call PropertyConfigurator or DOMConfigurator. I use OptionConverter.selectAndConfigure, as it should determine if the log4j config file is an xml or properties file and call the corresponding Configurator. The other difference I see is that I call OptionConverter.selectAndConfigure in my getLoggerRepository implementation method. My understanding is that when I call Logger.getLogger(..) and having set the Thread.currentThread().contextClassLoader, a new LoggerRepository/Hierarchy will be created or looked up if already exists. I can't see why it would make a difference if I manually call the OptionConverter.selectAndConfigure when a new context is about to run for the first time. But, it is something I will try. If you have any other thoughts, I'd appreciate them. Cheers, Vance -----Original Message----- From: Jacob Kjome [mailto:[EMAIL PROTECTED] Sent: Friday, 19 March 2004 2:31 AM To: Log4J Users List Subject: Re: Contextual Repository Selector problem I don't have much time to respond, but there already exists implementations of repository selectors in the latest Log4j CVS (ContextJNDIRepositorySelector) and in the latest Log4j sandbox CVS (ContextClassLoaderSelector). I added lots of instructions to them. Also look in InitShutdownController (in Log4j sandbox) to see how I initialize the repository selector. See more here... http://nagoya.apache.org/wiki/apachewiki.cgi?Log4JProjectPages/AppContainerL ogging Jake Quoting Vance Karimi <[EMAIL PROTECTED]>: > Hi > I am writing a container server application that runs services/contexts > within it. These services are hot deployed in a jar file and I manage the > ClassLoaders to handle separate contexts. I need to implement the > repository selector in Log4j so each thread that runs a service logs to a > separate log file. > > Based on the following http://www.qos.ch/logging/sc.html I have a Repository > Selector something very similar to: > > > import org.apache.log4j.spi.RepositorySelector; > import org.apache.log4j.spi.LoggerRepository; > import org.apache.log4j.spi.RootCategory; > import org.apache.log4j.Hierarchy; > import org.apache.log4j.Level; > import java.util.Hashtable; > > public class CRS implements RepositorySelector { > > // key: current thread's ContextClassLoader, > // value: Hierarchy instance > private Hashtable ht; > > public CRS() { > ht = new Hashtable(); > } > > public LoggerRepository getLoggerRepository() { > LoggerRepository loggerRepository = null; > > ClassLoader classLoader = > Thread.currentThread().getContextClassLoader(); > > loggerRepository = (LoggerRepository) > loggerRepositories.get(classLoader.toString()); > > if (loggerRepository != null) { > // do nothing > } else { > loggerRepository = new Hierarchy(new RootCategory((Level) > Level.DEBUG)); > loadRepository(loggerRepository); > loggerRepositories.put(classLoader.toString(), loggerRepository); > > } > > return loggerRepository; > } > > /** > * The Container should remove the entry when the web-application > * is removed or restarted. > * */ > public void remove(ClassLoader cl) { > if (loggerRepositories.containsKey(cl.toString())) { > LoggerRepository lr = (LoggerRepository) > loggerRepositories.get(cl.toString()); > lr.resetConfiguration(); > } > loggerRepositories.remove(cl.toString()); > } > > private static void loadRepository(LoggerRepository loggerRepository) { > > URL url = getURL(resources); > > if (url != null) { > OptionConverter.selectAndConfigure(url, null, loggerRepository); > } > } > ..... > } > > > I set the Context Repository Selector when the server first starts up: > > if (guard == null) { > guard = new Object(); > } > > ContextRepositorySelector crs = agent.registerContextRepositorySelector(); > LogManager.setRepositorySelector(crs, guard); > > > I have enabled debugging in Log4j. When my server first starts up, I get > the following debug statements due to the log4j.properties of the server, > showing the root context and 2 appenders (Default and Console) > > log4j: Parsing for [root] with value=[DEBUG, Default, Console]. > log4j: Level token is [DEBUG]. > log4j: Category root set to DEBUG > log4j: Parsing appender named "Default". > log4j: Parsing layout options for "Default". > log4j: Setting property [conversionPattern] to [%d [%t] %-5p %c - %m%n]. > log4j: End of parsing for "Default". > log4j: Setting property [append] to [true]. > log4j: Setting property [file] to [server/log/server.log]. > log4j: Setting property [datePattern] to ['.'yyyy-MM-dd]. > log4j: setFile called: server/log/server.log, true > log4j: setFile ended > log4j: Appender [Default] to be rolled at midnight. > log4j: Parsed "Default" options. > log4j: Parsing appender named "Console". > log4j: Parsing layout options for "Console". > log4j: Setting property [conversionPattern] to [%d [%t] %-5p %c - %m%n]. > log4j: End of parsing for "Console". > log4j: Parsed "Console" options. > log4j: Finished configuring. > log4j: JIVS: Time taken to look up loggerRepository 368ms > > I then deploy my service and call Logger.getLogger(my.service.class) to get > the following for the root logger with 2 appenders(A1 and A2): > > log4j: Parsing for [root] with value=[DEBUG, A1, A2]. > log4j: Level token is [DEBUG]. > log4j: Category root set to DEBUG > log4j: Parsing appender named "A1". > log4j: Parsing layout options for "A1". > log4j: Setting property [conversionPattern] to [%d [%t] %-5p %c - %m%n]. > log4j: End of parsing for "A1". > log4j: Setting property [file] to [server/log/recorder.log]. > log4j: Setting property [append] to [true]. > log4j: Setting property [datePattern] to ['.'yyyy-MM-dd]. > log4j: setFile called: server/log/recorder.log, true > log4j: setFile ended > log4j: Appender [A1] to be rolled at midnight. > log4j: Parsed "A1" options. > log4j: Parsing appender named "A2". > log4j: Parsing layout options for "A2". > log4j: Setting property [conversionPattern] to [%d [%t] %-5p %c - %m%n]. > log4j: End of parsing for "A2". > log4j: Parsed "A2" options. > log4j: Finished configuring. > log4j: JIVS: Time taken to look up loggerRepository 33ms > > Now the problem: > > All my logs are directed to server.log and the console. The recorder.log > (log for the deployed service) is created, but no logs are appended to the > file. I know the log4j.properties config file of the service is found and > loaded correctly due to the debug statements. > > I really need some direction here and have come to a dead end. Your > feedback would be really appreciated. > > Cheers, > Vance > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
