diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/BasicConfigurator.java b/logback-classic/src/main/java/ch/qos/logback/classic/BasicConfigurator.java index 3b972dde51..2a1830a545 100644 --- a/logback-classic/src/main/java/ch/qos/logback/classic/BasicConfigurator.java +++ b/logback-classic/src/main/java/ch/qos/logback/classic/BasicConfigurator.java @@ -29,7 +29,7 @@ * * @author Ceki Gülcü */ -@ConfiguratorRank(value = ConfiguratorRank.Value.FALLBACK) +@ConfiguratorRank(value = ConfiguratorRank.FALLBACK) public class BasicConfigurator extends ContextAwareBase implements Configurator { public BasicConfigurator() { diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/ClassicConstants.java b/logback-classic/src/main/java/ch/qos/logback/classic/ClassicConstants.java index 4551deb78f..2765b78a30 100644 --- a/logback-classic/src/main/java/ch/qos/logback/classic/ClassicConstants.java +++ b/logback-classic/src/main/java/ch/qos/logback/classic/ClassicConstants.java @@ -28,7 +28,7 @@ public class ClassicConstants { * property name for the model file used for configuration * @since 1.3.9/1.4.9 */ - public static final String MODEL_CONFIG_FILE_PROPERTY = "logback.modelFile"; + public static final String MODEL_CONFIG_FILE_PROPERTY = "logback.serializedModelFilew"; public static final String JNDI_CONFIGURATION_RESOURCE = JNDI_JAVA_NAMESPACE + "comp/env/logback/configuration-resource"; diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/joran/SerializedModelConfigurator.java b/logback-classic/src/main/java/ch/qos/logback/classic/joran/SerializedModelConfigurator.java index 5f226c0085..388cb87e4e 100644 --- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/SerializedModelConfigurator.java +++ b/logback-classic/src/main/java/ch/qos/logback/classic/joran/SerializedModelConfigurator.java @@ -17,6 +17,7 @@ import ch.qos.logback.classic.ClassicConstants; import ch.qos.logback.classic.joran.serializedModel.HardenedModelInputStream; import ch.qos.logback.classic.model.processor.LogbackClassicDefaultNestedComponentRules; +import ch.qos.logback.classic.spi.ConfiguratorRank; import ch.qos.logback.core.Context; import ch.qos.logback.core.LogbackException; import ch.qos.logback.core.model.Model; @@ -43,6 +44,7 @@ */ // BEWARE: the fqcn is used in SerializedModelModelHandler +@ConfiguratorRank(value = ConfiguratorRank.SERIALIZED_MODEL) public class SerializedModelConfigurator extends ContextAwareBase implements Configurator { final public static String AUTOCONFIG_MODEL_FILE = "logback"+ MODEL_CONFIG_FILE_EXTENSION; diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/model/processor/ConfigurationModelHandler.java b/logback-classic/src/main/java/ch/qos/logback/classic/model/processor/ConfigurationModelHandler.java index ee2588244b..bb5edb1942 100755 --- a/logback-classic/src/main/java/ch/qos/logback/classic/model/processor/ConfigurationModelHandler.java +++ b/logback-classic/src/main/java/ch/qos/logback/classic/model/processor/ConfigurationModelHandler.java @@ -86,7 +86,6 @@ public void handle(ModelInterpretationContext mic, Model model) { } protected void processScanAttrib(ModelInterpretationContext mic, ConfigurationModel configurationModel) { - System.out.println("This is overriden processScanAttrib"); String scanStr = mic.subst(configurationModel.getScanStr()); if (!OptionHelper.isNullOrEmpty(scanStr) && !"false".equalsIgnoreCase(scanStr)) { addInfo("Skipping ReconfigureOnChangeTask registration"); diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/ConfiguratorRank.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/ConfiguratorRank.java index 82b623426a..8cf7485ffe 100644 --- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/ConfiguratorRank.java +++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/ConfiguratorRank.java @@ -24,12 +24,19 @@ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface ConfiguratorRank { - enum Value { - FIRST, - REGULAR, - FALLBACK; - } - Value value() default Value.REGULAR; + static public int FALLBACK = -10; + static public int NOMINAL = 0; + static public int SERIALIZED_MODEL = 10; + static public int DEFAULT = 20; + + static public int CUSTOM_LOW_PRIORITY = DEFAULT; + + static public int CUSTOM_NORMAL_PRIORITY = 30; + + static public int CUSTOM_HIGH_PRIORITY = 40; + + static public int CUSTOM_TOP_PRIORITY = 50; + public int value() default DEFAULT; } diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextInitializer.java b/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextInitializer.java index 3b960ce55e..86b66520af 100644 --- a/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextInitializer.java +++ b/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextInitializer.java @@ -43,8 +43,6 @@ public class ContextInitializer { * @deprecated Please use ClassicConstants.CONFIG_FILE_PROPERTY instead */ final public static String CONFIG_FILE_PROPERTY = ClassicConstants.CONFIG_FILE_PROPERTY; - private static final String JORAN_CONFIGURATION_DURATION_MSG = "JoranConfiguration duration "; - private static final String CONFIGURATION_AS_A_SERVICE_DURATION_MSG = "Configuration as a service duration "; final LoggerContext loggerContext; @@ -67,18 +65,21 @@ public void autoConfig(ClassLoader classLoader) throws JoranException { loggerContext.getStatusManager().add(new InfoStatus(CoreConstants.LOGBACK_CLASSIC_VERSION_MESSAGE + versionStr, loggerContext)); StatusListenerConfigHelper.installIfAsked(loggerContext); - long startConfigurationAsAService = System.currentTimeMillis(); + List configuratorList = ClassicEnvUtil.loadFromServiceLoader(Configurator.class, classLoader); configuratorList.sort(rankComparator); + printConfiguratorOrder(configuratorList); + for (Configurator c : configuratorList) { try { + long start = System.currentTimeMillis(); contextAware.addInfo("Constructed configurator of type " + c.getClass()); c.setContext(loggerContext); Configurator.ExecutionStatus status = c.configure(loggerContext); + printDuration(start, c, status); if (status == Configurator.ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY) { - printDuration(startConfigurationAsAService, CONFIGURATION_AS_A_SERVICE_DURATION_MSG, true); return; } } catch (Exception e) { @@ -87,25 +88,33 @@ public void autoConfig(ClassLoader classLoader) throws JoranException { } } - printDuration(startConfigurationAsAService, CONFIGURATION_AS_A_SERVICE_DURATION_MSG, false); - long startJoranConfiguration = System.currentTimeMillis(); - Configurator.ExecutionStatus es = attemptConfigurationUsingJoranUsingReflexion(classLoader); - if (es == Configurator.ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY) { - printDuration(startJoranConfiguration, JORAN_CONFIGURATION_DURATION_MSG, true); - return; - } - printDuration(startJoranConfiguration, JORAN_CONFIGURATION_DURATION_MSG, false); +// long startJoranConfiguration = System.currentTimeMillis(); +// Configurator.ExecutionStatus es = attemptConfigurationUsingJoranUsingReflexion(classLoader); +// +// if (es == Configurator.ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY) { +// printDuration(startJoranConfiguration, JORAN_CONFIGURATION_DURATION_MSG, true); +// return; +// } +// printDuration(startJoranConfiguration, JORAN_CONFIGURATION_DURATION_MSG, false); +// +// // at this stage invoke basicConfigurator +// fallbackOnToBasicConfigurator(); + } - // at this stage invoke basicConfigurator - fallbackOnToBasicConfigurator(); + private void printConfiguratorOrder(List configuratorList) { + contextAware.addInfo("Here is a list of configurators discovered as a service, by rank: "); + for(Configurator c: configuratorList) { + contextAware.addInfo(" "+c.getClass().getName()); + } + contextAware.addInfo("They will be invoked in order until ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY is returned."); } - private void printDuration(long start, String message, boolean success) { + private void printDuration(long start, Configurator configurator, Configurator.ExecutionStatus executionStatus) { long end = System.currentTimeMillis(); - long configurationAsAServiceDuration = end - start; - contextAware.addInfo(message+configurationAsAServiceDuration + " milliseconds. Success status="+success); + long diff = end - start; + contextAware.addInfo( configurator.getClass().getName()+".configure() call lasted "+diff + " milliseconds. ExecutionStatus="+executionStatus); } private Configurator.ExecutionStatus attemptConfigurationUsingJoranUsingReflexion(ClassLoader classLoader) { @@ -128,21 +137,6 @@ private void fallbackOnToBasicConfigurator() { basicConfigurator.configure(loggerContext); } - // private void sortByPriority(List configuratorList) { - // configuratorList.sort(new Comparator() { - // @Override - // public int compare(Configurator o1, Configurator o2) { - // if (o1.getClass() == o2.getClass()) - // return 0; - // if (o1 instanceof DefaultJoranConfigurator) { - // return 1; - // } - // - // // otherwise do not intervene - // return 0; - // } - // }); - // } Comparator rankComparator = new Comparator() { @Override @@ -151,8 +145,8 @@ public int compare(Configurator c1, Configurator c2) { ConfiguratorRank r1 = c1.getClass().getAnnotation(ConfiguratorRank.class); ConfiguratorRank r2 = c2.getClass().getAnnotation(ConfiguratorRank.class); - ConfiguratorRank.Value value1 = r1 == null ? ConfiguratorRank.Value.REGULAR : r1.value(); - ConfiguratorRank.Value value2 = r2 == null ? ConfiguratorRank.Value.REGULAR : r2.value(); + int value1 = r1 == null ? ConfiguratorRank.DEFAULT : r1.value(); + int value2 = r2 == null ? ConfiguratorRank.DEFAULT : r2.value(); int result = compareRankValue(value1, value2); // reverse the result for high to low sort @@ -160,30 +154,12 @@ public int compare(Configurator c1, Configurator c2) { } }; - private int compareRankValue(ConfiguratorRank.Value value1, ConfiguratorRank.Value value2) { - - switch (value1) { - case FIRST: - if (value2 == ConfiguratorRank.Value.FIRST) - return 0; - else - return 1; - case REGULAR: - if (value2 == ConfiguratorRank.Value.FALLBACK) - return 1; - else if (value2 == ConfiguratorRank.Value.REGULAR) - return 0; - else - return -1; - case FALLBACK: - if (value2 == ConfiguratorRank.Value.FALLBACK) - return 0; - else - return -1; - - default: + private int compareRankValue(int value1, int value2) { + if(value1 > value2) + return 1; + else if (value1 == value2) return 0; - } + else return -1; } } diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/util/DefaultJoranConfigurator.java b/logback-classic/src/main/java/ch/qos/logback/classic/util/DefaultJoranConfigurator.java index f31861711e..b1cbe37cbc 100644 --- a/logback-classic/src/main/java/ch/qos/logback/classic/util/DefaultJoranConfigurator.java +++ b/logback-classic/src/main/java/ch/qos/logback/classic/util/DefaultJoranConfigurator.java @@ -22,7 +22,9 @@ /** * @since 1.3.0-beta1 */ -@ConfiguratorRank(value = ConfiguratorRank.Value.REGULAR) +// Note that DefaultJoranConfigurator is invoked via reflection + + @ConfiguratorRank(value = ConfiguratorRank.NOMINAL) public class DefaultJoranConfigurator extends ContextAwareBase implements Configurator { final public static String AUTOCONFIG_FILE = "logback.xml"; @@ -37,7 +39,7 @@ public ExecutionStatus configure(Context context) { } catch (JoranException e) { e.printStackTrace(); } - // we tried and that counts Mary. + // You tried and that counts Mary. return ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY; } else { return ExecutionStatus.INVOKE_NEXT_IF_ANY; diff --git a/logback-classic/src/main/resources/META-INF/services/ch.qos.logback.core.spi.Configurator b/logback-classic/src/main/resources/META-INF/services/ch.qos.logback.core.spi.Configurator index 1b6c66cee2..d1c8bb88be 100644 --- a/logback-classic/src/main/resources/META-INF/services/ch.qos.logback.core.spi.Configurator +++ b/logback-classic/src/main/resources/META-INF/services/ch.qos.logback.core.spi.Configurator @@ -1 +1,9 @@ -ch.qos.logback.classic.joran.SerializedModelConfigurator \ No newline at end of file +# Configurators are invoked according to their rank, highest rank is invoked first +# SerializedModelConfigurator has rank 10 +# DefaultJoranConfigurator has rank 0 (NOMINAL) +# BasicConfigurator has rank -10 (FALLBACK) +# +ch.qos.logback.classic.joran.SerializedModelConfigurator +ch.qos.logback.classic.util.DefaultJoranConfigurator +ch.qos.logback.classic.BasicConfigurator + diff --git a/logback-classic/src/test/input/joran/model/minimal.xml b/logback-classic/src/test/input/joran/model/minimal.xml index 387c56d3a6..945e4c8924 100644 --- a/logback-classic/src/test/input/joran/model/minimal.xml +++ b/logback-classic/src/test/input/joran/model/minimal.xml @@ -3,7 +3,7 @@ - + diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/joran/JoranConfiguratorTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/joran/JoranConfiguratorTest.java index cc6f7a475a..b16c191389 100644 --- a/logback-classic/src/test/java/ch/qos/logback/classic/joran/JoranConfiguratorTest.java +++ b/logback-classic/src/test/java/ch/qos/logback/classic/joran/JoranConfiguratorTest.java @@ -14,6 +14,7 @@ package ch.qos.logback.classic.joran; import ch.qos.logback.classic.AsyncAppender; +import ch.qos.logback.classic.ClassicConstants; import ch.qos.logback.classic.ClassicTestConstants; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; @@ -728,7 +729,7 @@ public void dateConverterWithLocale() throws JoranException { public void modelSerialization() throws JoranException, IOException, ClassNotFoundException { String outputPath = OUTPUT_DIR_PREFIX+"minimal_"+diff+ MODEL_CONFIG_FILE_EXTENSION; - loggerContext.putProperty("target.smo", outputPath); + loggerContext.putProperty("targetModelFile", outputPath); configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "model/minimal.xml"); StatusPrinter.print(loggerContext); @@ -747,13 +748,13 @@ public void modelSerialization() throws JoranException, IOException, ClassNotFou assertEquals(2, configurationModel.getSubModels().size()); SerializeModelModel smm = (SerializeModelModel) configurationModel.getSubModels().get(0); - assertEquals("${target.smo}", smm.getFile()); + assertEquals("${targetModelFile}", smm.getFile()); LoggerModel loggerModel = (LoggerModel) configurationModel.getSubModels().get(1); assertEquals("ModelSerializationTest", loggerModel.getName()); - // + // // diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/util/MockConfigurator.java b/logback-classic/src/test/java/ch/qos/logback/classic/util/MockConfigurator.java index 034ea6ad4e..23bd246c18 100644 --- a/logback-classic/src/test/java/ch/qos/logback/classic/util/MockConfigurator.java +++ b/logback-classic/src/test/java/ch/qos/logback/classic/util/MockConfigurator.java @@ -18,7 +18,7 @@ import ch.qos.logback.core.Context; import ch.qos.logback.core.spi.ContextAwareBase; -@ConfiguratorRank(ConfiguratorRank.Value.REGULAR) +@ConfiguratorRank(ConfiguratorRank.CUSTOM_LOW_PRIORITY) public class MockConfigurator extends ContextAwareBase implements Configurator { static Context context = null; diff --git a/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java b/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java index fe3db797ae..6a1114f641 100644 --- a/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java +++ b/logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java @@ -227,5 +227,5 @@ public class CoreConstants { public static final String LOGBACK_CLASSIC_VERSION_MESSAGE = "This is logback-classic version "; public static final char JSON_LINE_SEPARATOR = '\n'; - final public static String MODEL_CONFIG_FILE_EXTENSION = ".smo"; + final public static String MODEL_CONFIG_FILE_EXTENSION = ".scmo"; } diff --git a/logback-core/src/main/java/ch/qos/logback/core/model/processor/SerializeModelModelHandler.java b/logback-core/src/main/java/ch/qos/logback/core/model/processor/SerializeModelModelHandler.java index 107e17f1b0..93a1bee336 100644 --- a/logback-core/src/main/java/ch/qos/logback/core/model/processor/SerializeModelModelHandler.java +++ b/logback-core/src/main/java/ch/qos/logback/core/model/processor/SerializeModelModelHandler.java @@ -45,7 +45,7 @@ public void handle(ModelInterpretationContext modelInterpretationContext, Model Object configuratorHint = modelInterpretationContext.getConfiguratorHint(); if(configuratorHint != null && configuratorHint.getClass().getName().equals("ch.qos.logback.classic.joran.SerializedModelConfigurator")) { - addInfo("Skipping model serialization as calling configurator is model based."); + addInfo("Skipping model serialization as calling configurator is already model based."); return; }