LOG4J2-1343 refactored RollingRandomAccessFileManager to reuse the garbage-free Layout mechanism defined in the superclass, simplified logic when bytes to write exceed buffer size, take unwritten buffered bytes into account when deciding when to roll over
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/cb33b0fe Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/cb33b0fe Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/cb33b0fe Branch: refs/heads/LOG4J2-1356 Commit: cb33b0feb91f8be1c139270717da6ffc08513e36 Parents: 32e557b Author: rpopma <[email protected]> Authored: Thu Apr 7 03:05:35 2016 +0900 Committer: rpopma <[email protected]> Committed: Thu Apr 7 03:05:35 2016 +0900 ---------------------------------------------------------------------- .../rolling/RollingRandomAccessFileManager.java | 59 ++++++++++++++------ 1 file changed, 43 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/cb33b0fe/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java index 02c47e0..5c4ae10 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java @@ -45,6 +45,8 @@ public class RollingRandomAccessFileManager extends RollingFileManager implement private RandomAccessFile randomAccessFile; private final ByteBuffer buffer; private final ThreadLocal<Boolean> isEndOfBatch = new ThreadLocal<>(); + private long drained; + private final long startSize; public RollingRandomAccessFileManager(final RandomAccessFile raf, final String fileName, final String pattern, final OutputStream os, final boolean append, final boolean immediateFlush, final int bufferSize, @@ -52,6 +54,7 @@ public class RollingRandomAccessFileManager extends RollingFileManager implement final String advertiseURI, final Layout<? extends Serializable> layout, final boolean writeHeader) { super(fileName, pattern, os, append, size, time, policy, strategy, advertiseURI, layout, bufferSize, writeHeader); + this.startSize = size; this.isImmediateFlush = immediateFlush; this.randomAccessFile = raf; isEndOfBatch.set(Boolean.FALSE); @@ -96,22 +99,40 @@ public class RollingRandomAccessFileManager extends RollingFileManager implement @Override protected synchronized void write(final byte[] bytes, int offset, int length, final boolean immediateFlush) { - int chunk = 0; - do { - if (length > buffer.remaining()) { - flush(); - } - chunk = Math.min(length, buffer.remaining()); - buffer.put(bytes, offset, chunk); - offset += chunk; - length -= chunk; - } while (length > 0); + if (length >= buffer.capacity()) { + // if request length exceeds buffer capacity, flush the buffer and write the data directly + flush(); + writeToRandomAccessFile(bytes, offset, length); + return; + } + if (length > buffer.remaining()) { + flush(); + } + buffer.put(bytes, offset, length); if (immediateFlush || isImmediateFlush || isEndOfBatch.get() == Boolean.TRUE) { flush(); } } + private void writeToRandomAccessFile(final byte[] bytes, final int offset, final int length) { + try { + randomAccessFile.write(bytes, offset, length); + drained += buffer.limit(); // track file size + } catch (final IOException ex) { + final String msg = "Error writing to RandomAccessFile " + getName(); + throw new AppenderLoggingException(msg, ex); + } + } + + /** + * Returns the current size of the file. + * @return The size of the file in bytes. + */ + public long getFileSize() { + return startSize + drained + getByteBufferDestination().getByteBuffer().position(); + } + @Override protected void createFileAfterRollover() throws IOException { this.randomAccessFile = new RandomAccessFile(getFileName(), "rw"); @@ -124,12 +145,8 @@ public class RollingRandomAccessFileManager extends RollingFileManager implement @Override public synchronized void flush() { buffer.flip(); - try { - randomAccessFile.write(buffer.array(), 0, buffer.limit()); - size += buffer.limit(); // track file size - } catch (final IOException ex) { - final String msg = "Error writing to RandomAccessFile " + getName(); - throw new AppenderLoggingException(msg, ex); + if (buffer.limit() > 0) { + writeToRandomAccessFile(buffer.array(), 0, buffer.limit()); } buffer.clear(); } @@ -154,6 +171,16 @@ public class RollingRandomAccessFileManager extends RollingFileManager implement return buffer.capacity(); } + /** + * Returns this {@code RollingRandomAccessFileManager}. + * @param immediateFlush ignored + * @return this {@code RollingRandomAccessFileManager} + */ + @Override + protected ByteBufferDestination createByteBufferDestination(final boolean immediateFlush) { + return this; + } + @Override public ByteBuffer getByteBuffer() { return buffer;
