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 2017/06/30 12:30:20 UTC

logging-log4j2 git commit: LOG4J2-1908 Improved error message when misconfigured with multiple incompatible appenders targeting same file

Repository: logging-log4j2
Updated Branches:
  refs/heads/master 10ad73fbc -> 9672576b3


LOG4J2-1908 Improved error message when misconfigured with multiple incompatible appenders targeting same file


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

Branch: refs/heads/master
Commit: 9672576b3dd6aeb68df36f6698dc260e43d26cb3
Parents: 10ad73f
Author: rpopma <rp...@apache.org>
Authored: Fri Jun 30 21:30:15 2017 +0900
Committer: rpopma <rp...@apache.org>
Committed: Fri Jun 30 21:30:15 2017 +0900

----------------------------------------------------------------------
 .../log4j/core/appender/FileManager.java        | 12 ++--
 .../core/appender/MemoryMappedFileManager.java  |  4 +-
 .../core/appender/OutputStreamManager.java      | 19 +++++++
 .../core/appender/RandomAccessFileManager.java  |  4 +-
 .../appender/rolling/RollingFileManager.java    |  6 +-
 .../rolling/RollingRandomAccessFileManager.java |  4 +-
 .../core/config/plugins/util/PluginBuilder.java |  5 +-
 .../core/appender/OutputStreamManagerTest.java  | 58 ++++++++++++++++++++
 .../multipleIncompatibleAppendersTest.xml       | 47 ++++++++++++++++
 src/changes/changes.xml                         |  3 +
 10 files changed, 146 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9672576b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileManager.java
index 6f7a98a..087dc5f 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileManager.java
@@ -177,8 +177,8 @@ public class FileManager extends OutputStreamManager {
         if (locking && bufferedIo) {
             locking = false;
         }
-        return (FileManager) getManager(fileName, new FactoryData(append, locking, bufferedIo, bufferSize,
-                createOnDemand, advertiseUri, layout, filePermissions, fileOwner, fileGroup, configuration), FACTORY);
+        return narrow(FileManager.class, getManager(fileName, new FactoryData(append, locking, bufferedIo, bufferSize,
+                createOnDemand, advertiseUri, layout, filePermissions, fileOwner, fileGroup, configuration), FACTORY));
     }
 
     @Override
