Repository: logging-log4j2
Updated Branches:
  refs/heads/master 3ea82560e -> 6ce7867d7


[LOG4J2-2321] AsyncLogger uses the parent level when unspecified

AsyncLoggerConfig is parsed the same way as LoggerConfig.
When level is not specified on an AsyncLogger it is inherited from
the parent rather than set to ERROR, this provides parity with
the standard LoggerConfig.


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

Branch: refs/heads/master
Commit: 6ce7867d746e883a7e9f9f9a585df0b5ffaea001
Parents: 3ea8256
Author: Carter Kozak <cko...@apache.org>
Authored: Thu Apr 19 00:15:39 2018 -0400
Committer: Carter Kozak <cko...@apache.org>
Committed: Thu Apr 19 23:29:36 2018 -0400

----------------------------------------------------------------------
 .../log4j/core/async/AsyncLoggerConfig.java     | 96 +++++++++++++++-----
 .../core/config/NestedLoggerConfigTest.java     | 92 +++++++++++++++++++
 .../AsyncLoggerConfig/default-level.xml         | 12 +++
 .../AsyncLoggerConfig/inherit-level.xml         | 12 +++
 .../LoggerConfig/default-level.xml              | 12 +++
 .../LoggerConfig/inherit-level.xml              | 12 +++
 src/changes/changes.xml                         |  3 +
 7 files changed, 215 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6ce7867d/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfig.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfig.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfig.java
index 84ef572..8a68ed0 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfig.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfig.java
@@ -35,10 +35,9 @@ import 
org.apache.logging.log4j.core.config.plugins.PluginAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
-import org.apache.logging.log4j.core.impl.Log4jLogEvent;
+import 
org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
 import org.apache.logging.log4j.core.jmx.RingBufferAdmin;
 import org.apache.logging.log4j.core.util.Booleans;
-import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.spi.AbstractLogger;
 import org.apache.logging.log4j.util.Strings;
 
@@ -171,17 +170,18 @@ public class AsyncLoggerConfig extends LoggerConfig {
      * @param config The Configuration.
      * @param filter A Filter.
      * @return A new LoggerConfig.
+     * @deprecated use {@link #createLogger(boolean, Level, String, String, 
AppenderRef[], Property[], Configuration, Filter)}
      */
