Repository: logging-log4j2
Updated Branches:
  refs/heads/master de7487ed2 -> 05ef4b32d


[LOG4J2-1964] Dynamic reconfiguration does not work for filePattern of
RollingFile. Apply patch with minor tweaks. Closes #90.

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

Branch: refs/heads/master
Commit: 05ef4b32d154c8bb5dd75a94247948818bba743c
Parents: de7487e
Author: Pierrick HYMBERT <[email protected]>
Authored: Wed Jul 5 19:46:19 2017 -0700
Committer: Gary Gregory <[email protected]>
Committed: Wed Jul 5 19:46:19 2017 -0700

----------------------------------------------------------------------
 .../core/appender/rolling/PatternProcessor.java | 16 +++-
 .../appender/rolling/RollingFileManager.java    | 25 ++++--
 .../rolling/RollingAppenderReconfigureTest.java | 93 ++++++++++++++++++++
 .../resources/log4j-rolling-reconfigure.xml     | 59 +++++++++++++
 src/changes/changes.xml                         |  3 +
 5 files changed, 187 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/05ef4b32/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
index 1c7926b..b5a5aa3 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
@@ -93,11 +93,24 @@ public class PatternProcessor {
         }
     }
 
+    /**
+     * Copy constructor with another pattern as source.
+     *
+     * @param pattern  The file pattern.
+     * @param copy Source pattern processor
+     */
+    public PatternProcessor(final String pattern, final PatternProcessor copy) 
{
+        this(pattern);
+        this.prevFileTime = copy.prevFileTime;
+        this.nextFileTime = copy.nextFileTime;
+        this.currentFileTime = copy.currentFileTime;
+    }
+
     public long getCurrentFileTime() {
         return currentFileTime;
     }
 
