You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rp...@apache.org on 2014/09/26 17:14:40 UTC

git commit: LOG4J2-589 CustomLevel elements should be configured in a containing CustomLevels element.

Repository: logging-log4j2
Updated Branches:
  refs/heads/LOG4J2-589 bfbcc93b0 -> ba3feb233


LOG4J2-589 CustomLevel elements should be configured in a containing
CustomLevels element.

* Renamed CustomLevelPlugin to CustomLevelConfig
* Added method Configuration#getCustomLevels
* Added plugin CustomLevels to act as the CustomLevel container
* Updated manual page
* Updated schema

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/ba3feb23
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/ba3feb23
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/ba3feb23

Branch: refs/heads/LOG4J2-589
Commit: ba3feb23378ca23eadb9f2a7e3b6fd073ea7afe9
Parents: bfbcc93
Author: rpopma <rp...@apache.org>
Authored: Sat Sep 27 00:14:43 2014 +0900
Committer: rpopma <rp...@apache.org>
Committed: Sat Sep 27 00:14:43 2014 +0900

----------------------------------------------------------------------
 .../core/config/AbstractConfiguration.java      | 22 ++++-
 .../log4j/core/config/Configuration.java        | 30 +++++-
 .../log4j/core/config/CustomLevelConfig.java    | 99 ++++++++++++++++++++
 .../log4j/core/config/CustomLevelPlugin.java    | 51 ----------
 .../logging/log4j/core/config/CustomLevels.java | 59 ++++++++++++
 log4j-core/src/main/resources/Log4j-config.xsd  |  5 +-
 src/site/xdoc/manual/customloglevels.xml.vm     |  8 +-
 7 files changed, 211 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ba3feb23/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
index 325545b..fa5b4cb 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
@@ -98,6 +98,7 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement
     private String name;
     private ConcurrentMap<String, Appender> appenders = new ConcurrentHashMap<String, Appender>();
     private ConcurrentMap<String, LoggerConfig> loggers = new ConcurrentHashMap<String, LoggerConfig>();
+    private List<CustomLevelConfig> customLevels = Collections.emptyList();
     private final ConcurrentMap<String, String> properties = new ConcurrentHashMap<String, String>();
     private final StrLookup tempLookup = new Interpolator(properties);
     private final StrSubstitutor subst = new StrSubstitutor(tempLookup);
@@ -371,9 +372,12 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement
                     root = l.getRoot();
                     setRoot = true;
                 }
-            } else if (child.getObject() instanceof Level) {
-                // This else clause prevents the warning message below from being logged.
-                // Nothing to do: plugin already created the custom Level instance.
+            } else if (child.getName().equalsIgnoreCase("CustomLevels")) {
+                customLevels = ((CustomLevels) child.getObject()).getCustomLevels();
+            } else if (child.getObject() instanceof CustomLevelConfig) {
+                List<CustomLevelConfig> copy = new ArrayList<CustomLevelConfig>(customLevels);
+                copy.add((CustomLevelConfig) child.getObject());
+                customLevels = copy;
             } else {
                 LOGGER.error("Unknown object \"{}\" of type {} is ignored.", child.getName(),
                         child.getObject().getClass().getName());
@@ -605,6 +609,15 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement
             app.stop();
         }
     }
+    
+    /*
+     * (non-Javadoc)
+     * @see org.apache.logging.log4j.core.config.Configuration#getCustomLevels()
+     */
+    @Override
+    public List<CustomLevelConfig> getCustomLevels() {
+        return Collections.unmodifiableList(customLevels);
+    }
 
     /**
      * Locates the appropriate LoggerConfig for a Logger name. This will remove tokens from the
@@ -732,8 +745,7 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement
     * @see org.apache.logging.log4j.core.config.plugins.visitors.PluginVisitor
     * @see org.apache.logging.log4j.core.config.plugins.convert.TypeConverter
     */