-    @PluginFactory
+    @Deprecated
     public static LoggerConfig createLogger(
-            @PluginAttribute("additivity") final String additivity,
-            @PluginAttribute("level") final String levelName,
-            @PluginAttribute("name") final String loggerName,
-            @PluginAttribute("includeLocation") final String includeLocation,
-            @PluginElement("AppenderRef") final AppenderRef[] refs,
-            @PluginElement("Properties") final Property[] properties,
-            @PluginConfiguration final Configuration config,
-            @PluginElement("Filter") final Filter filter) {
+            final String additivity,
+            final String levelName,
+            final String loggerName,
+            final String includeLocation,
+            final AppenderRef[] refs,
+            final Property[] properties,
+            final Configuration config,
+            final Filter filter) {
         if (loggerName == null) {
             LOGGER.error("Loggers cannot be configured without a name");
             return null;
@@ -204,6 +204,35 @@ public class AsyncLoggerConfig extends LoggerConfig {
                 additive, properties, config, 
includeLocation(includeLocation));
     }
 
+    /**
+     * Factory method to create a LoggerConfig.
+     *
+     * @param additivity True if additive, false otherwise.
+     * @param level The Level to be associated with the Logger.
+     * @param loggerName The name of the Logger.
+     * @param includeLocation "true" if location should be passed downstream
+     * @param refs An array of Appender names.
+     * @param properties Properties to pass to the Logger.
+     * @param config The Configuration.
+     * @param filter A Filter.
+     * @return A new LoggerConfig.
+     * @since 3.0
+     */
+    @PluginFactory
+    public static LoggerConfig createLogger(
+            @PluginAttribute(value = "additivity", defaultBoolean = true) 
final boolean additivity,
+            @PluginAttribute("level") final Level level,
+            @Required(message = "Loggers cannot be configured without a name") 
@PluginAttribute("name") final String loggerName,
+            @PluginAttribute("includeLocation") final String includeLocation,
+            @PluginElement("AppenderRef") final AppenderRef[] refs,
+            @PluginElement("Properties") final Property[] properties,
+            @PluginConfiguration final Configuration config,
+            @PluginElement("Filter") final Filter filter) {
+        final String name = loggerName.equals(ROOT) ? Strings.EMPTY : 
loggerName;
+        return new AsyncLoggerConfig(name, Arrays.asList(refs), filter, level, 
additivity, properties, config,
+                includeLocation(includeLocation));
+    }
+
     // Note: for asynchronous loggers, includeLocation default is FALSE
     protected static boolean includeLocation(final String 
includeLocationConfigValue) {
         return Boolean.parseBoolean(includeLocationConfigValue);
@@ -215,30 +244,49 @@ public class AsyncLoggerConfig extends LoggerConfig {
     @Plugin(name = "asyncRoot", category = Core.CATEGORY_NAME, printObject = 
true)
     public static class RootLogger extends LoggerConfig {
 
-        @PluginFactory
+        /**
+         * @deprecated use {@link #createLogger(String, Level, String, 
AppenderRef[], Property[], Configuration, Filter)}
+         */
+        @Deprecated
         public static LoggerConfig createLogger(
-                @PluginAttribute("additivity") final String additivity,
-                @PluginAttribute("level") final String levelName,
-                @PluginAttribute("includeLocation") final String 
includeLocation,
-                @PluginElement("AppenderRef") final AppenderRef[] refs,
-                @PluginElement("Properties") final Property[] properties,
-                @PluginConfiguration final Configuration config,
-                @PluginElement("Filter") final Filter filter) {
+                final String additivity,
+                final String levelName,
+                final String includeLocation,
+                final AppenderRef[] refs,
+                final Property[] properties,
+                final Configuration config,
+                final Filter filter) {
             final List<AppenderRef> appenderRefs = Arrays.asList(refs);
-            Level level;
+            Level level = null;
             try {
                 level = Level.toLevel(levelName, Level.ERROR);
             } catch (final Exception ex) {
-                LOGGER.error(
-                        "Invalid Log level specified: {}. Defaulting to Error",
-                        levelName);
+                LOGGER.error("Invalid Log level specified: {}. Defaulting to 
Error", levelName);
                 level = Level.ERROR;
             }
             final boolean additive = Booleans.parseBoolean(additivity, true);
-
             return new AsyncLoggerConfig(LogManager.ROOT_LOGGER_NAME,
                     appenderRefs, filter, level, additive, properties, config,
                     AsyncLoggerConfig.includeLocation(includeLocation));
         }
+
+        /**
+         * @since 3.0
+         */
+        @PluginFactory
+        public static LoggerConfig createLogger(
+                @PluginAttribute("additivity") final String additivity,
+                @PluginAttribute("level") final Level level,
+                @PluginAttribute("includeLocation") final String 
includeLocation,
+                @PluginElement("AppenderRef") final AppenderRef[] refs,
+                @PluginElement("Properties") final Property[] properties,
+                @PluginConfiguration final Configuration config,
+                @PluginElement("Filter") final Filter filter) {
+            final List<AppenderRef> appenderRefs = Arrays.asList(refs);
+            final Level actualLevel = level == null ? Level.ERROR : level;
+            final boolean additive = Booleans.parseBoolean(additivity, true);
+            return new AsyncLoggerConfig(LogManager.ROOT_LOGGER_NAME, 
appenderRefs, filter, actualLevel, additive,
+                    properties, config, 
AsyncLoggerConfig.includeLocation(includeLocation));
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6ce7867d/log4j-core/src/test/java/org/apache/logging/log4j/core/config/NestedLoggerConfigTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/NestedLoggerConfigTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/NestedLoggerConfigTest.java
new file mode 100644
index 0000000..bbc9837
--- /dev/null
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/NestedLoggerConfigTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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 com.google.common.collect.ImmutableList;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.xml.XmlConfiguration;
+import org.apache.logging.log4j.core.impl.Log4jLogEvent.Builder;
+import org.apache.logging.log4j.core.impl.LogEventFactory;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.SimpleMessage;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Path;
+import java.util.HashSet;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
+/**
+ * Tests for LoggerConfig hierarchies.
+ */
+@RunWith(Parameterized.class)
+public class NestedLoggerConfigTest {
+
+    @Parameterized.Parameters(name = "{0}")
+    public static List<String> data() throws IOException {
+        return ImmutableList.of("logger-config/LoggerConfig/", 
"logger-config/AsyncLoggerConfig/");
+    }
+
+    private final String prefix;
+
+    public NestedLoggerConfigTest(String prefix) {
+        this.prefix = prefix;
+    }
+
+    @Test
+    public void testInheritParentDefaultLevel() throws IOException {
+        Configuration configuration = loadConfiguration(prefix + 
"default-level.xml");
+        try {
+            assertEquals(Level.ERROR, 
configuration.getLoggerConfig("com.foo").getLevel());
+        } finally {
+            configuration.stop();
+        }
+    }
+
+    @Test
+    public void testInheritParentLevel() throws IOException {
+        Configuration configuration = loadConfiguration(prefix + 
"inherit-level.xml");
+        try {
+            assertEquals(Level.TRACE, 
configuration.getLoggerConfig("com.foo").getLevel());
+        } finally {
+            configuration.stop();
+        }
+    }
+
+    private Configuration loadConfiguration(String resourcePath) throws 
IOException {
+        InputStream in = 
getClass().getClassLoader().getResourceAsStream(resourcePath);
+        try {
+            Configuration configuration = new XmlConfiguration(new 
LoggerContext("test"), new ConfigurationSource(in));
+            configuration.initialize();
+            configuration.start();
+            return configuration;
+        } finally {
+            in.close();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6ce7867d/log4j-core/src/test/resources/logger-config/AsyncLoggerConfig/default-level.xml
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/resources/logger-config/AsyncLoggerConfig/default-level.xml
 
b/log4j-core/src/test/resources/logger-config/AsyncLoggerConfig/default-level.xml
new file mode 100644
index 0000000..d99c7c1
--- /dev/null
+++ 
b/log4j-core/src/test/resources/logger-config/AsyncLoggerConfig/default-level.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration>
+    <Appenders>
+        <Null name="null"/>
+    </Appenders>
+    <Loggers>
+        <AsyncLogger name="com.foo" />
+        <AsyncRoot>
+            <AppenderRef ref="null" />
+        </AsyncRoot>
+    </Loggers>
+</Configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6ce7867d/log4j-core/src/test/resources/logger-config/AsyncLoggerConfig/inherit-level.xml
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/resources/logger-config/AsyncLoggerConfig/inherit-level.xml
 
b/log4j-core/src/test/resources/logger-config/AsyncLoggerConfig/inherit-level.xml
new file mode 100644
index 0000000..2f39167
--- /dev/null
+++ 
b/log4j-core/src/test/resources/logger-config/AsyncLoggerConfig/inherit-level.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration>
+    <Appenders>
+        <Null name="null"/>
+    </Appenders>
+    <Loggers>
+        <AsyncLogger name="com.foo" />
+        <AsyncRoot level="trace">
+            <AppenderRef ref="null" />
+        </AsyncRoot>
+    </Loggers>
+</Configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6ce7867d/log4j-core/src/test/resources/logger-config/LoggerConfig/default-level.xml
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/resources/logger-config/LoggerConfig/default-level.xml 
b/log4j-core/src/test/resources/logger-config/LoggerConfig/default-level.xml
new file mode 100644
index 0000000..79d4ab1
--- /dev/null
+++ b/log4j-core/src/test/resources/logger-config/LoggerConfig/default-level.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration>
+    <Appenders>
+        <Null name="null"/>
+    </Appenders>
+    <Loggers>
+        <Logger name="com.foo" />
+        <Root>
+            <AppenderRef ref="null" />
+        </Root>
+    </Loggers>
+</Configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6ce7867d/log4j-core/src/test/resources/logger-config/LoggerConfig/inherit-level.xml
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/resources/logger-config/LoggerConfig/inherit-level.xml 
b/log4j-core/src/test/resources/logger-config/LoggerConfig/inherit-level.xml
new file mode 100644
index 0000000..4019eb1
--- /dev/null
+++ b/log4j-core/src/test/resources/logger-config/LoggerConfig/inherit-level.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration>
+    <Appenders>
+        <Null name="null"/>
+    </Appenders>
+    <Loggers>
+        <Logger name="com.foo" />
+        <Root level="trace">
+            <AppenderRef ref="null" />
+        </Root>
+    </Loggers>
+</Configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6ce7867d/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 4307479..ab2396f 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -148,6 +148,9 @@
       <action issue="LOG4J2-548" dev="ggregory" type="update" due-to="Shehata, 
Paresh Varke, Eric Victorson, Martin Laforet">
         Log4j 2.0 ERROR "Could not search jar" with JBoss EAP 6.2.
       </action>
+      <action issue="LOG4J2-2321" dev="ckozak" type="fix">
+        AsyncLogger uses the correct level when unspecified. This provides 
parity between AsyncLogger and Logger.
+      </action>
     </release>
     <release version="2.11.1" date="2018-MM-DD" description="GA Release 
2.11.1">
       <action issue="LOG4J2-2268" dev="rgoers" type="fix" due-to="Tilman 
Hausherr">

Reply via email to