-    public void setCurrentFileTime(long currentFileTime) {
+    public void setCurrentFileTime(final long currentFileTime) {
         this.currentFileTime = currentFileTime;
     }
 
@@ -331,4 +344,5 @@ public class PatternProcessor {
     public long getNextFileTime() {
         return nextFileTime;
     }
+
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/05ef4b32/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 bc539ef..4e07ec2 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
@@ -56,7 +56,7 @@ public class RollingFileManager extends FileManager {
 
     protected long size;
     private long initialTime;
-    private final PatternProcessor patternProcessor;
+    private volatile PatternProcessor patternProcessor;
     private final Semaphore semaphore = new Semaphore(1);
     private final Log4jThreadFactory threadFactory = 
Log4jThreadFactory.createThreadFactory("RollingFileManager");
     private volatile TriggeringPolicy triggeringPolicy;
@@ -77,6 +77,9 @@ public class RollingFileManager extends FileManager {
     private static final AtomicReferenceFieldUpdater<RollingFileManager, 
RolloverStrategy> rolloverStrategyUpdater =
             AtomicReferenceFieldUpdater.newUpdater(RollingFileManager.class, 
RolloverStrategy.class, "rolloverStrategy");
 
+    private static final AtomicReferenceFieldUpdater<RollingFileManager, 
PatternProcessor> patternProcessorUpdater =
+            AtomicReferenceFieldUpdater.newUpdater(RollingFileManager.class, 
PatternProcessor.class, "patternProcessor");
+
     @Deprecated
     protected RollingFileManager(final String fileName, final String pattern, 
final OutputStream os,
             final boolean append, final long size, final long time, final 
TriggeringPolicy triggeringPolicy,
@@ -351,6 +354,10 @@ public class RollingFileManager extends FileManager {
         rolloverStrategyUpdater.compareAndSet(this, this.rolloverStrategy, 
rolloverStrategy);
     }
 
+    public void setPatternProcessor(final PatternProcessor patternProcessor) {
+        patternProcessorUpdater.compareAndSet(this, this.patternProcessor, 
patternProcessor);
+    }
+
     /**
      * Returns the triggering policy.
      * @param <T> TriggeringPolicy type
@@ -541,16 +548,18 @@ public class RollingFileManager extends FileManager {
             this.fileGroup = fileGroup;
         }
 
-        public TriggeringPolicy getTriggeringPolicy()
-        {
+        public TriggeringPolicy getTriggeringPolicy() {
             return this.policy;
         }
 
-        public RolloverStrategy getRolloverStrategy()
-        {
+        public RolloverStrategy getRolloverStrategy() {
             return this.strategy;
         }
 
+        public String getPattern() {
+            return pattern;
+        }
+
         @Override
         public String toString() {
             final StringBuilder builder = new StringBuilder();
@@ -581,11 +590,11 @@ public class RollingFileManager extends FileManager {
     }
 
     @Override
-    public void updateData(final Object data)
-    {
+    public void updateData(final Object data) {
         final FactoryData factoryData = (FactoryData) data;
         setRolloverStrategy(factoryData.getRolloverStrategy());
         setTriggeringPolicy(factoryData.getTriggeringPolicy());
+        setPatternProcessor(new PatternProcessor(factoryData.getPattern(), 
getPatternProcessor()));
     }
 
     /**
@@ -628,7 +637,7 @@ public class RollingFileManager extends FileManager {
                 final long time = data.createOnDemand || file == null ?
                         System.currentTimeMillis() : file.lastModified(); // 
LOG4J2-531 create file first so time has valid value
 
-                RollingFileManager rm = new 
RollingFileManager(data.getLoggerContext(), data.fileName, data.pattern, os,
+                final RollingFileManager rm = new 
RollingFileManager(data.getLoggerContext(), data.fileName, data.pattern, os,
                     data.append, data.createOnDemand, size, time, data.policy, 
data.strategy, data.advertiseURI,
                     data.layout, data.filePermissions, data.fileOwner, 
data.fileGroup, writeHeader, buffer);
                 if (os != null && rm.isAttributeViewEnabled()) {

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/05ef4b32/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderReconfigureTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderReconfigureTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderReconfigureTest.java
new file mode 100644
index 0000000..15961d4
--- /dev/null
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderReconfigureTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.rolling;
+
+import static org.apache.logging.log4j.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.hamcrest.Matchers.endsWith;
+import static org.hamcrest.Matchers.hasItemInArray;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+
+/**
+ * LOG4J2-1725.
+ */
+public class RollingAppenderReconfigureTest {
+
+    private static final String DIR = "target/rolling1";
+
+    private static final String CONFIG = "log4j-rolling-reconfigure.xml";
+
+    private static final File CONFIG_FILE = new File("target/test-classes/", 
CONFIG);
+
+    public static LoggerContextRule loggerContextRule = LoggerContextRule
+            .createShutdownTimeoutLoggerContextRule(CONFIG);
+
+    @Rule
+    public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR);
+
+    private Logger logger;
+
+    @Before
+    public void setUp() throws Exception {
+        this.logger = 
loggerContextRule.getLogger(RollingAppenderReconfigureTest.class.getName());
+    }
+
+    @Test
+    public void testReconfigure() throws Exception {
+        for (int i = 0; i < 500; ++i) {
+            final String message = "This is test message number " + i;
+            logger.debug(message);
+        }
+
+        final File dir = new File(DIR);
+        assertTrue("Directory not created", dir.exists());
+        final File[] files = dir.listFiles();
+        assertThat(files, 
hasItemInArray(that(hasName(that(endsWith(".current"))))));
+        assertThat(files, 
hasItemInArray(that(hasName(that(endsWith(".rolled"))))));
+
+        final String originalXmlConfig = 
FileUtils.readFileToString(CONFIG_FILE, "UTF-8");
+        try {
+            final String updatedXmlConfig = 
originalXmlConfig.replace("target/rolling1/rollingtest.%i.rolled",
+                    "target/rolling1/rollingtest.%i.reconfigured");
+            FileUtils.write(CONFIG_FILE, updatedXmlConfig, "UTF-8");
+
+            // Reconfigure
+            loggerContextRule.getLoggerContext().reconfigure();
+
+            for (int i = 0; i < 500; ++i) {
+                final String message = "This is test message number " + i;
+                logger.debug(message);
+            }
+
+            final File[] filesAfterReconfigured = dir.listFiles();
+            assertThat(filesAfterReconfigured, 
hasItemInArray(that(hasName(that(endsWith(".reconfigured"))))));
+            assertThat(filesAfterReconfigured, 
hasItemInArray(that(hasName(that(endsWith(".current"))))));
+            assertThat(filesAfterReconfigured, 
hasItemInArray(that(hasName(that(endsWith(".rolled"))))));
+        } finally {
+            FileUtils.write(CONFIG_FILE, originalXmlConfig, "UTF-8");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/05ef4b32/log4j-core/src/test/resources/log4j-rolling-reconfigure.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-rolling-reconfigure.xml 
b/log4j-core/src/test/resources/log4j-rolling-reconfigure.xml
new file mode 100644
index 0000000..4f4899d
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-rolling-reconfigure.xml
@@ -0,0 +1,59 @@
+<?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" name="XMLConfigTest">
+  <Properties>
+    <Property name="filename">target/rolling1/rollingtest.current</Property>
+  </Properties>
+  <ThresholdFilter level="debug"/>
+
+  <Appenders>
+    <Console name="STDOUT">
+      <PatternLayout pattern="%m%n"/>
+    </Console>
+    <RollingFile name="RollingFile" fileName="${filename}"
+                 filePattern="target/rolling1/rollingtest.%i.rolled">
+      <PatternLayout>
+        <Pattern>%m%n</Pattern>
+      </PatternLayout>
+      <SizeBasedTriggeringPolicy size="1000" />
+      <DefaultRolloverStrategy max="500"/>
+    </RollingFile>
+    <List name="List">
+      <ThresholdFilter level="error"/>
+    </List>
+  </Appenders>
+
+  <Loggers>
+    <Logger name="org.apache.logging.log4j.test1" level="debug" 
additivity="false">
+      <ThreadContextMapFilter>
+        <KeyValuePair key="test" value="123"/>
+      </ThreadContextMapFilter>
+      <AppenderRef ref="STDOUT"/>
+    </Logger>
+
+    <Logger name="org.apache.logging.log4j.core.appender.rolling" 
level="debug" additivity="false">
+      <AppenderRef ref="RollingFile"/>
+    </Logger>
+
+    <Root level="error">
+      <AppenderRef ref="STDOUT"/>
+    </Root>
+  </Loggers>
+
+</Configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/05ef4b32/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 973fb98..6776fff 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -85,6 +85,9 @@
       <action issue="LOG4J2-1874" dev="rpopma" type="add" due-to="Roman 
Leventov">
         Added methods ::writeBytes(ByteBuffer) and ::writeBytes(byte[], int, 
int) to ByteBufferDestination interface and use these methods in 
TextEncoderHelper where possible to prepare for future enhancements to reduce 
lock contention.
       </action>
+      <action issue="LOG4J2-1964" dev="ggregory" type="fix" due-to="Pierrick 
HYMBERT">
+        Dynamic reconfiguration does not work for filePattern of RollingFile.
+      </action>
       <action issue="LOG4J2-1943" dev="rgoers" type="fix">
         The eventPrefix attribute was being ignored in the RFC5424Layout.
       </action>

Reply via email to