-    private <T> Object createPluginObject(final PluginType<T> type, final Node node, final LogEvent event)
-    {
+    private <T> Object createPluginObject(final PluginType<T> type, final Node node, final LogEvent event) {
         final Class<T> clazz = type.getPluginClass();
 
         if (Map.class.isAssignableFrom(clazz)) {

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ba3feb23/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configuration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configuration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configuration.java
index ae2e99f..beacbb3 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configuration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configuration.java
@@ -16,6 +16,7 @@
  */
 package org.apache.logging.log4j.core.config;
 
+import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.LogEvent;
@@ -37,13 +38,15 @@ public interface Configuration extends Filterable {
 
     /**
      * Returns the configuration name.
+     * 
      * @return the name of the configuration.
      */
     String getName();
 
     /**
-     * Locates the appropriate LoggerConfig for a Logger name. This will remove tokens from the
-     * package name as necessary or return the root LoggerConfig if no other matches were found.
+     * Locates the appropriate LoggerConfig for a Logger name. This will remove tokens from the package name as
+     * necessary or return the root LoggerConfig if no other matches were found.
+     * 
      * @param name The Logger name.
      * @return The located LoggerConfig.
      */
@@ -51,6 +54,7 @@ public interface Configuration extends Filterable {
 
     /**
      * Returns the Appender with the specified name.
+     * 
      * @param name The name of the Appender.
      * @return the Appender with the specified name or null if the Appender cannot be located.
      */
@@ -58,6 +62,7 @@ public interface Configuration extends Filterable {
 
     /**
      * Returns a Map containing all the Appenders and their name.
+     * 
      * @return A Map containing each Appender's name and the Appender object.
      */
     Map<String, Appender> getAppenders();
@@ -107,10 +112,29 @@ public interface Configuration extends Filterable {
     Advertiser getAdvertiser();
 
     boolean isShutdownHookEnabled();
-    
+
     /**
      * Returns the source of this configuration.
+     * 
      * @return the source of this configuration
      */
     ConfigurationSource getConfigurationSource();
+
+    /**
+     * <p>
+     * Returns a list of descriptors of the custom levels defined in the current configuration. The returned list does
+     * <em>not</em> include custom levels that are defined in code with direct calls to {@link Level.forName}.
+     * </p>
+     * <p>
+     * Note that the list does not include levels of previous configurations. For example, suppose a configuration
+     * contains custom levels A, B and C. The configuration is then modified to contain custom levels B, C and D. For
+     * the new configuration, this method will return only {B, C, D}, that is, only the custom levels defined in
+     * <em>this</em> configuration. The previously defined level A still exists (and can be obtained with
+     * {@link Level#getLevel(String)}), it is just not in the current configuration. {@link Level#values()} will return
+     * {A, B, C, D and the built-in levels}.
+     * </p>
+     * 
+     * @return the custom levels defined in the current configuration
+     */
+    List<CustomLevelConfig> getCustomLevels();
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ba3feb23/log4j-core/src/main/java/org/apache/logging/log4j/core/config/CustomLevelConfig.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/CustomLevelConfig.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/CustomLevelConfig.java
new file mode 100644
index 0000000..24e772a
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/CustomLevelConfig.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.core.config;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.core.util.Assert;
+import org.apache.logging.log4j.status.StatusLogger;
+
+/**
+ * Descriptor of a custom Level object that is created via configuration.
+ */
+@Plugin(name = "CustomLevel", category = "Core", printObject = true)
+public final class CustomLevelConfig {
+
+    private final String levelName;
+    private final int intLevel;
+
+    private CustomLevelConfig(final String levelName, final int intLevel) {
+        this.levelName = Assert.requireNonNull(levelName, "levelName is null");
+        this.intLevel = intLevel;
+    }
+
+    /**
+     * Creates a CustomLevelConfig object. This also defines the Level object with a call to
+     * {@link Level#forName(String, int)}.
+     * 
+     * @param levelName name of the custom level.
+     * @param intLevel the intLevel that determines where this level resides relative to the built-in levels
+     * @return A CustomLevelConfig object.
+     */
+    @PluginFactory
+    public static CustomLevelConfig createLevel(// @formatter:off
+            @PluginAttribute("name") final String levelName,
+            @PluginAttribute("intLevel") final int intLevel) {
+        // @formatter:on
+
+        StatusLogger.getLogger().debug("Creating CustomLevel(name='{}', intValue={})", levelName, intLevel);
+        Level.forName(levelName, intLevel);
+        return new CustomLevelConfig(levelName, intLevel);
+    }
+
+    /**
+     * Returns the custom level name.
+     * 
+     * @return the custom level name
+     */
+    public String getLevelName() {
+        return levelName;
+    }
+
+    /**
+     * Returns the custom level intLevel that determines the strength of the custom level relative to the built-in
+     * levels.
+     * 
+     * @return the custom level intLevel
+     */
+    public int getIntLevel() {
+        return intLevel;
+    }
+
+    @Override
+    public int hashCode() {
+        return intLevel ^ levelName.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (!(object instanceof CustomLevelConfig)) {
+            return false;
+        }
+        CustomLevelConfig other = (CustomLevelConfig) object;
+        return this.intLevel == other.intLevel && this.levelName.equals(other.levelName);
+    }
+
+    @Override
+    public String toString() {
+        return "CustomLevel[name=" + levelName + ", intLevel=" + intLevel + "]";
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ba3feb23/log4j-core/src/main/java/org/apache/logging/log4j/core/config/CustomLevelPlugin.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/CustomLevelPlugin.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/CustomLevelPlugin.java
deleted file mode 100644
index 532e811..0000000
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/CustomLevelPlugin.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.logging.log4j.core.config;
-
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.core.config.plugins.Plugin;
-import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
-import org.apache.logging.log4j.core.config.plugins.PluginFactory;
-import org.apache.logging.log4j.status.StatusLogger;
-
-/**
- * Custom Level object that is created via configuration.
- */
-@Plugin(name = "CustomLevel", category = "Core", printObject = true)
-public final class CustomLevelPlugin {
-
-    private CustomLevelPlugin() {
-    }
-
-    /**
-     * Creates a custom Level object.
-     * 
-     * @param levelName name of the custom level.
-     * @param intLevel the intLevel that determines where this level resides relative to the built-in levels
-     * @return A Level object.
-     */
-    @PluginFactory
-    public static Level createLevel(// @formatter:off
-            @PluginAttribute("name") final String levelName,
-            @PluginAttribute("intLevel") final int intLevel) {
-        // @formatter:on
-
-        StatusLogger.getLogger().debug("Creating CustomLevel(name='{}', intValue={})", levelName, intLevel);
-        Level result = Level.forName(levelName, intLevel);
-        return result;
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ba3feb23/log4j-core/src/main/java/org/apache/logging/log4j/core/config/CustomLevels.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/CustomLevels.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/CustomLevels.java
new file mode 100644
index 0000000..440aef3
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/CustomLevels.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging.log4j.core.config;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+
+/**
+ * Container for CustomLevelConfig objects.
+ */
+@Plugin(name = "CustomLevels", category = "Core", printObject = true)
+public final class CustomLevels {
+
+    private final List<CustomLevelConfig> customLevels;
+
+    private CustomLevels(final CustomLevelConfig[] customLevels) {
+        this.customLevels = new ArrayList<CustomLevelConfig>(Arrays.asList(customLevels));
+    }
+
+    /**
+     * Create a CustomLevels object to contain all the CustomLevelConfigs.
+     * 
+     * @param customLevels An array of CustomLevelConfigs.
+     * @return A CustomLevels object.
+     */
+    @PluginFactory
+    public static CustomLevels createCustomLevels(//
+            @PluginElement("CustomLevels") final CustomLevelConfig[] customLevels) {
+        return new CustomLevels(customLevels == null ? new CustomLevelConfig[0] : customLevels);
+    }
+
+    /**
+     * Returns a list of the {@code CustomLevelConfig} objects created during configuration.
+     * @return the configured custom levels
+     */
+    public List<CustomLevelConfig> getCustomLevels() {
+        return customLevels;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ba3feb23/log4j-core/src/main/resources/Log4j-config.xsd
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/resources/Log4j-config.xsd b/log4j-core/src/main/resources/Log4j-config.xsd
index 20c1500..8f492d1 100644
--- a/log4j-core/src/main/resources/Log4j-config.xsd
+++ b/log4j-core/src/main/resources/Log4j-config.xsd
@@ -20,7 +20,10 @@
     <xs:element name="Configuration" type="ConfigurationType"/>
     <xs:complexType name="ConfigurationType">
         <xs:sequence>
-            <xs:element name="CustomLevel" type="CustomLevelType"/>
+            <xs:choice minOccurs="0" maxOccurs="1">
+                <xs:element name="CustomLevels" type="CustomLevelsType"/>
+                <xs:element name="CustomLevel" type="CustomLevelType"/>
+            </xs:choice>
             <xs:element name="Properties" type="PropertiesType"/>
             <xs:choice minOccurs="0" maxOccurs="1">
                 <xs:element name="Filters" type="FiltersType"/>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ba3feb23/src/site/xdoc/manual/customloglevels.xml.vm
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/customloglevels.xml.vm b/src/site/xdoc/manual/customloglevels.xml.vm
index cdb0108..09c1121 100644
--- a/src/site/xdoc/manual/customloglevels.xml.vm
+++ b/src/site/xdoc/manual/customloglevels.xml.vm
@@ -140,9 +140,11 @@ logger.log(Level.getLevel("FORGOT_TO_DEFINE"), "some message"); // throws except
 <?xml version="1.0" encoding="UTF-8"?>
 <Configuration status="WARN">
   <!-- Define custom levels before using them for filtering below. -->
-  <CustomLevel name="DIAG" intLevel="350" />
-  <CustomLevel name="NOTICE" intLevel="450" />
-  <CustomLevel name="VERBOSE" intLevel="550" />
+  <CustomLevels>
+    <CustomLevel name="DIAG" intLevel="350" />
+    <CustomLevel name="NOTICE" intLevel="450" />
+    <CustomLevel name="VERBOSE" intLevel="550" />
+  </CustomLevels>
   
   <Appenders>
     <Console name="Console" target="SYSTEM_OUT">