You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rg...@apache.org on 2021/12/05 20:53:10 UTC

[logging-log4j2] branch release-2.x updated: LOG4J2-1798 - Handle interrupted exceptions that occur during rollover.

This is an automated email from the ASF dual-hosted git repository.

rgoers pushed a commit to branch release-2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git


The following commit(s) were added to refs/heads/release-2.x by this push:
     new f6b2730  LOG4J2-1798 - Handle interrupted exceptions that occur during rollover.
f6b2730 is described below

commit f6b2730a652a17ec856b7a1477c938066b3556bc
Author: Ralph Goers <rg...@apache.org>
AuthorDate: Sun Dec 5 13:53:00 2021 -0700

    LOG4J2-1798 - Handle interrupted exceptions that occur during rollover.
---
 .../core/appender/rolling/RollingFileManager.java  | 26 ++++++--
 .../RollingFileAppenderInterruptedThreadTest.java  | 78 ++++++++++++++++++++++
 src/changes/changes.xml                            |  3 +
 3 files changed, 100 insertions(+), 7 deletions(-)

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 dc7ca76..de6e673 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
@@ -382,13 +382,25 @@ public class RollingFileManager extends FileManager {
                 }
             }
         }
-        if (rollover(rolloverStrategy)) {
-            try {
-                size = 0;
-                initialTime = System.currentTimeMillis();
-                createFileAfterRollover();
-            } catch (final IOException e) {
-                logError("Failed to create file after rollover", e);
+
+        boolean interrupted = Thread.interrupted(); // clear interrupted state
+        try {
+            if (interrupted) {
+                LOGGER.warn("RollingFileManager cleared thread interrupted state, continue to rollover");
+            }
+
+            if (rollover(rolloverStrategy)) {
+                try {
+                    size = 0;
+                    initialTime = System.currentTimeMillis();
+                    createFileAfterRollover();
+                } catch (final IOException e) {
+                    logError("Failed to create file after rollover", e);
+                }
+            }
+        } finally {
+            if (interrupted) { // restore interrupted state
+                Thread.currentThread().interrupt();
             }
         }
         if (rolloverListeners.size() > 0) {
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderInterruptedThreadTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderInterruptedThreadTest.java
new file mode 100644
index 0000000..da621a2
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderInterruptedThreadTest.java
@@ -0,0 +1,78 @@
+package org.apache.logging.log4j.core.appender.rolling;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.Logger;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.ConsoleAppender;
+import org.apache.logging.log4j.core.appender.RollingFileAppender;
+import org.apache.logging.log4j.core.config.Configurator;
+import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
+import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
+import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
+import org.apache.logging.log4j.junit.CleanFolders;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.instanceOf;
+
+/**
+ * Tests https://issues.apache.org/jira/browse/LOG4J2-1798
+ */
+public class RollingFileAppenderInterruptedThreadTest {
+
+    private static final String ROLLING_APPENDER_FILES_DIR =
+            "target/" + RollingFileAppenderInterruptedThreadTest.class.getSimpleName();
+
+    @Rule
+    public CleanFolders cleanFolders = new CleanFolders(true, false, 3, ROLLING_APPENDER_FILES_DIR);
+
+    LoggerContext loggerContext;
+
+    @Before
+    public void setUp() {
+        ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
+        builder.setConfigurationName("LOG4J2-1798 test");
+
+        builder.add(builder.newAppender("consoleLog", "Console")
+                .addAttribute("target", ConsoleAppender.Target.SYSTEM_ERR));
+
+        builder.add(builder.newAppender("fileAppender", "RollingFile")
+                .addAttribute("filePattern", ROLLING_APPENDER_FILES_DIR + "/file-%i.log")
+                .add(builder.newLayout("PatternLayout").addAttribute("pattern", "%msg%n"))
+                .addComponent(builder.newComponent("SizeBasedTriggeringPolicy")
+                        .addAttribute("size", "20B"))); // relatively small amount to trigger rotation quickly
+
+        builder.add(builder.newRootLogger(Level.INFO)
+                .add(builder.newAppenderRef("consoleLog"))
+                .add(builder.newAppenderRef("fileAppender")));
+
+        loggerContext = Configurator.initialize(builder.build());
+    }
+
+    @After
+    public void tearDown() {
+        Configurator.shutdown(loggerContext);
+        loggerContext = null;
+    }
+
+    @Test
+    public void testRolloverInInterruptedThread() {
+        Logger logger = loggerContext.getLogger(getClass().getName());
+
+        Assert.assertThat(logger.getAppenders().values(), hasItem(instanceOf(RollingFileAppender.class)));
+
+        logger.info("Sending logging event 1"); // send first event to initialize rollover system
+
+        Thread.currentThread().interrupt(); // mark thread as interrupted
+        logger.info("Sending logging event 2"); // send second event to trigger rotation, expecting 2 files in result
+
+        Assert.assertTrue(new File(ROLLING_APPENDER_FILES_DIR, "file-1.log").exists());
+        Assert.assertTrue(new File(ROLLING_APPENDER_FILES_DIR, "file-2.log").exists());
+    }
+}
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 317d950..c9108f3 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -116,6 +116,9 @@
         Improve PatternLayout performance by reducing unnecessary indirection and branching.
       </action>
       <!-- FIXES -->
+      <action issue="LOG4J2-1798" dev="rgoers" due-to="Viacheslav Zhivaev">
+        Handle interrupted exceptions that occur during rollover.
+      </action>
       <action issue="LOG4J2-2951" dev="rgoers">
         Log4j 1.x properties were not being substituted.
       </action>