Skip to content

Commit 7959176

Browse files
authored
Reopen log file when rollover is unsuccessful (#3226)
Fixes `RollingFileManager` to reopen the log file when the rollover was unsuccessful
1 parent 546e4fa commit 7959176

File tree

3 files changed

+63
-19
lines changed

3 files changed

+63
-19
lines changed

log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManagerTest.java

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,21 @@
1717
package org.apache.logging.log4j.core.appender.rolling;
1818

1919
import static org.junit.Assert.assertEquals;
20-
import static org.junit.Assert.assertNotEquals;
2120
import static org.junit.Assert.assertNotNull;
2221
import static org.junit.Assert.assertNull;
22+
import static org.junit.Assert.assertTrue;
2323
import static org.junit.Assert.fail;
2424

25+
import java.io.ByteArrayOutputStream;
2526
import java.io.File;
2627
import java.io.FileInputStream;
2728
import java.io.IOException;
2829
import java.io.InputStreamReader;
30+
import java.io.OutputStream;
2931
import java.io.Reader;
32+
import java.nio.ByteBuffer;
3033
import java.nio.charset.StandardCharsets;
34+
import java.nio.file.Files;
3135
import org.apache.logging.log4j.core.LoggerContext;
3236
import org.apache.logging.log4j.core.appender.RollingFileAppender;
3337
import org.apache.logging.log4j.core.appender.rolling.action.AbstractAction;
@@ -138,21 +142,18 @@ public RolloverDescription rollover(final RollingFileManager manager) throws Sec
138142
assertNotNull(manager);
139143
manager.initialize();
140144

141-
// Get the initialTime of this original log file
142-
final long initialTime = manager.getFileTime();
143-
144145
// Log something to ensure that the existing file size is > 0
145146
final String testContent = "Test";
146147
manager.writeToDestination(testContent.getBytes(StandardCharsets.US_ASCII), 0, testContent.length());
147148

148149
// Trigger rollover that will fail
149150
manager.rollover();
150151

151-
// If the rollover fails, then the size should not be reset
152-
assertNotEquals(0, manager.getFileSize());
152+
// If the rollover fails, then the log file should be unchanged
153+
assertEquals(file.getAbsolutePath(), manager.getFileName());
153154

154-
// The initialTime should not have changed
155-
assertEquals(initialTime, manager.getFileTime());
155+
// The logged content should be unchanged
156+
assertEquals(testContent, new String(Files.readAllBytes(file.toPath()), StandardCharsets.US_ASCII));
156157
}
157158

158159
@Test
@@ -188,4 +189,39 @@ public void testCreateParentDir() {
188189
manager.close();
189190
}
190191
}
192+
193+
@Test
194+
@Issue("https://github.com/apache/logging-log4j2/issues/2592")
195+
public void testRolloverOfDeletedFile() throws IOException {
196+
final File file = File.createTempFile("testRolloverOfDeletedFile", "log");
197+
file.deleteOnExit();
198+
final String testContent = "Test";
199+
try (final OutputStream os =
200+
new ByteArrayOutputStream(); // use a dummy OutputStream so that the real file can be deleted
201+
final RollingFileManager manager = new RollingFileManager(
202+
null,
203+
file.getAbsolutePath(),
204+
"testRolloverOfDeletedFile.log.%d{yyyy-MM-dd}",
205+
os,
206+
true,
207+
false,
208+
0,
209+
System.currentTimeMillis(),
210+
OnStartupTriggeringPolicy.createPolicy(1),
211+
DefaultRolloverStrategy.newBuilder().build(),
212+
file.getName(),
213+
null,
214+
null,
215+
null,
216+
null,
217+
false,
218+
ByteBuffer.allocate(256))) {
219+
assertTrue(file.delete());
220+
manager.setRenameEmptyFiles(true);
221+
manager.rollover();
222+
assertEquals(file.getAbsolutePath(), manager.getFileName());
223+
manager.writeBytes(testContent.getBytes(StandardCharsets.US_ASCII), 0, testContent.length());
224+
}
225+
assertEquals(testContent, new String(Files.readAllBytes(file.toPath()), StandardCharsets.US_ASCII));
226+
}
191227
}

log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -604,43 +604,43 @@ public RolloverStrategy getRolloverStrategy() {
604604

605605
private boolean rollover(final RolloverStrategy strategy) {
606606

607-
boolean releaseRequired = false;
607+
boolean outputStreamClosed = false;
608608
try {
609609
// Block until the asynchronous operation is completed.
610610
semaphore.acquire();
611-
releaseRequired = true;
612611
} catch (final InterruptedException e) {
613612
logError("Thread interrupted while attempting to check rollover", e);
614-
return false;
613+
return outputStreamClosed;
615614
}
616615

617-
boolean success = true;
616+
boolean asyncActionStarted = true;
618617

619618
try {
620619
final RolloverDescription descriptor = strategy.rollover(this);
621620
if (descriptor != null) {
622621
writeFooter();
623622
closeOutputStream();
623+
outputStreamClosed = true;
624+
boolean syncActionSuccess = true;
624625
if (descriptor.getSynchronous() != null) {
625626
LOGGER.debug("RollingFileManager executing synchronous {}", descriptor.getSynchronous());
626627
try {
627-
success = descriptor.getSynchronous().execute();
628+
syncActionSuccess = descriptor.getSynchronous().execute();
628629
} catch (final Exception ex) {
629-
success = false;
630+
syncActionSuccess = false;
630631
logError("Caught error in synchronous task", ex);
631632
}
632633
}
633634

634-
if (success && descriptor.getAsynchronous() != null) {
635+
if (syncActionSuccess && descriptor.getAsynchronous() != null) {
635636
LOGGER.debug("RollingFileManager executing async {}", descriptor.getAsynchronous());
636637
asyncExecutor.execute(new AsyncAction(descriptor.getAsynchronous(), this));
637-
releaseRequired = false;
638+
asyncActionStarted = false;
638639
}
639-
return success;
640640
}
641-
return false;
641+
return outputStreamClosed;
642642
} finally {
643-
if (releaseRequired) {
643+
if (asyncActionStarted) {
644644
semaphore.release();
645645
}
646646
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xmlns="https://logging.apache.org/xml/ns"
4+
xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
5+
type="fixed">
6+
<issue id="2592" link="https://github.com/apache/logging-log4j2/issues/2592"/>
7+
<description format="asciidoc">Fix `RollingFileManager` to reopen the log file when the rollover was unsuccessful</description>
8+
</entry>

0 commit comments

Comments
 (0)