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>
