Skip to content

Commit 42caff8

Browse files
authored
fix writing the header for RollingFileAppender (#862)
this fixes issue #857 `encoderInit` will write the header once the `OutputStreamAppender` is started. Since the outputStream is set before starting, the other `encoderInit` inside the `start`-method is still needed. Signed-off-by: Carl Mai <[email protected]>
1 parent 91961ad commit 42caff8

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

logback-core/src/main/java/ch/qos/logback/core/OutputStreamAppender.java

+2
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ public void setOutputStream(OutputStream outputStream) {
174174
closeOutputStream();
175175
this.outputStream = outputStream;
176176

177+
// after opening we have to output the header
178+
encoderInit();
177179
} finally {
178180
streamWriteLock.unlock();
179181
}

logback-core/src/test/java/ch/qos/logback/core/rolling/RollingFileAppenderTest.java

+64-2
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313
*/
1414
package ch.qos.logback.core.rolling;
1515

16+
import ch.qos.logback.core.util.Duration;
17+
import ch.qos.logback.core.util.FileSize;
1618
import org.junit.jupiter.api.AfterEach;
1719
import org.junit.jupiter.api.Assertions;
1820
import org.junit.jupiter.api.BeforeEach;
21+
import org.junit.jupiter.api.DisplayName;
1922
import org.junit.jupiter.api.Test;
2023

2124
import ch.qos.logback.core.Appender;
@@ -27,6 +30,14 @@
2730
import ch.qos.logback.core.testUtil.CoreTestConstants;
2831
import ch.qos.logback.core.testUtil.RandomUtil;
2932
import ch.qos.logback.core.status.testUtil.StatusChecker;
33+
34+
import java.io.File;
35+
import java.io.FileInputStream;
36+
import java.io.IOException;
37+
import java.io.InputStream;
38+
import java.nio.file.Files;
39+
import java.util.Collections;
40+
import java.util.List;
3041
//import ch.qos.logback.core.util.StatusPrinter;
3142

3243
public class RollingFileAppenderTest extends AbstractAppenderTest<Object> {
@@ -37,13 +48,14 @@ public class RollingFileAppenderTest extends AbstractAppenderTest<Object> {
3748
TimeBasedRollingPolicy<Object> tbrp = new TimeBasedRollingPolicy<Object>();
3849
int diff = RandomUtil.getPositiveInt();
3950
String randomOutputDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "/";
51+
DummyEncoder<Object> encoder;
4052

4153
@BeforeEach
4254
public void setUp() throws Exception {
4355
// noStartTest fails if the context is set in setUp
4456
// rfa.setContext(context);
45-
46-
rfa.setEncoder(new DummyEncoder<Object>());
57+
encoder = new DummyEncoder<>();
58+
rfa.setEncoder(encoder);
4759
rfa.setName("test");
4860
tbrp.setContext(context);
4961
tbrp.setParent(rfa);
@@ -260,4 +272,54 @@ public void collidingFileNamePattern() {
260272
checker.assertContainsMatch(Status.ERROR, "'FileNamePattern' option has the same value");
261273
}
262274

275+
@Test
276+
@DisplayName("Checks header and footer are written when the files are rolled")
277+
public void testHeaderFooterWritten() throws IOException, InterruptedException {
278+
for (int i = 0; i < 8; i++) {
279+
File file = new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "header-" + i + ".log");
280+
file.deleteOnExit();
281+
}
282+
encoder.setFileHeader("HEADER");
283+
encoder.setFileFooter("FOOTER");
284+
rfa.setContext(context);
285+
FixedWindowRollingPolicy fixedWindowRollingPolicy = new FixedWindowRollingPolicy();
286+
fixedWindowRollingPolicy.setContext(context);
287+
fixedWindowRollingPolicy.setParent(rfa);
288+
fixedWindowRollingPolicy.setMaxIndex(3);
289+
String fileNamePattern = CoreTestConstants.OUTPUT_DIR_PREFIX + "header-%i.log";
290+
fixedWindowRollingPolicy.setFileNamePattern(fileNamePattern);
291+
rfa.setRollingPolicy(fixedWindowRollingPolicy);
292+
rfa.setFile(CoreTestConstants.OUTPUT_DIR_PREFIX + "header-0.log");
293+
fixedWindowRollingPolicy.start();
294+
rfa.setImmediateFlush(true);
295+
SizeBasedTriggeringPolicy<Object> sbtp = new SizeBasedTriggeringPolicy<>();
296+
sbtp.setMaxFileSize(new FileSize(10));
297+
sbtp.setCheckIncrement(Duration.buildByMilliseconds(10));
298+
299+
rfa.setTriggeringPolicy(sbtp);
300+
rfa.getTriggeringPolicy().start();
301+
rfa.start();
302+
303+
for (int i = 0; i < 100; i++) {
304+
rfa.doAppend("data" + i);
305+
File file = new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "header-" + fixedWindowRollingPolicy.getMaxIndex() + ".log");
306+
if (file.exists()) {
307+
break;
308+
}
309+
Thread.sleep(5);
310+
}
311+
rfa.stop();
312+
313+
for (int i = 0; i < fixedWindowRollingPolicy.getMaxIndex(); i++) {
314+
File file = new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "header-" + i + ".log");
315+
Assertions.assertTrue(file.exists());
316+
List<String> lines = Files.readAllLines(file.toPath());
317+
Assertions.assertTrue(lines.size() > 2, "At least 2 lines per file are expected in " + file);
318+
Assertions.assertEquals("HEADER", lines.get(0));
319+
Assertions.assertEquals("FOOTER", lines.get(lines.size() - 1));
320+
Assertions.assertEquals(1, Collections.frequency(lines, "HEADER"));
321+
Assertions.assertEquals(1, Collections.frequency(lines, "FOOTER"));
322+
}
323+
}
324+
263325
}

0 commit comments

Comments
 (0)