Skip to content

Commit 2e5a961

Browse files
king-tylerjvz
authored andcommitted
Reopen log file when rollover is unsuccessful (#3226)
Fixes `RollingFileManager` to reopen the log file when the rollover was unsuccessful
1 parent 0aeb58c commit 2e5a961

File tree

3 files changed

+60
-12
lines changed

3 files changed

+60
-12
lines changed

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

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,17 @@
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;
24+
import static org.junit.jupiter.api.Assertions.assertNotEquals;
2425

26+
import java.io.ByteArrayOutputStream;
2527
import java.io.File;
2628
import java.io.IOException;
29+
import java.io.OutputStream;
30+
import java.nio.ByteBuffer;
2731
import java.nio.charset.StandardCharsets;
2832
import java.nio.file.Files;
2933
import org.apache.logging.log4j.core.LoggerContext;
@@ -185,4 +189,40 @@ public void testCreateParentDir() {
185189
manager.close();
186190
}
187191
}
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+
null,
204+
file.getAbsolutePath(),
205+
"testRolloverOfDeletedFile.log.%d{yyyy-MM-dd}",
206+
os,
207+
true,
208+
false,
209+
0,
210+
System.currentTimeMillis(),
211+
OnStartupTriggeringPolicy.createPolicy(1),
212+
DefaultRolloverStrategy.newBuilder().build(),
213+
file.getName(),
214+
null,
215+
null,
216+
null,
217+
null,
218+
false,
219+
ByteBuffer.allocate(256))) {
220+
assertTrue(file.delete());
221+
manager.setRenameEmptyFiles(true);
222+
manager.rollover();
223+
assertEquals(file.getAbsolutePath(), manager.getFileName());
224+
manager.writeBytes(testContent.getBytes(StandardCharsets.US_ASCII), 0, testContent.length());
225+
}
226+
assertEquals(testContent, Files.readString(file.toPath(), StandardCharsets.US_ASCII));
227+
}
188228
}

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
@@ -516,43 +516,43 @@ public RolloverStrategy getRolloverStrategy() {
516516

517517
private boolean rollover(final RolloverStrategy strategy) {
518518

519-
boolean releaseRequired = false;
519+
boolean outputStreamClosed = false;
520520
try {
521521
// Block until the asynchronous operation is completed.
522522
semaphore.acquire();
523-
releaseRequired = true;
524523
} catch (final InterruptedException e) {
525524
logError("Thread interrupted while attempting to check rollover", e);
526-
return false;
525+
return outputStreamClosed;
527526
}
528527

529-
boolean success = true;
528+
boolean asyncActionStarted = true;
530529

531530
try {
532531
final RolloverDescription descriptor = strategy.rollover(this);
533532
if (descriptor != null) {
534533
writeFooter();
535534
closeOutputStream();
535+
outputStreamClosed = true;
536+
boolean syncActionSuccess = true;
536537
if (descriptor.getSynchronous() != null) {
537538
LOGGER.debug("RollingFileManager executing synchronous {}", descriptor.getSynchronous());
538539
try {
539-
success = descriptor.getSynchronous().execute();
540+
syncActionSuccess = descriptor.getSynchronous().execute();
540541
} catch (final Exception ex) {
541-
success = false;
542+
syncActionSuccess = false;
542543
logError("Caught error in synchronous task", ex);
543544
}
544545
}
545546

546-
if (success && descriptor.getAsynchronous() != null) {
547+
if (syncActionSuccess && descriptor.getAsynchronous() != null) {
547548
LOGGER.debug("RollingFileManager executing async {}", descriptor.getAsynchronous());
548549
asyncExecutor.execute(new AsyncAction(descriptor.getAsynchronous(), this));
549-
releaseRequired = false;
550+
asyncActionStarted = false;
550551
}
551-
return success;
552552
}
553-
return false;
553+
return outputStreamClosed;
554554
} finally {
555-
if (releaseRequired) {
555+
if (asyncActionStarted) {
556556
semaphore.release();
557557
}
558558
}
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)