diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/FileRenameActionTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/FileRenameActionTest.java index 7309e6e7ccf..ebbd93a9b35 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/FileRenameActionTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/FileRenameActionTest.java @@ -23,6 +23,7 @@ import java.io.PrintStream; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import org.junitpioneer.jupiter.Issue; public class FileRenameActionTest { @@ -97,4 +98,28 @@ public void testNoParent() throws Exception { assertTrue(dest.exists(), "Renamed file does not exist"); assertFalse(file.exists(), "Old file exists"); } + + @Test + @Issue("https://github.com/apache/logging-log4j2/issues/2592") + public void testRenameForMissingFile() throws Exception { + final File file = new File("fileRename.log"); + final File dest = new File(tempDir, "newFile.log"); + FileRenameAction action = new FileRenameAction(file, dest, true); + boolean renameResult = action.execute(); + assertTrue(renameResult, "Rename action returned false"); + assertTrue(dest.exists(), "Renamed file does not exist"); + assertFalse(file.exists(), "Old file exists"); + } + + @Test + @Issue("https://github.com/apache/logging-log4j2/issues/2592") + public void testRenameForMissingFileWithoutEmptyFilesRenaming() throws Exception { + final File file = new File("fileRename.log"); + final File dest = new File(tempDir, "newFile.log"); + FileRenameAction action = new FileRenameAction(file, dest, false); + boolean renameResult = action.execute(); + assertTrue(renameResult, "Rename action returned false"); + assertFalse(dest.exists(), "Renamed file should not exist"); + assertFalse(file.exists(), "Old file exists"); + } } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/FileRenameAction.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/FileRenameAction.java index e7bb2376db7..9d84d02eb54 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/FileRenameAction.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/FileRenameAction.java @@ -17,6 +17,7 @@ package org.apache.logging.log4j.core.appender.rolling.action; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.PrintWriter; @@ -166,12 +167,38 @@ public static boolean execute(final File source, final File destination, final b } } } catch (final IOException exCopy) { - LOGGER.error( - "Unable to copy file {} to {}: {} {}", - source.getAbsolutePath(), - destination.getAbsolutePath(), - exCopy.getClass().getName(), - exCopy.getMessage()); + if (source.isFile()) { + LOGGER.error( + "Unable to copy file {} to {}: {} {}", + source.getAbsolutePath(), + destination.getAbsolutePath(), + exCopy.getClass().getName(), + exCopy.getMessage()); + } else { + LOGGER.debug( + "Unable to copy file {} to {}: {} {} - will try to create destination since source file does not exist", + source.getAbsolutePath(), + destination.getAbsolutePath(), + exCopy.getClass().getName(), + exCopy.getMessage()); + try { + Files.copy( + new ByteArrayInputStream(new byte[0]), + destination.toPath(), + StandardCopyOption.REPLACE_EXISTING); + result = true; + LOGGER.trace( + "Created file {} since {} does not exist", + destination.getAbsolutePath(), + source.getAbsolutePath()); + } catch (final IOException exCreate) { + LOGGER.error( + "Unable to create file {}: {} {}", + destination.getAbsolutePath(), + exCreate.getClass().getName(), + exCreate.getMessage()); + } + } } } else { LOGGER.trace( @@ -191,7 +218,8 @@ public static boolean execute(final File source, final File destination, final b } } else { try { - return source.delete(); + Files.deleteIfExists(source.toPath()); + return true; } catch (final Exception exDelete) { LOGGER.error( "Unable to delete empty file {}: {} {}", diff --git a/src/changelog/.2.x.x/2592_fix_FileRenameAction_for_missing_source_file.xml b/src/changelog/.2.x.x/2592_fix_FileRenameAction_for_missing_source_file.xml new file mode 100644 index 00000000000..9cf98b3e3e4 --- /dev/null +++ b/src/changelog/.2.x.x/2592_fix_FileRenameAction_for_missing_source_file.xml @@ -0,0 +1,8 @@ + + + + Fixed `FileRenameAction` when the source file doesn't exist + \ No newline at end of file