ceki 2004/11/16 12:29:44 Modified: src/java/org/apache/log4j/helpers Constants.java IntializationUtil.java src/java/org/apache/joran Interpreter.java src/java/org/apache/log4j/joran/action ConfigurationAction.java src/java/org/apache/log4j/joran JoranConfigurator.java Added: tests/input/joran simple1.xml simple2.xml tests/src/java/org/apache/log4j/joran JoranConfiguratorTest.java src/java/org/apache/log4j/joran/action ActionBase.java Log: Self-logigng in log4j. For more documentation see http://www.qos.ch/logging/selfLogging.jsp Revision Changes Path 1.7 +8 -2 logging-log4j/src/java/org/apache/log4j/helpers/Constants.java Index: Constants.java =================================================================== RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/helpers/Constants.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- Constants.java 20 Jun 2004 07:28:52 -0000 1.6 +++ Constants.java 16 Nov 2004 20:29:44 -0000 1.7 @@ -18,9 +18,12 @@ /** - * Constants used by netwrok-based appenders and others. + * Constants used internally throughout log4j. */ public interface Constants { + + static final String LOG4J_PACKAGE_NAME = "org.apache.log4j"; + static final String APPLICATION_KEY = "application"; static final String HOSTNAME_KEY = "hostname"; static final String LOG4J_ID_KEY = "log4jid"; @@ -37,5 +40,8 @@ static final String DEFAULT_CONFIGURATION_KEY = "log4j.configuration"; static final String CONFIGURATOR_CLASS_KEY = "log4j.configuratorClass"; - static String JNDI_CONTEXT_NAME = "java:comp/env/log4j/context-name"; + static final String JNDI_CONTEXT_NAME = "java:comp/env/log4j/context-name"; + + static final String TEMP_LIST_APPENDER_NAME = "TEMP_LIST_APPENDER"; + static final String TEMP_CONSOLE_APPENDER_NAME = "TEMP_CONSOLE_APPENDER"; } 1.5 +8 -8 logging-log4j/src/java/org/apache/log4j/helpers/IntializationUtil.java Index: IntializationUtil.java =================================================================== RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/helpers/IntializationUtil.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- IntializationUtil.java 30 Mar 2004 10:45:21 -0000 1.4 +++ IntializationUtil.java 16 Nov 2004 20:29:44 -0000 1.5 @@ -16,9 +16,6 @@ package org.apache.log4j.helpers; -import org.apache.log4j.ConsoleAppender; -import org.apache.log4j.Logger; -import org.apache.log4j.PatternLayout; import org.apache.log4j.helpers.Loader; import org.apache.log4j.helpers.LogLog; import org.apache.log4j.helpers.OptionConverter; @@ -38,11 +35,14 @@ public static void log4jInternalConfiguration(LoggerRepository repository) { - Logger logger = repository.getLogger("LOG4J"); - logger.setAdditivity(false); - logger.addAppender( - new ConsoleAppender( - new PatternLayout("log4j-internal: %r %-22c{2} - %m%n"))); + // This method does not do anoything currently. It might become useful + // when sub-domains are added to log4j. + +// Logger logger = repository.getLogger("LOG4J"); +// logger.setAdditivity(false); +// logger.addAppender( +// new ConsoleAppender( +// new PatternLayout("log4j-internal: %r %-22c{2} - %m%n"))); } /** 1.1 logging-log4j/tests/input/joran/simple1.xml Index: simple1.xml =================================================================== <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration> <log4j:configuration > <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%5sn %d %level [%t] %c - %m%n"/> </layout> </appender> <root> <level value ="DEBUG" /> <appender-ref ref="CONSOLE" /> </root> </log4j:configuration> 1.1 logging-log4j/tests/input/joran/simple2.xml Index: simple2.xml =================================================================== <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration> <log4j:configuration debug="true"> <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%sn %d %c - %m%n"/> </layout> </appender> <root> <level value ="DEBUG" /> <appender-ref ref="CONSOLE" /> </root> </log4j:configuration> 1.14 +2 -5 logging-log4j/src/java/org/apache/joran/Interpreter.java Index: Interpreter.java =================================================================== RCS file: /home/cvs/logging-log4j/src/java/org/apache/joran/Interpreter.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- Interpreter.java 28 May 2004 14:49:38 -0000 1.13 +++ Interpreter.java 16 Nov 2004 20:29:44 -0000 1.14 @@ -17,8 +17,6 @@ package org.apache.joran; import org.apache.joran.action.*; -import org.apache.log4j.helpers.LogLog; - //import org.apache.log4j.Logger; //mport org.apache.log4j.helpers.LogLog; @@ -101,7 +99,6 @@ } public void startDocument() { - LogLog.info(" in JP startDocument"); } public void startElement( @@ -110,7 +107,7 @@ String tagName = getTagName(localName, qName); - LogLog.debug("in startElement <" + tagName + ">"); + //LogLog.debug("in startElement <" + tagName + ">"); pattern.push(tagName); @@ -125,7 +122,7 @@ String errMsg = "no applicable action for <" + tagName + ">, current pattern is [" + pattern+"]"; - LogLog.warn(errMsg); + //LogLog.warn(errMsg); ec.addError(new ErrorItem(errMsg)); } } 1.1 logging-log4j/tests/src/java/org/apache/log4j/joran/JoranConfiguratorTest.java Index: JoranConfiguratorTest.java =================================================================== /* * Copyright 1999,2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.log4j.joran; import java.util.List; import org.apache.log4j.LogManager; import junit.framework.TestCase; /** * @author ceki * */ public class JoranConfiguratorTest extends TestCase { public void test1() { JoranConfigurator jc = new JoranConfigurator(); jc.doConfigure("./input/joran/simple2.xml", LogManager.getLoggerRepository()); List errorList = jc.getExecutionContext().getErrorList(); for(int i = 0; i < errorList.size(); i++) { System.out.println(errorList.get(i)); } } } 1.2 +61 -8 logging-log4j/src/java/org/apache/log4j/joran/action/ConfigurationAction.java Index: ConfigurationAction.java =================================================================== RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/ConfigurationAction.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ConfigurationAction.java 12 May 2004 15:39:03 -0000 1.1 +++ ConfigurationAction.java 16 Nov 2004 20:29:44 -0000 1.2 @@ -1,33 +1,86 @@ +/* + * Copyright 1999,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.apache.log4j.joran.action; +import org.apache.joran.ErrorItem; import org.apache.joran.ExecutionContext; -import org.apache.joran.action.Action; +import org.apache.log4j.ConsoleAppender; import org.apache.log4j.Logger; +import org.apache.log4j.PatternLayout; +import org.apache.log4j.helpers.Constants; import org.apache.log4j.helpers.LogLog; -import org.apache.log4j.helpers.OptionConverter; +import org.apache.log4j.spi.LoggerRepository; import org.xml.sax.Attributes; -public class ConfigurationAction extends Action { +public class ConfigurationAction extends ActionBase { static final Logger logger = Logger.getLogger(ConfigurationAction.class); static final String INTERNAL_DEBUG_ATTR = "debug"; + boolean attachment = false; public void begin(ExecutionContext ec, String name, Attributes attributes) { String debugAttrib = attributes.getValue(INTERNAL_DEBUG_ATTR); - logger.debug("debug attribute= \"" + debugAttrib + "\"."); - if (debugAttrib == null || debugAttrib.equals("") || debugAttrib.equals("null")) { + + if ( + (debugAttrib == null) || debugAttrib.equals("") + || debugAttrib.equals("null")) { LogLog.debug("Ignoring " + INTERNAL_DEBUG_ATTR + " attribute."); } else { - LogLog.setInternalDebugging( - OptionConverter.toBoolean(debugAttrib, true)); + LoggerRepository repository = (LoggerRepository) ec.getObject(0); + attachTemporaryConsoleAppender(repository); + attachment = true; } - } + } + + protected void attachTemporaryConsoleAppender(LoggerRepository repository) { + Logger ll = repository.getLogger(Constants.LOG4J_PACKAGE_NAME); + + ConsoleAppender appender = new ConsoleAppender(); + appender.setLayout( + new PatternLayout("LOG4J-INTERNAL: %d %level [%t] %c - %m%n")); + appender.setName(Constants.TEMP_CONSOLE_APPENDER_NAME); + appender.activateOptions(); + ll.addAppender(appender); + } + + protected void detachTemporaryConsoleAppender(ExecutionContext ec) { + LoggerRepository repository = (LoggerRepository) ec.getObject(0); + Logger ll = repository.getLogger(Constants.LOG4J_PACKAGE_NAME); + ConsoleAppender consoleAppender = + (ConsoleAppender) ll.getAppender(Constants.TEMP_CONSOLE_APPENDER_NAME); + if (consoleAppender == null) { + String errMsg = + "Could not find appender " + Constants.TEMP_LIST_APPENDER_NAME; + getLogger(repository).error(errMsg); + ec.addError(new ErrorItem(errMsg)); + return; + } + consoleAppender.close(); + ll.removeAppender(consoleAppender); + } public void finish(ExecutionContext ec) { } public void end(ExecutionContext ec, String e) { + if (attachment) { + detachTemporaryConsoleAppender(ec); + } } } 1.1 logging-log4j/src/java/org/apache/log4j/joran/action/ActionBase.java Index: ActionBase.java =================================================================== /* * Copyright 1999,2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.log4j.joran.action; import org.apache.joran.action.Action; import org.apache.log4j.Logger; import org.apache.log4j.spi.LoggerRepository; /** * ActionBase extension [EMAIL PROTECTED] Action} by adding logging capabilities * * @author Ceki Gülcü * */ public abstract class ActionBase extends Action { Logger logger; Logger getLogger(LoggerRepository repository) { if (logger == null) { logger = repository.getLogger(this.getClass().getName()); } return logger; } } 1.15 +66 -2 logging-log4j/src/java/org/apache/log4j/joran/JoranConfigurator.java Index: JoranConfigurator.java =================================================================== RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/joran/JoranConfigurator.java,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- JoranConfigurator.java 31 May 2004 21:36:19 -0000 1.14 +++ JoranConfigurator.java 16 Nov 2004 20:29:44 -0000 1.15 @@ -35,8 +35,10 @@ import org.apache.joran.action.NewRuleAction; import org.apache.joran.action.ParamAction; import org.apache.joran.helper.SimpleRuleStore; +import org.apache.log4j.Appender; import org.apache.log4j.Logger; //import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.helpers.Constants; import org.apache.log4j.joran.action.ActionConst; import org.apache.log4j.joran.action.AppenderAction; import org.apache.log4j.joran.action.AppenderRefAction; @@ -52,6 +54,8 @@ import org.apache.log4j.joran.action.SubstitutionPropertyAction; import org.apache.log4j.spi.Configurator; import org.apache.log4j.spi.LoggerRepository; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.varia.ListAppender; import org.apache.log4j.xml.Log4jEntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -69,6 +73,7 @@ Interpreter joranInterpreter; LoggerRepository repository; + boolean listAppnderAttached = false; // The logger will be retreived form the logger repository being // configured @@ -104,7 +109,7 @@ FileInputStream fis = null; ExecutionContext ec = joranInterpreter.getExecutionContext(); - getLogger().info("in JoranConfigurator doConfigure "+filename); + //getLogger().info("in JoranConfigurator doConfigure {}", filename); try { fis = new FileInputStream(filename); doConfigure(fis, repository); @@ -139,6 +144,9 @@ ec.pushObject(repository); String errMsg; try { + attachListAppender(repository); + + getLogger().debug("Starting to parse configuration {}", inputSource); SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser saxParser = spf.newSAXParser(); @@ -149,6 +157,7 @@ inputSource.setSystemId("dummy://log4j.dtd"); saxParser.parse(inputSource, joranInterpreter); + getLogger().debug("Finished parsing."); } catch (SAXException e) { // all exceptions should have been recorded already. } catch (ParserConfigurationException pce) { @@ -158,6 +167,8 @@ } catch (IOException ie) { errMsg = "I/O error occured while parsing xml file"; ec.addError(new ErrorItem("Parser configuration error occured", ie)); + } finally { + detachListAppender(repository); } } @@ -210,10 +221,63 @@ Logger getLogger() { if(logger == null) { - logger = repository.getLogger(JoranConfigurator.class.getName()); + logger = repository.getLogger(this.getClass().getName()); } return logger; } + /** + * Attach a list appender which will be used to collect the logging events + * generated by log4j components, including this JoranConfigurator. These + * events will later be output when [EMAIL PROTECTED] #detachListAppender} method + * is called. + * + * @param repository + */ + protected void attachListAppender(LoggerRepository repository) { + Logger ll = repository.getLogger(Constants.LOG4J_PACKAGE_NAME); + Appender appender = new ListAppender(); + appender.setName(Constants.TEMP_LIST_APPENDER_NAME); + ll.addAppender(appender); + ll.setAdditivity(false); + } + + /** + * Output the previously collected events using the current log4j + * configuration. When that is completed, cluse and detach the + * ListAppender previously created by [EMAIL PROTECTED] #attachListAppender}. + * + * @param repository + */ + protected void detachListAppender(LoggerRepository repository) { + ExecutionContext ec = joranInterpreter.getExecutionContext(); + Logger ll = repository.getLogger(Constants.LOG4J_PACKAGE_NAME); + + // FIXME: What happens if the users wanted to set the additivity flag + // to false in the config file? We are now potentially overriding her + // wishes but I don't see any other way. + ll.setAdditivity(true); + + ListAppender listAppender = (ListAppender) ll.getAppender(Constants.TEMP_LIST_APPENDER_NAME); + if(listAppender == null) { + String errMsg = "Could not find appender "+Constants.TEMP_LIST_APPENDER_NAME; + getLogger().error(errMsg); + ec.addError(new ErrorItem(errMsg)); + return; + } + + List eventList = listAppender.getList(); + int size = eventList.size(); + for(int i = 0; i < size; i++) { + LoggingEvent event = (LoggingEvent) eventList.get(i); + Logger xLogger = event.getLogger(); + if (event.getLevel().isGreaterOrEqual(xLogger.getEffectiveLevel())) { + xLogger.callAppenders(event); + } + } + listAppender.clearModel(); + listAppender.close(); + ll.removeAppender(listAppender); + } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]