Author: rpopma
Date: Sat Jun 21 16:34:58 2014
New Revision: 1604428
URL: http://svn.apache.org/r1604428
Log:
LOG4J2-581, LOG4J2-675 RollingRandomAccessFile now writes the layout header
after rollover; RollingFile and RollingRandomAccessFile now write the layout
footer before rollover.
Added:
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerHeaderFooterTest.java
(with props)
logging/log4j/log4j2/trunk/log4j-core/src/test/resources/RollingRandomAccessFileAppenderHeaderFooterTest.xml
(with props)
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
logging/log4j/log4j2/trunk/src/changes/changes.xml
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java?rev=1604428&r1=1604427&r2=1604428&view=diff
==============================================================================
---
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java
(original)
+++
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java
Sat Jun 21 16:34:58 2014
@@ -28,8 +28,7 @@ import org.apache.logging.log4j.core.Lay
public class OutputStreamManager extends AbstractManager {
private volatile OutputStream os;
-
- private final Layout<?> layout;
+ protected final Layout<?> layout;
protected OutputStreamManager(final OutputStream os, final String
streamName, final Layout<?> layout) {
super(streamName);
@@ -66,11 +65,21 @@ public class OutputStreamManager extends
*/
@Override
public void releaseSub() {
+ writeFooter();
+ close();
+ }
+
+ /**
+ * Writes the footer.
+ */
+ protected void writeFooter() {
+ if (layout == null) {
+ return;
+ }
byte[] footer = layout.getFooter();
if (footer != null) {
write(footer);
}
- close();
}
/**
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java?rev=1604428&r1=1604427&r2=1604428&view=diff
==============================================================================
---
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
(original)
+++
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
Sat Jun 21 16:34:58 2014
@@ -167,6 +167,7 @@ public class RollingFileManager extends
try {
final RolloverDescription descriptor = strategy.rollover(this);
if (descriptor != null) {
+ writeFooter();
close();
if (descriptor.getSynchronous() != null) {
LOGGER.debug("RollingFileManager executing synchronous
{}", descriptor.getSynchronous());
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java?rev=1604428&r1=1604427&r2=1604428&view=diff
==============================================================================
---
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
(original)
+++
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
Sat Jun 21 16:34:58 2014
@@ -55,6 +55,26 @@ public class RollingRandomAccessFileMana
this.randomAccessFile = raf;
isEndOfBatch.set(Boolean.FALSE);
this.buffer = ByteBuffer.allocate(bufferSize);
+ writeHeader();
+ }
+
+ /**
+ * Writes the layout's header to the file if it exists.
+ */
+ private void writeHeader() {
+ if (layout == null) {
+ return;
+ }
+ byte[] header = layout.getHeader();
+ if (header == null) {
+ return;
+ }
+ try {
+ // write to the file, not to the buffer: the buffer may not be
empty
+ randomAccessFile.write(header, 0, header.length);
+ } catch (final IOException ioe) {
+ LOGGER.error("Unable to write header", ioe);
+ }
}
public static RollingRandomAccessFileManager
getRollingRandomAccessFileManager(final String fileName,
@@ -99,6 +119,7 @@ public class RollingRandomAccessFileMana
if (isAppend()) {
randomAccessFile.seek(randomAccessFile.length());
}
+ writeHeader();
}
@Override
Added:
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerHeaderFooterTest.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerHeaderFooterTest.java?rev=1604428&view=auto
==============================================================================
---
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerHeaderFooterTest.java
(added)
+++
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerHeaderFooterTest.java
Sat Jun 21 16:34:58 2014
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.appender.rolling;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.nio.charset.Charset;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.layout.HtmlLayout;
+import org.apache.logging.log4j.junit.InitialLoggerContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class RollingRandomAccessFileManagerHeaderFooterTest {
+
+ private static final String DIR =
"target/RollingRandomAccessFileAppenderHeaderFooterTest/";
+ private static final String LOGFILE =
"target/RollingRandomAccessFileAppenderHeaderFooterTest.log";
+
+ @Rule
+ public InitialLoggerContext init = new
InitialLoggerContext("RollingRandomAccessFileAppenderHeaderFooterTest.xml");
+
+ private Logger logger;
+
+ @Before
+ public void setUp() throws Exception {
+ this.logger =
this.init.getLogger(RollingRandomAccessFileManagerHeaderFooterTest.class.getName());
+ deleteDir();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ deleteDir();
+ }
+
+ @Test
+ public void testAppender() throws Exception {
+ for (int i = 0; i < 8; ++i) {
+ logger.debug("This is test message number " + i);
+ }
+ Thread.sleep(50);
+ final File dir = new File(DIR);
+ assertTrue("Directory not created", dir.exists() &&
dir.listFiles().length > 0);
+ final File[] files = dir.listFiles();
+ assertTrue("No files created", files.length > 0);
+ for (final File file : files) {
+ assertHeader(file);
+ assertFooter(file);
+ }
+ final File logFile = new File(LOGFILE);
+ assertTrue("Expected logfile to exist: " + LOGFILE, logFile.exists());
+ assertHeader(logFile);
+ }
+
+ private void assertHeader(File file) throws Exception {
+ HtmlLayout layout = HtmlLayout.createDefaultLayout();
+ String header = new String(layout.getHeader(),
Charset.defaultCharset());
+ String withoutTimestamp = header.substring(0, 435);
+ String contents = new String(slurp(file), Charset.defaultCharset());
+ String contentsInitialChunk = contents.substring(0, 435);
+ assertEquals(file.getName(), withoutTimestamp, contentsInitialChunk);
+ }
+
+ private void assertFooter(File file) throws Exception {
+ HtmlLayout layout = HtmlLayout.createDefaultLayout();
+ String footer = new String(layout.getFooter(),
Charset.defaultCharset());
+ String contents = new String(slurp(file), Charset.defaultCharset());
+ assertTrue(file.getName(), contents.endsWith(footer));
+ }
+
+ private byte[] slurp(File file) throws Exception {
+ FileInputStream in = null;
+ try {
+ in = new FileInputStream(file);
+ byte[] result = new byte[(int) file.length()];
+ int pos = 0;
+ int length = in.read(result);
+ while (length > 0) {
+ pos += length;
+ length = in.read(result, pos, result.length - pos);
+ }
+ return result;
+ } finally {
+ try {
+ in.close();
+ } catch (Exception ignored) {
+ }
+ }
+ }
+
+ private static void deleteDir() {
+ final File dir = new File(DIR);
+ if (dir.exists()) {
+ final File[] files = dir.listFiles();
+ for (final File file : files) {
+ file.delete();
+ }
+ dir.delete();
+ }
+ }
+}
Propchange:
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerHeaderFooterTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
logging/log4j/log4j2/trunk/log4j-core/src/test/resources/RollingRandomAccessFileAppenderHeaderFooterTest.xml
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/resources/RollingRandomAccessFileAppenderHeaderFooterTest.xml?rev=1604428&view=auto
==============================================================================
---
logging/log4j/log4j2/trunk/log4j-core/src/test/resources/RollingRandomAccessFileAppenderHeaderFooterTest.xml
(added)
+++
logging/log4j/log4j2/trunk/log4j-core/src/test/resources/RollingRandomAccessFileAppenderHeaderFooterTest.xml
Sat Jun 21 16:34:58 2014
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="OFF">
+ <Appenders>
+ <RollingRandomAccessFile name="RollingRandomAccessFile"
fileName="target/RollingRandomAccessFileAppenderHeaderFooterTest.log"
+
filePattern="target/RollingRandomAccessFileAppenderHeaderFooterTest/rolled%i.log"
append="false"
+ immediateFlush="true">
+ <HTMLLayout></HTMLLayout>
+ <Policies>
+ <!--
+ <TimeBasedTriggeringPolicy />
+ -->
+ <SizeBasedTriggeringPolicy size="1024" />
+ </Policies>
+ </RollingRandomAccessFile>
+ </Appenders>
+
+ <Loggers>
+ <Root level="trace" includeLocation="false">
+ <AppenderRef ref="RollingRandomAccessFile"/>
+ </Root>
+ </Loggers>
+</Configuration>
\ No newline at end of file
Propchange:
logging/log4j/log4j2/trunk/log4j-core/src/test/resources/RollingRandomAccessFileAppenderHeaderFooterTest.xml
------------------------------------------------------------------------------
svn:eol-style = native
Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/changes/changes.xml?rev=1604428&r1=1604427&r2=1604428&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/changes/changes.xml (original)
+++ logging/log4j/log4j2/trunk/src/changes/changes.xml Sat Jun 21 16:34:58 2014
@@ -22,6 +22,12 @@
</properties>
<body>
<release version="2.0-rc2" date="2014-MM-DD" description="Bug fixes and
enhancements">
+ <action issue="LOG4J2-675" dev="rpopma" type="add">
+ RollingFile and RollingRandomAccessFile now write the layout footer
before rollover.
+ </action>
+ <action issue="LOG4J2-581" dev="rpopma" type="fix" due-to="Alexander
Khokhlov">
+ RollingRandomAccessFile now writes the layout header after rollover.
+ </action>
<action issue="LOG4J2-622" dev="rpopma" type="fix" due-to="Farooq Khan">
RollingFileManager now correctly honours the bufferedIO configuration
after rollover.
</action>