@@ -301,7 +301,7 @@ public class FileManager extends OutputStreamManager {
     public int getBufferSize() {
         return bufferSize;
     }
-    
+
     /**
      * Returns posix file permissions if defined and the OS supports posix file attribute,
      * null otherwise.
@@ -311,10 +311,10 @@ public class FileManager extends OutputStreamManager {
     public Set<PosixFilePermission> getFilePermissions() {
         return filePermissions;
     }
-    
+
     /**
      * Returns file owner if defined and the OS supports owner file attribute view,
-     * null otherwise. 
+     * null otherwise.
      * @return File owner
      * @see FileOwnerAttributeView
      */
@@ -324,7 +324,7 @@ public class FileManager extends OutputStreamManager {
 
     /**
      * Returns file group if defined and the OS supports posix/group file attribute view,
-     * null otherwise. 
+     * null otherwise.
      * @return File group
      * @see PosixFileAttributeView
      */

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9672576b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java
index 99f3b06..7d5fd8d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java
@@ -101,8 +101,8 @@ public class MemoryMappedFileManager extends OutputStreamManager {
     public static MemoryMappedFileManager getFileManager(final String fileName, final boolean append,
             final boolean immediateFlush, final int regionLength, final String advertiseURI,
             final Layout<? extends Serializable> layout) {
-        return (MemoryMappedFileManager) getManager(fileName, new FactoryData(append, immediateFlush, regionLength,
-                advertiseURI, layout), FACTORY);
+        return narrow(MemoryMappedFileManager.class, getManager(fileName, new FactoryData(append, immediateFlush,
+                regionLength, advertiseURI, layout), FACTORY));
     }
 
     public Boolean isEndOfBatch() {

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9672576b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java
index 55e51e4..d219f00 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java
@@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.ConfigurationException;
 import org.apache.logging.log4j.core.layout.ByteBufferDestination;
 import org.apache.logging.log4j.core.layout.ByteBufferDestinationHelper;
 import org.apache.logging.log4j.core.util.Constants;
@@ -115,6 +116,24 @@ public class OutputStreamManager extends AbstractManager implements ByteBufferDe
         return AbstractManager.getManager(name, factory, data);
     }
 
+    /**
+     * Returns the specified manager, cast to the specified narrow type.
+     * @param narrowClass the type to cast to
+     * @param manager the manager object to return
+     * @param <M> the narrow type
+     * @return the specified manager, cast to the specified narrow type
+     * @throws ConfigurationException if the manager cannot be cast to the specified type, which only happens when
+     *          the configuration has multiple incompatible appenders writing to the same file
+     */
+    protected static <M extends OutputStreamManager> M narrow(
+            final Class<M> narrowClass, final OutputStreamManager manager) {
+        if (narrowClass.isAssignableFrom(manager.getClass())) {
+            return (M) manager;
+        }
+        throw new ConfigurationException(
+                "Configuration has multiple incompatible Appenders pointing to the same file " + manager.getName());
+    }
+
     @SuppressWarnings("unused")
     protected OutputStream createOutputStream() throws IOException {
         throw new IllegalStateException(getClass().getCanonicalName() + " must implement createOutputStream()");

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9672576b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileManager.java
index 5148ee5..59f0df3 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileManager.java
@@ -71,8 +71,8 @@ public class RandomAccessFileManager extends OutputStreamManager {
     public static RandomAccessFileManager getFileManager(final String fileName, final boolean append,
             final boolean isFlush, final int bufferSize, final String advertiseURI,
             final Layout<? extends Serializable> layout, final Configuration configuration) {
-        return (RandomAccessFileManager) getManager(fileName, new FactoryData(append,
-                isFlush, bufferSize, advertiseURI, layout, configuration), FACTORY);
+        return narrow(RandomAccessFileManager.class, getManager(fileName, new FactoryData(append,
+                isFlush, bufferSize, advertiseURI, layout, configuration), FACTORY));
     }
 
     public Boolean isEndOfBatch() {

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9672576b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
index 546924c..bc539ef 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
@@ -177,9 +177,9 @@ public class RollingFileManager extends FileManager {
             final String filePermissions, final String fileOwner, final String fileGroup,
             final Configuration configuration) {
         final String name = fileName == null ? pattern : fileName;
-        return (RollingFileManager) getManager(name, new FactoryData(fileName, pattern, append,
+        return narrow(RollingFileManager.class, getManager(name, new FactoryData(fileName, pattern, append,
             bufferedIO, policy, strategy, advertiseURI, layout, bufferSize, immediateFlush, createOnDemand,
-            filePermissions, fileOwner, fileGroup, configuration), factory);
+            filePermissions, fileOwner, fileGroup, configuration), factory));
     }
 
     /**
@@ -646,7 +646,7 @@ public class RollingFileManager extends FileManager {
     private static class EmptyQueue extends ArrayBlockingQueue<Runnable> {
 
         /**
-         * 
+         *
          */
         private static final long serialVersionUID = 1L;
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9672576b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
index af53d97..f9943ab 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
@@ -101,9 +101,9 @@ public class RollingRandomAccessFileManager extends RollingFileManager {
             final TriggeringPolicy policy, final RolloverStrategy strategy, final String advertiseURI,
             final Layout<? extends Serializable> layout, final String filePermissions, final String fileOwner, final String fileGroup,
             final Configuration configuration) {
-        return (RollingRandomAccessFileManager) getManager(fileName, new FactoryData(filePattern, isAppend,
+        return narrow(RollingRandomAccessFileManager.class, getManager(fileName, new FactoryData(filePattern, isAppend,
                 immediateFlush, bufferSize, policy, strategy, advertiseURI, layout,
-                filePermissions, fileOwner, fileGroup, configuration), FACTORY);
+                filePermissions, fileOwner, fileGroup, configuration), FACTORY));
     }
 
     public Boolean isEndOfBatch() {

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9672576b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java
index e5baade..5a2cd04 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java
@@ -121,8 +121,11 @@ public class PluginBuilder implements Builder<Object> {
                 injectFields(builder);
                 return builder.build();
             }
+        } catch (final ConfigurationException e) {
+            LOGGER.error("Could not create plugin of type {} for element {}", this.clazz, node.getName(), e);
+            return null; // no point in trying the factory method
         } catch (final Exception e) {
-            LOGGER.error("Unable to inject fields into builder class for plugin type {}, element {}: {}",
+            LOGGER.error("Could not create plugin of type {} for element {}: {}",
                     this.clazz, node.getName(),
                     (e instanceof InvocationTargetException ? ((InvocationTargetException) e).getCause() : e).toString(), e);
         }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9672576b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamManagerTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamManagerTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamManagerTest.java
new file mode 100644
index 0000000..06ca393
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamManagerTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.appender;
+
+import java.util.List;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.status.StatusData;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * OutputStreamManager Tests.
+ */
+public class OutputStreamManagerTest {
+    private static final String CONFIG = "multipleIncompatibleAppendersTest.xml";
+
+    @ClassRule
+    public static LoggerContextRule context = new LoggerContextRule(CONFIG);
+
+    @Test
+    public void narrow() throws Exception {
+        Logger logger = LogManager.getLogger(OutputStreamManagerTest.class);
+        logger.info("test");
+        List<StatusData> statusData = StatusLogger.getLogger().getStatusData();
+        StatusData data = statusData.get(0);
+        if (data.getMessage().getFormattedMessage().contains("WindowsAnsiOutputStream")) {
+            data = statusData.get(1);
+        }
+        assertEquals(Level.ERROR, data.getLevel());
+        assertEquals("Could not create plugin of type class org.apache.logging.log4j.core.appender.RollingRandomAccessFileAppender for element RollingRandomAccessFile",
+                data.getMessage().getFormattedMessage());
+        assertEquals("org.apache.logging.log4j.core.config.ConfigurationException: Configuration has multiple incompatible Appenders pointing to the same file target/multiIncompatibleAppender.log",
+                data.getThrowable().toString());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9672576b/log4j-core/src/test/resources/multipleIncompatibleAppendersTest.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/multipleIncompatibleAppendersTest.xml b/log4j-core/src/test/resources/multipleIncompatibleAppendersTest.xml
new file mode 100644
index 0000000..f1fd48a
--- /dev/null
+++ b/log4j-core/src/test/resources/multipleIncompatibleAppendersTest.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<Configuration status="WARN">
+  <properties>
+    <property name="pattern">%d{ISO8601} %r [%t] %-5level %logger{1.} - %msg%n</property>
+  </properties>
+  <Appenders>
+    <Console name="CONSOLE" target="SYSTEM_OUT" follow="true">
+      <PatternLayout pattern="${pattern}" />
+    </Console>
+    <File name="FILE" fileName="target/multiIncompatibleAppender.log">
+      <PatternLayout pattern="${pattern}" />
+    </File>
+    <RollingRandomAccessFile name="ROLLING"
+        fileName="target/multiIncompatibleAppender.log"
+        filePattern="target/logs/%d{yyyyMMdd}/multiIncompatibleAppender-%i.log.gz">
+      <PatternLayout pattern="${pattern}" />
+      <Policies>
+        <OnStartupTriggeringPolicy/>
+        <SizeBasedTriggeringPolicy size="1 GB" />
+        <TimeBasedTriggeringPolicy/>
+      </Policies>
+      <DefaultRolloverStrategy/>
+    </RollingRandomAccessFile>
+  </Appenders>
+  <Loggers>
+    <Root level="DEBUG">
+      <AppenderRef ref="CONSOLE" level="WARN"/>
+      <AppenderRef ref="FILE" />
+    </Root>
+  </Loggers>
+</Configuration>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9672576b/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index e20b463..13783c6 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -31,6 +31,9 @@
          - "remove" - Removed
     -->
     <release version="2.9.0" date="2017-MM-DD" description="GA Release 2.9.0">
+      <action issue="LOG4J2-1908" dev="rpopma" type="update">
+        Improved error message when misconfigured with multiple incompatible appenders targeting same file.
+      </action>
       <action issue="LOG4J2-1954" dev="rpopma" type="update">
         Configurations with multiple root loggers now fail loudly.
       </action>