You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rp...@apache.org on 2016/04/11 19:53:28 UTC

[01/11] logging-log4j2 git commit: LOG4J2-1343 simplified: OutputStreamManagers now implement ByteBufferDestination

Repository: logging-log4j2
Updated Branches:
  refs/heads/LOG4J2-1343-no-gc-os-appenders-bytebuffered [created] 141bdd2ab


LOG4J2-1343 simplified: OutputStreamManagers now implement ByteBufferDestination


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/7c3aa067
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/7c3aa067
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/7c3aa067

Branch: refs/heads/LOG4J2-1343-no-gc-os-appenders-bytebuffered
Commit: 7c3aa06758be2cbfe3c7c9f45b19d614074fc0d5
Parents: aac2882
Author: rpopma <rp...@apache.org>
Authored: Tue Apr 12 02:26:19 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Tue Apr 12 02:26:19 2016 +0900

----------------------------------------------------------------------
 .../core/appender/AbstractOutputStreamAppender.java     | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7c3aa067/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java
index 85faf43..4a95098 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java
@@ -17,10 +17,10 @@
 package org.apache.logging.log4j.core.appender;
 
 import java.io.Serializable;
+
 import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.layout.ByteBufferDestination;
 import org.apache.logging.log4j.core.util.Constants;
 
 /**
@@ -53,11 +53,6 @@ public abstract class AbstractOutputStreamAppender<M extends OutputStreamManager
         super(name, filter, layout, ignoreExceptions);
         this.manager = manager;
         this.immediateFlush = immediateFlush;
-
-        if (Constants.ENABLE_DIRECT_ENCODERS) {
-            final ByteBufferDestination destination = manager.createByteBufferDestination(immediateFlush);
-            manager.setByteBufferDestination(destination);
-        }
     }
 
     /**
@@ -122,10 +117,7 @@ public abstract class AbstractOutputStreamAppender<M extends OutputStreamManager
     }
 
     protected void directEncodeEvent(final LogEvent event) {
-        getLayout().encode(event, manager.getByteBufferDestination());
-        if (!manager.isBufferedIO()) { // buffering was not requested by the user
-            manager.flushBuffer(); // we're not allowed to leave anything in the buffer: drain buffer into manager
-        }
+        getLayout().encode(event, manager);
         if (this.immediateFlush || event.isEndOfBatch()) {
             manager.flush();
         }


[08/11] logging-log4j2 git commit: LOG4J2-1343 RollingRandomRollingFileManager: simplified now that superclass owns the ByteBuffer

Posted by rp...@apache.org.
LOG4J2-1343 RollingRandomRollingFileManager: simplified now that superclass owns the ByteBuffer


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/294fe587
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/294fe587
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/294fe587

Branch: refs/heads/LOG4J2-1343-no-gc-os-appenders-bytebuffered
Commit: 294fe587dbc7bb9489b68f3c7510b39515532aa4
Parents: d3c029b
Author: rpopma <rp...@apache.org>
Authored: Tue Apr 12 02:40:30 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Tue Apr 12 02:40:30 2016 +0900

----------------------------------------------------------------------
 .../rolling/RollingRandomAccessFileManager.java | 75 ++++----------------
 1 file changed, 12 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/294fe587/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 319cbd6..39f30be 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
@@ -41,24 +41,17 @@ public class RollingRandomAccessFileManager extends RollingFileManager implement
 
     private static final RollingRandomAccessFileManagerFactory FACTORY = new RollingRandomAccessFileManagerFactory();
 
-    private final boolean isImmediateFlush;
     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,
             final long size, final long time, final TriggeringPolicy policy, final RolloverStrategy strategy,
             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;
+        super(fileName, pattern, os, append, size, time, policy, strategy, advertiseURI, layout, writeHeader,
+                ByteBuffer.wrap(new byte[bufferSize]));
         this.randomAccessFile = raf;
         isEndOfBatch.set(Boolean.FALSE);
-        this.buffer = ByteBuffer.wrap(new byte[bufferSize]);
         writeHeader();
     }
 
@@ -97,42 +90,24 @@ public class RollingRandomAccessFileManager extends RollingFileManager implement
         this.isEndOfBatch.set(Boolean.valueOf(endOfBatch));
     }
 
+    // override to make visible for unit tests
     @Override
-    protected synchronized void write(final byte[] bytes, int offset, int length, final boolean immediateFlush) {
-        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();
-        }
+    protected synchronized void write(final byte[] bytes, final int offset, final int length,
+            final boolean immediateFlush) {
+        super.write(bytes, offset, length, immediateFlush);
     }
 
-    private void writeToRandomAccessFile(final byte[] bytes, final int offset, final int length) {
+    @Override
+    protected synchronized void writeToDestination(final byte[] bytes, final int offset, final int length) {
         try {
             randomAccessFile.write(bytes, offset, length);
-            drained += buffer.limit(); // track file size
+            size += length;
         } 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");
@@ -144,11 +119,7 @@ public class RollingRandomAccessFileManager extends RollingFileManager implement
 
     @Override
     public synchronized void flush() {
-        buffer.flip();
-        if (buffer.limit() > 0) {
-            writeToRandomAccessFile(buffer.array(), 0, buffer.limit());
-        }
-        buffer.clear();
+        flushBuffer(byteBuffer);
     }
 
     @Override
@@ -168,28 +139,7 @@ public class RollingRandomAccessFileManager extends RollingFileManager implement
      */
     @Override
     public int getBufferSize() {
-        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;
-    }
-
-    @Override
-    public ByteBuffer drain(final ByteBuffer buf) {
-        flush();
-        return buffer;
+        return byteBuffer.capacity();
     }
 
     /**
@@ -298,8 +248,7 @@ public class RollingRandomAccessFileManager extends RollingFileManager implement
     }
 
     @Override
-    public void updateData(final Object data)
-    {
+    public void updateData(final Object data) {
         final FactoryData factoryData = (FactoryData) data;
         setRolloverStrategy(factoryData.getRolloverStrategy());
         setTriggeringPolicy(factoryData.getTriggeringPolicy());


[10/11] logging-log4j2 git commit: LOG4J2-1343 removed OutputStreamManagerDestination and BytebufferDestinationOutputStream since OutputStreamManager now directly implements the ByteBufferDestination interface

Posted by rp...@apache.org.
LOG4J2-1343 removed OutputStreamManagerDestination and BytebufferDestinationOutputStream since OutputStreamManager now directly implements the ByteBufferDestination interface


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/884830f7
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/884830f7
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/884830f7

Branch: refs/heads/LOG4J2-1343-no-gc-os-appenders-bytebuffered
Commit: 884830f7668553a7ec3334e196544e21a8b8a492
Parents: 382dc41
Author: rpopma <rp...@apache.org>
Authored: Tue Apr 12 02:43:37 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Tue Apr 12 02:43:37 2016 +0900

----------------------------------------------------------------------
 .../OutputStreamManagerDestination.java         |  59 --------
 .../util/ByteBufferDestinationOutputStream.java | 141 -------------------
 2 files changed, 200 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/884830f7/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManagerDestination.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManagerDestination.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManagerDestination.java
deleted file mode 100644
index 18689a1..0000000
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManagerDestination.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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;
-
-import java.nio.ByteBuffer;
-import java.util.Objects;
-
-import org.apache.logging.log4j.core.layout.ByteBufferDestination;
-
-/**
- * Decorates an {@code OutputStreamManager} to adapt it to the {@code ByteBufferDestination} interface.
- */
-public class OutputStreamManagerDestination implements ByteBufferDestination {
-    private static final int DEFAULT_BUFFER_SIZE = 8 * 1024;
-    private final ByteBuffer byteBuffer;
-    private final boolean immediateFlush;
-    private final OutputStreamManager outputStreamManager;
-
-    public OutputStreamManagerDestination(final boolean immediateFlush, final OutputStreamManager outputStreamManager) {
-        this(DEFAULT_BUFFER_SIZE, immediateFlush, outputStreamManager);
-    }
-
-    public OutputStreamManagerDestination(final int bufferSize, final boolean immediateFlush,
-            final OutputStreamManager outputStreamManager) {
-
-        this.byteBuffer = ByteBuffer.wrap(new byte[bufferSize]);
-        this.immediateFlush = immediateFlush;
-        this.outputStreamManager = Objects.requireNonNull(outputStreamManager, "outputStreamManager");
-    }
-
-    @Override
-    public ByteBuffer getByteBuffer() {
-        return byteBuffer;
-    }
-
-    @Override
-    public ByteBuffer drain(final ByteBuffer buf) {
-        buf.flip();
-        if (buf.limit() > 0) {
-            outputStreamManager.write(buf.array(), 0, buf.limit(), immediateFlush);
-        }
-        buf.clear();
-        return buf;
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/884830f7/log4j-core/src/main/java/org/apache/logging/log4j/core/util/ByteBufferDestinationOutputStream.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/ByteBufferDestinationOutputStream.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/ByteBufferDestinationOutputStream.java
deleted file mode 100644
index b6a7ed4..0000000
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/ByteBufferDestinationOutputStream.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * 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.util;
-
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.util.Objects;
-
-import org.apache.logging.log4j.core.layout.ByteBufferDestination;
-
-/**
- * Buffered OutputStream that implements the ByteBufferDestination interface.
- * <p>
- * This class is not thread-safe and it cannot be made thread-safe on its own since it exposes its buffer for direct
- * modification. Client code needs to make sure multiple threads don't modify the buffer or write to this OutputStream
- * concurrently.
- * </p>
- *
- * @see ByteBufferDestination
- */
-public class ByteBufferDestinationOutputStream extends FilterOutputStream implements ByteBufferDestination {
-    private static final int DEFAULT_BUFFER_SIZE = 8 * 1024;
-    private final ByteBuffer byteBuffer;
-
-    public ByteBufferDestinationOutputStream(final OutputStream out) {
-        this(out, DEFAULT_BUFFER_SIZE);
-    }
-
-    public ByteBufferDestinationOutputStream(final OutputStream out, final int bufferSize) {
-        super(Objects.requireNonNull(out));
-        this.byteBuffer = ByteBuffer.wrap(new byte[Assert.valueIsAtLeast(bufferSize, 16)]);
-    }
-
-    @Override
-    public ByteBuffer getByteBuffer() {
-        return byteBuffer;
-    }
-
-    /**
-     * Writes any data in the specified {@code ByteBuffer} to the wrapped {@code OutputStream}, returning the specified
-     * {@code ByteBuffer}.
-     *
-     * @param buf the buffer to drain
-     * @return the specified ByteBuffer
-     */
-    @Override
-    public ByteBuffer drain(final ByteBuffer buf) {
-        buf.flip();
-        try {
-            out.write(buf.array(), 0, buf.limit());
-        } catch (final IOException ex) {
-            throw new IllegalStateException("Could not write " + buf.limit() + " bytes to " + out, ex);
-        }
-        buf.clear();
-        return buf;
-    }
-
-    /**
-     * Writes any data remaining in the {@code ByteBuffer} to the {@code OutputStream}.
-     */
-    /**
-     * Flushes this buffered output stream. This forces any buffered
-     * output bytes to be written out to the underlying output stream.
-     *
-     * @exception  IOException  if an I/O error occurs.
-     * @see        java.io.FilterOutputStream#out
-     */
-    public void flush() {
-        flushBuffer();
-        try {
-            out.flush();
-        } catch (final IOException ex) {
-            throw new IllegalStateException("Could not flush " + out, ex);
-        }
-    }
-
-    private void flushBuffer() {
-        drain(byteBuffer);
-    }
-
-    /**
-     * Writes <code>len</code> bytes from the specified byte array
-     * starting at offset <code>off</code> to this buffered output stream.
-     *
-     * <p> Ordinarily this method stores bytes from the given array into this
-     * stream's buffer, flushing the buffer to the underlying output stream as
-     * needed.  If the requested length is at least as large as this stream's
-     * buffer, however, then this method will flush the buffer and write the
-     * bytes directly to the underlying output stream.  Thus redundant
-     * <code>BufferedOutputStream</code>s will not copy data unnecessarily.
-     *
-     * @param      src     the data.
-     * @param      offset   the start offset in the data.
-     * @param      length   the number of bytes to write.
-     * @exception  IOException  if an I/O error occurs.
-     */
-    public void write(final byte src[], final int offset, final int length) throws IOException {
-        if (length >= byteBuffer.capacity()) {
-            /* If the request length exceeds the size of the output buffer,
-               flush the output buffer and then write the data directly.
-               In this way buffered streams will cascade harmlessly. */
-            flushBuffer();
-            out.write(src, offset, length);
-            return;
-        }
-        if (length > byteBuffer.remaining()) {
-            flushBuffer();
-        }
-        byteBuffer.put(src, offset, length);
-    }
-
-
-    /**
-     * Writes the specified byte to this buffered output stream.
-     *
-     * @param      b   the byte to be written.
-     * @exception  IOException  if an I/O error occurs.
-     */
-    public void write(final int b) throws IOException {
-        if (byteBuffer.remaining() <= 0) {
-            flushBuffer();
-        }
-        byteBuffer.put((byte) b);
-    }
-}


[06/11] logging-log4j2 git commit: LOG4J2-1343 RollingFileManager: removed BufferedOutputStream, use ByteBuffer instead

Posted by rp...@apache.org.
LOG4J2-1343 RollingFileManager: removed BufferedOutputStream, use ByteBuffer instead


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/5c5209be
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/5c5209be
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/5c5209be

Branch: refs/heads/LOG4J2-1343-no-gc-os-appenders-bytebuffered
Commit: 5c5209beb1bb62d87b952f4d599d8b36b7bf212b
Parents: 4855eb8
Author: rpopma <rp...@apache.org>
Authored: Tue Apr 12 02:37:57 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Tue Apr 12 02:37:57 2016 +0900

----------------------------------------------------------------------
 .../appender/rolling/RollingFileManager.java    | 68 ++++++++++----------
 1 file changed, 35 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/5c5209be/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
index 560ec6c..d0b0735 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
@@ -16,13 +16,13 @@
  */
 package org.apache.logging.log4j.core.appender.rolling;
 
-import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.Serializable;
+import java.nio.ByteBuffer;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
 
@@ -55,11 +55,20 @@ public class RollingFileManager extends FileManager {
     private static final AtomicReferenceFieldUpdater<RollingFileManager, RolloverStrategy> rolloverStrategyUpdater =
             AtomicReferenceFieldUpdater.newUpdater(RollingFileManager.class, RolloverStrategy.class, "rolloverStrategy");
 
+    @Deprecated
     protected RollingFileManager(final String fileName, final String pattern, final OutputStream os,
             final boolean append, final long size, final long time, final TriggeringPolicy triggeringPolicy,
             final RolloverStrategy rolloverStrategy, final String advertiseURI,
             final Layout<? extends Serializable> layout, final int bufferSize, final boolean writeHeader) {
-        super(fileName, os, append, false, advertiseURI, layout, bufferSize, writeHeader);
+        this(fileName, pattern, os, append, size, time, triggeringPolicy, rolloverStrategy, advertiseURI, layout,
+                writeHeader, ByteBuffer.wrap(new byte[DEFAULT_BUFFER_SIZE]));
+    }
+
+    protected RollingFileManager(final String fileName, final String pattern, final OutputStream os,
+            final boolean append, final long size, final long time, final TriggeringPolicy triggeringPolicy,
+            final RolloverStrategy rolloverStrategy, final String advertiseURI,
+            final Layout<? extends Serializable> layout, final boolean writeHeader, final ByteBuffer buffer) {
+        super(fileName, os, append, false, advertiseURI, layout, writeHeader, buffer);
         this.size = size;
         this.initialTime = time;
         this.triggeringPolicy = triggeringPolicy;
@@ -83,27 +92,32 @@ public class RollingFileManager extends FileManager {
      */
     public static RollingFileManager getFileManager(final String fileName, final String pattern, final boolean append,
             final boolean bufferedIO, final TriggeringPolicy policy, final RolloverStrategy strategy,
-            final String advertiseURI, final Layout<? extends Serializable> layout, final int bufferSize) {
+            final String advertiseURI, final Layout<? extends Serializable> layout, final int bufferSize,
+            final boolean immediateFlush) {
 
         return (RollingFileManager) getManager(fileName, new FactoryData(pattern, append,
-            bufferedIO, policy, strategy, advertiseURI, layout, bufferSize), factory);
+            bufferedIO, policy, strategy, advertiseURI, layout, bufferSize, immediateFlush), factory);
     }
 
+    // override to make visible for unit tests
     @Override
-    protected synchronized void write(final byte[] bytes, final int offset, final int length, final boolean immediateFlush) {
-        size += length;
+    protected synchronized void write(final byte[] bytes, final int offset, final int length,
+            final boolean immediateFlush) {
         super.write(bytes, offset, length, immediateFlush);
     }
 
+    @Override
+    protected synchronized void writeToDestination(final byte[] bytes, final int offset, final int length) {
+        size += length;
+        super.writeToDestination(bytes, offset, length);
+    }
+
     /**
      * Returns the current size of the file.
      * @return The size of the file in bytes.
      */
     public long getFileSize() {
-        if (Constants.ENABLE_DIRECT_ENCODERS) {
-            return size + getByteBufferDestination().getByteBuffer().position();
-        }
-        return size;
+        return size + byteBuffer.position();
     }
 
     /**
@@ -138,14 +152,7 @@ public class RollingFileManager extends FileManager {
 
     protected void createFileAfterRollover() throws IOException  {
         final OutputStream os = new FileOutputStream(getFileName(), isAppend());
-
-        // when the garbage-free Layout encode mechanism is used
-        // we use a ByteBuffer instead of BufferedOutputStream
-        if (!Constants.ENABLE_DIRECT_ENCODERS && isBufferedIO()) {
-            setOutputStream(new BufferedOutputStream(os, getBufferSize()));
-        } else {
-            setOutputStream(os);
-        }
+        setOutputStream(os);
     }
 
     /**
@@ -156,14 +163,12 @@ public class RollingFileManager extends FileManager {
         return patternProcessor;
     }
 
-    public void setTriggeringPolicy(final TriggeringPolicy triggeringPolicy)
-    {
+    public void setTriggeringPolicy(final TriggeringPolicy triggeringPolicy) {
         triggeringPolicy.initialize(this);
         triggeringPolicyUpdater.compareAndSet(this, this.triggeringPolicy, triggeringPolicy);
     }
 
-    public void setRolloverStrategy(final RolloverStrategy rolloverStrategy)
-    {
+    public void setRolloverStrategy(final RolloverStrategy rolloverStrategy) {
         rolloverStrategyUpdater.compareAndSet(this, this.rolloverStrategy, rolloverStrategy);
     }
 
@@ -307,6 +312,7 @@ public class RollingFileManager extends FileManager {
         private final boolean append;
         private final boolean bufferedIO;
         private final int bufferSize;
+        private final boolean immediateFlush;
         private final TriggeringPolicy policy;
         private final RolloverStrategy strategy;
         private final String advertiseURI;
@@ -320,10 +326,11 @@ public class RollingFileManager extends FileManager {
          * @param advertiseURI
          * @param layout The Layout.
          * @param bufferSize the buffer size
+         * @param immediateFlush flush on every write or not
          */
         public FactoryData(final String pattern, final boolean append, final boolean bufferedIO,
                 final TriggeringPolicy policy, final RolloverStrategy strategy, final String advertiseURI,
-                final Layout<? extends Serializable> layout, final int bufferSize) {
+                final Layout<? extends Serializable> layout, final int bufferSize, final boolean immediateFlush) {
             this.pattern = pattern;
             this.append = append;
             this.bufferedIO = bufferedIO;
@@ -332,6 +339,7 @@ public class RollingFileManager extends FileManager {
             this.strategy = strategy;
             this.advertiseURI = advertiseURI;
             this.layout = layout;
+            this.immediateFlush = immediateFlush;
         }
 
         public TriggeringPolicy getTriggeringPolicy()
@@ -408,18 +416,12 @@ public class RollingFileManager extends FileManager {
             OutputStream os;
             try {
                 os = new FileOutputStream(name, data.append);
-                int bufferSize = data.bufferSize;
-
-                // when the garbage-free Layout encode mechanism is used
-                // we use a ByteBuffer instead of BufferedOutputStream
-                if (!Constants.ENABLE_DIRECT_ENCODERS && data.bufferedIO) {
-                    os = new BufferedOutputStream(os, bufferSize);
-                } else {
-                    bufferSize = -1; // negative buffer size signals bufferedIO was configured false
-                }
+                final int actualSize = data.bufferedIO ? data.bufferSize : DEFAULT_BUFFER_SIZE;
+                final ByteBuffer buffer = ByteBuffer.wrap(new byte[actualSize]);
+
                 final long time = file.lastModified(); // LOG4J2-531 create file first so time has valid value
                 return new RollingFileManager(name, data.pattern, os, data.append, size, time, data.policy,
-                    data.strategy, data.advertiseURI, data.layout, bufferSize, writeHeader);
+                    data.strategy, data.advertiseURI, data.layout, writeHeader, buffer);
             } catch (final FileNotFoundException ex) {
                 LOGGER.error("FileManager (" + name + ") " + ex, ex);
             }


[07/11] logging-log4j2 git commit: LOG4J2-1343 RandomRollingFileManager: simplified now that superclass owns the ByteBuffer

Posted by rp...@apache.org.
LOG4J2-1343 RandomRollingFileManager: simplified now that superclass owns the ByteBuffer


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/d3c029b1
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/d3c029b1
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/d3c029b1

Branch: refs/heads/LOG4J2-1343-no-gc-os-appenders-bytebuffered
Commit: d3c029b1353e43569acdf50c59f478f14723848d
Parents: 5c5209b
Author: rpopma <rp...@apache.org>
Authored: Tue Apr 12 02:39:35 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Tue Apr 12 02:39:35 2016 +0900

----------------------------------------------------------------------
 .../core/appender/RandomAccessFileManager.java  | 63 +++-----------------
 1 file changed, 7 insertions(+), 56 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d3c029b1/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileManager.java
index cbd5eb1..6a2bee5 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileManager.java
@@ -39,22 +39,17 @@ public class RandomAccessFileManager extends OutputStreamManager implements Byte
 
     private static final RandomAccessFileManagerFactory FACTORY = new RandomAccessFileManagerFactory();
 
-    private final boolean isImmediateFlush;
     private final String advertiseURI;
     private final RandomAccessFile randomAccessFile;
-    private final ByteBuffer buffer;
     private final ThreadLocal<Boolean> isEndOfBatch = new ThreadLocal<>();
 
     protected RandomAccessFileManager(final RandomAccessFile file,
-            final String fileName, final OutputStream os,
-            final boolean immediateFlush, final int bufferSize,
+            final String fileName, final OutputStream os, final int bufferSize,
             final String advertiseURI, final Layout<? extends Serializable> layout, final boolean writeHeader) {
-        super(os, fileName, layout, writeHeader);
-        this.isImmediateFlush = immediateFlush;
+        super(os, fileName, layout, writeHeader, ByteBuffer.wrap(new byte[bufferSize]));
         this.randomAccessFile = file;
         this.advertiseURI = advertiseURI;
         this.isEndOfBatch.set(Boolean.FALSE);
-        this.buffer = ByteBuffer.wrap(new byte[bufferSize]);
     }
 
     /**
@@ -86,26 +81,7 @@ public class RandomAccessFileManager extends OutputStreamManager implements Byte
     }
 
     @Override
-    protected synchronized void write(final byte[] bytes, int offset, int length, final boolean immediateFlush) {
-        super.write(bytes, offset, length, immediateFlush); // writes to dummy output stream
-
-        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) {
+    protected void writeToDestination(final byte[] bytes, final int offset, final int length) {
         try {
             randomAccessFile.write(bytes, offset, length);
         } catch (final IOException ex) {
@@ -116,11 +92,7 @@ public class RandomAccessFileManager extends OutputStreamManager implements Byte
 
     @Override
     public synchronized void flush() {
-        buffer.flip();
-        if (buffer.limit() > 0) {
-            writeToRandomAccessFile(buffer.array(), 0, buffer.limit());
-        }
-        buffer.clear();
+        flushBuffer(byteBuffer);
     }
 
     @Override
@@ -147,7 +119,7 @@ public class RandomAccessFileManager extends OutputStreamManager implements Byte
      * @return the buffer size
      */
     public int getBufferSize() {
-        return buffer.capacity();
+        return byteBuffer.capacity();
     }
 
     /**
@@ -167,27 +139,6 @@ public class RandomAccessFileManager extends OutputStreamManager implements Byte
     }
 
     /**
-     * Returns this {@code RandomAccessFileManager}.
-     * @param immediateFlush ignored
-     * @return this {@code RandomAccessFileManager}
-     */
-    @Override
-    protected ByteBufferDestination createByteBufferDestination(final boolean immediateFlush) {
-        return this;
-    }
-
-    @Override
-    public ByteBuffer getByteBuffer() {
-        return buffer;
-    }
-
-    @Override
-    public ByteBuffer drain(final ByteBuffer buf) {
-        flush();
-        return buffer;
-    }
-
-    /**
      * Factory Data.
      */
     private static class FactoryData {
@@ -201,7 +152,7 @@ public class RandomAccessFileManager extends OutputStreamManager implements Byte
          * Constructor.
          *
          * @param append Append status.
-         * @param bufferSize TODO
+         * @param bufferSize size of the buffer
          */
         public FactoryData(final boolean append, final boolean immediateFlush,
                 final int bufferSize, final String advertiseURI, final Layout<? extends Serializable> layout) {
@@ -247,7 +198,7 @@ public class RandomAccessFileManager extends OutputStreamManager implements Byte
                 } else {
                     raf.setLength(0);
                 }
-                return new RandomAccessFileManager(raf, name, os, data.immediateFlush,
+                return new RandomAccessFileManager(raf, name, os,
                         data.bufferSize, data.advertiseURI, data.layout, writeHeader);
             } catch (final Exception ex) {
                 LOGGER.error("RandomAccessFileManager (" + name + ") " + ex, ex);


[09/11] logging-log4j2 git commit: LOG4J2-1343 MemoryMappedFileManager: simplified by leveraging superclass logic

Posted by rp...@apache.org.
LOG4J2-1343 MemoryMappedFileManager: simplified by leveraging superclass logic


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/382dc410
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/382dc410
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/382dc410

Branch: refs/heads/LOG4J2-1343-no-gc-os-appenders-bytebuffered
Commit: 382dc4106fd8b4f3285a1de3d369551faa1ec97e
Parents: 294fe58
Author: rpopma <rp...@apache.org>
Authored: Tue Apr 12 02:42:52 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Tue Apr 12 02:42:52 2016 +0900

----------------------------------------------------------------------
 .../core/appender/MemoryMappedFileManager.java  | 35 +++-----------------
 1 file changed, 5 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/382dc410/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java
index dc9fc88..336b9ee 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java
@@ -76,13 +76,14 @@ public class MemoryMappedFileManager extends OutputStreamManager implements Byte
     protected MemoryMappedFileManager(final RandomAccessFile file, final String fileName, final OutputStream os,
             final boolean force, final long position, final int regionLength, final String advertiseURI,
             final Layout<? extends Serializable> layout, final boolean writeHeader) throws IOException {
-        super(os, fileName, layout, writeHeader);
+        super(os, fileName, layout, writeHeader, ByteBuffer.wrap(new byte[0]));
         this.isForce = force;
         this.randomAccessFile = Objects.requireNonNull(file, "RandomAccessFile");
         this.regionLength = regionLength;
         this.advertiseURI = advertiseURI;
         this.isEndOfBatch.set(Boolean.FALSE);
         this.mappedBuffer = mmap(randomAccessFile.getChannel(), getFileName(), position, regionLength);
+        this.byteBuffer = mappedBuffer;
         this.mappingOffset = position;
     }
 
@@ -113,24 +114,7 @@ public class MemoryMappedFileManager extends OutputStreamManager implements Byte
     }
 
     @Override
-    protected void write(final byte[] bytes) {
-        write(bytes, 0, bytes.length, false);
-    }
-
-    @Override
-    protected void write(final byte[] bytes, final boolean immediateFlush) {
-        write(bytes, 0, bytes.length, immediateFlush);
-    }
-
-    @Override
-    protected void write(final byte[] bytes, final int offset, final int length) {
-        write(bytes, 0, bytes.length, false);
-    }
-
-    @Override
     protected synchronized void write(final byte[] bytes, int offset, int length, final boolean immediateFlush) {
-        super.write(bytes, offset, length, immediateFlush); // writes to dummy output stream
-
         while (length > mappedBuffer.remaining()) {
             final int chunk = mappedBuffer.remaining();
             mappedBuffer.put(bytes, offset, chunk);
@@ -160,6 +144,7 @@ public class MemoryMappedFileManager extends OutputStreamManager implements Byte
                     millis);
 
             mappedBuffer = mmap(randomAccessFile.getChannel(), getFileName(), offset, length);
+            this.byteBuffer = mappedBuffer;
             mappingOffset = offset;
         } catch (final Exception ex) {
             logError("unable to remap", ex);
@@ -284,19 +269,9 @@ public class MemoryMappedFileManager extends OutputStreamManager implements Byte
         return result;
     }
 
-    /**
-     * Returns this {@code MemoryMappedFileManager}.
-     * @param immediateFlush ignored
-     * @return this {@code MemoryMappedFileManager}
-     */
-    @Override
-    protected ByteBufferDestination createByteBufferDestination(final boolean immediateFlush) {
-        return this;
-    }
-
     @Override
-    protected void flushBuffer() {
-        // do nothing (avoid spurious calls to remap())
+    protected void flushBuffer(final ByteBuffer buffer) {
+        // do nothing (do not call drain() to avoid spurious remapping)
     }
 
     @Override


[05/11] logging-log4j2 git commit: LOG4J2-1343 pass immediateFlush boolean to RollingFileManager constructor

Posted by rp...@apache.org.
LOG4J2-1343 pass immediateFlush boolean to RollingFileManager constructor


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/4855eb89
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/4855eb89
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/4855eb89

Branch: refs/heads/LOG4J2-1343-no-gc-os-appenders-bytebuffered
Commit: 4855eb899cab6e4afaec5f4a3e372fb28d7ea2ee
Parents: 96b2f93
Author: rpopma <rp...@apache.org>
Authored: Tue Apr 12 02:33:01 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Tue Apr 12 02:33:01 2016 +0900

----------------------------------------------------------------------
 .../apache/logging/log4j/core/appender/RollingFileAppender.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4855eb89/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java
index 8332953..21d0b91 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java
@@ -189,7 +189,7 @@ public final class RollingFileAppender extends AbstractOutputStreamAppender<Roll
         }
 
         final RollingFileManager manager = RollingFileManager.getFileManager(fileName, filePattern, isAppend,
-            isBuffered, policy, strategy, advertiseURI, layout, bufferSize);
+            isBuffered, policy, strategy, advertiseURI, layout, bufferSize, isFlush);
         if (manager == null) {
             return null;
         }


[11/11] logging-log4j2 git commit: LOG4J2-1343 fix bug in test

Posted by rp...@apache.org.
LOG4J2-1343 fix bug in test


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/141bdd2a
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/141bdd2a
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/141bdd2a

Branch: refs/heads/LOG4J2-1343-no-gc-os-appenders-bytebuffered
Commit: 141bdd2abc28b5546e395e21a7364edbcb8776b0
Parents: 884830f
Author: rpopma <rp...@apache.org>
Authored: Tue Apr 12 02:45:15 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Tue Apr 12 02:45:15 2016 +0900

----------------------------------------------------------------------
 .../core/appender/RandomAccessFileManagerTest.java     | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/141bdd2a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/RandomAccessFileManagerTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/RandomAccessFileManagerTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/RandomAccessFileManagerTest.java
index b048e8a..ac95668 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/RandomAccessFileManagerTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/RandomAccessFileManagerTest.java
@@ -47,9 +47,8 @@ public class RandomAccessFileManagerTest {
         final File file = folder.newFile();
         try (final RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
             final OutputStream os = NullOutputStream.NULL_OUTPUT_STREAM;
-            final RandomAccessFileManager manager = new RandomAccessFileManager(raf, file.getName(), os, false,
+            final RandomAccessFileManager manager = new RandomAccessFileManager(raf, file.getName(), os,
                     RandomAccessFileManager.DEFAULT_BUFFER_SIZE, null, null, true);
-            manager.setByteBufferDestination(manager.createByteBufferDestination(false));
 
             final int size = RandomAccessFileManager.DEFAULT_BUFFER_SIZE * 3;
             final byte[] data = new byte[size];
@@ -69,9 +68,8 @@ public class RandomAccessFileManagerTest {
         final File file = folder.newFile();
         try (final RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
             final OutputStream os = NullOutputStream.NULL_OUTPUT_STREAM;
-            final RandomAccessFileManager manager = new RandomAccessFileManager(raf, file.getName(), os, false,
+            final RandomAccessFileManager manager = new RandomAccessFileManager(raf, file.getName(), os,
                     RandomAccessFileManager.DEFAULT_BUFFER_SIZE, null, null, true);
-            manager.setByteBufferDestination(manager.createByteBufferDestination(false));
 
             final int size = RandomAccessFileManager.DEFAULT_BUFFER_SIZE * 3 + 1;
             final byte[] data = new byte[size];
@@ -91,7 +89,7 @@ public class RandomAccessFileManagerTest {
             final int bufferSize = 4 * 1024;
             assertNotEquals(bufferSize, RandomAccessFileManager.DEFAULT_BUFFER_SIZE);
 
-            final RandomAccessFileManager manager = new RandomAccessFileManager(raf, file.getName(), os, false,
+            final RandomAccessFileManager manager = new RandomAccessFileManager(raf, file.getName(), os,
                     bufferSize, null, null, true);
 
             // check the resulting buffer size is what was requested
@@ -104,9 +102,8 @@ public class RandomAccessFileManagerTest {
         try (final RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
             final OutputStream os = NullOutputStream.NULL_OUTPUT_STREAM;
             final int bufferSize = 1;
-            final RandomAccessFileManager manager = new RandomAccessFileManager(raf, file.getName(), os, false,
+            final RandomAccessFileManager manager = new RandomAccessFileManager(raf, file.getName(), os,
                     bufferSize, null, null, true);
-            manager.setByteBufferDestination(manager.createByteBufferDestination(false));
 
             final int size = bufferSize * 3 + 1;
             final byte[] data = new byte[size];
@@ -135,7 +132,7 @@ public class RandomAccessFileManagerTest {
 
         final RandomAccessFileManager manager = RandomAccessFileManager.getFileManager(
                 file.getAbsolutePath(), isAppend, true, RandomAccessFileManager.DEFAULT_BUFFER_SIZE, null, null);
-        manager.write(bytes, 0, bytes.length, false);
+        manager.write(bytes, 0, bytes.length, true);
         final int expected = bytes.length * 2;
         assertEquals("appended, not overwritten", expected, file.length());
     }


[04/11] logging-log4j2 git commit: LOG4J2-1343 simplified

Posted by rp...@apache.org.
LOG4J2-1343 simplified


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/96b2f930
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/96b2f930
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/96b2f930

Branch: refs/heads/LOG4J2-1343-no-gc-os-appenders-bytebuffered
Commit: 96b2f93070a78f83f682a29de737be2bb1268d07
Parents: 73e601c
Author: rpopma <rp...@apache.org>
Authored: Tue Apr 12 02:32:24 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Tue Apr 12 02:32:24 2016 +0900

----------------------------------------------------------------------
 .../log4j/core/appender/FileManager.java        | 63 +++++++-------------
 1 file changed, 21 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/96b2f930/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileManager.java
index d147127..43372b6 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileManager.java
@@ -16,7 +16,6 @@
  */
 package org.apache.logging.log4j.core.appender;
 
-import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
@@ -30,8 +29,6 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.logging.log4j.core.Layout;
-import org.apache.logging.log4j.core.layout.ByteBufferDestination;
-import org.apache.logging.log4j.core.util.Constants;
 
 
 /**
@@ -46,14 +43,22 @@ public class FileManager extends OutputStreamManager {
     private final String advertiseURI;
     private final int bufferSize;
 
+    @Deprecated
     protected FileManager(final String fileName, final OutputStream os, final boolean append, final boolean locking,
             final String advertiseURI, final Layout<? extends Serializable> layout, final int bufferSize,
             final boolean writeHeader) {
-        super(os, fileName, layout, writeHeader);
+        this(fileName, os, append, locking, advertiseURI, layout, writeHeader, ByteBuffer.wrap(new byte[bufferSize]));
+    }
+
+    /** @since 2.6 */
+    protected FileManager(final String fileName, final OutputStream os, final boolean append, final boolean locking,
+            final String advertiseURI, final Layout<? extends Serializable> layout, final boolean writeHeader,
+            final ByteBuffer buffer) {
+        super(os, fileName, layout, writeHeader, buffer);
         this.isAppend = append;
         this.isLocking = locking;
         this.advertiseURI = advertiseURI;
-        this.bufferSize = bufferSize;
+        this.bufferSize = buffer.capacity();
     }
 
     /**
@@ -65,17 +70,18 @@ public class FileManager extends OutputStreamManager {
      * @param advertiseUri the URI to use when advertising the file
      * @param layout The layout
      * @param bufferSize buffer size for buffered IO
+     * @param immediateFlush true if the contents should be flushed on every write, false otherwise.
      * @return A FileManager for the File.
      */
     public static FileManager getFileManager(final String fileName, final boolean append, boolean locking,
             final boolean bufferedIo, final String advertiseUri, final Layout<? extends Serializable> layout,
-            final int bufferSize) {
+            final int bufferSize, final boolean immediateFlush) {
 
         if (locking && bufferedIo) {
             locking = false;
         }
         return (FileManager) getManager(fileName, new FactoryData(append, locking, bufferedIo, bufferSize,
-                advertiseUri, layout), FACTORY);
+                immediateFlush, advertiseUri, layout), FACTORY);
     }
 
     @Override
@@ -140,29 +146,6 @@ public class FileManager extends OutputStreamManager {
     }
 
     /**
-     * Returns whether the user requested IO to be buffered.
-     * @return whether the buffer size is larger than zero.
-     */
-    @Override
-    protected boolean isBufferedIO() {
-        return bufferSize > 0;
-    }
-
-    /**
-     * Returns a OutputStreamManagerDestination with the user-requested buffer size.
-     * @param immediateFlush the value to pass to the {@link #write(byte[], int, int, boolean)} method when the
-     *          ByteBufferDestination is {@link ByteBufferDestination#drain(ByteBuffer) drained}
-     * @return a OutputStreamManagerDestination with the user-requested buffer size
-     */
-    @Override
-    protected ByteBufferDestination createByteBufferDestination(final boolean immediateFlush) {
-        if (isBufferedIO()) {
-            return new OutputStreamManagerDestination(bufferSize, immediateFlush, this);
-        }
-        return new OutputStreamManagerDestination(immediateFlush, this);
-    }
-
-    /**
      * FileManager's content format is specified by: <code>Key: "fileURI" Value: provided "advertiseURI" param</code>.
      *
      * @return Map of content format keys supporting FileManager
@@ -182,6 +165,7 @@ public class FileManager extends OutputStreamManager {
         private final boolean locking;
         private final boolean bufferedIO;
         private final int bufferSize;
+        private final boolean immediateFlush;
         private final String advertiseURI;
         private final Layout<? extends Serializable> layout;
 
@@ -191,14 +175,16 @@ public class FileManager extends OutputStreamManager {
          * @param locking Locking status.
          * @param bufferedIO Buffering flag.
          * @param bufferSize Buffer size.
+         * @param immediateFlush flush on every write or not
          * @param advertiseURI the URI to use when advertising the file
          */
         public FactoryData(final boolean append, final boolean locking, final boolean bufferedIO, final int bufferSize,
-                final String advertiseURI, final Layout<? extends Serializable> layout) {
+                final boolean immediateFlush, final String advertiseURI, final Layout<? extends Serializable> layout) {
             this.append = append;
             this.locking = locking;
             this.bufferedIO = bufferedIO;
             this.bufferSize = bufferSize;
+            this.immediateFlush = immediateFlush;
             this.advertiseURI = advertiseURI;
             this.layout = layout;
         }
@@ -227,17 +213,10 @@ public class FileManager extends OutputStreamManager {
             OutputStream os;
             try {
                 os = new FileOutputStream(name, data.append);
-                int bufferSize = data.bufferSize;
-
-                // when the garbage-free Layout encode mechanism is used
-                // we use a ByteBuffer instead of BufferedOutputStream
-                if (!Constants.ENABLE_DIRECT_ENCODERS && data.bufferedIO) {
-                    os = new BufferedOutputStream(os, bufferSize);
-                } else {
-                    bufferSize = -1; // signals to RollingFileManager not to use BufferedOutputStream
-                }
-                return new FileManager(name, os, data.append, data.locking, data.advertiseURI, data.layout, bufferSize,
-                        writeHeader);
+                final int actualSize = data.bufferedIO ? data.bufferSize : DEFAULT_BUFFER_SIZE;
+                final ByteBuffer buffer = ByteBuffer.wrap(new byte[actualSize]);
+                return new FileManager(name, os, data.append, data.locking, data.advertiseURI, data.layout,
+                        writeHeader, buffer);
             } catch (final FileNotFoundException ex) {
                 LOGGER.error("FileManager (" + name + ") " + ex, ex);
             }


[02/11] logging-log4j2 git commit: LOG4J2-1343 OutputStreamManager now implements ByteBufferDestination

Posted by rp...@apache.org.
LOG4J2-1343 OutputStreamManager now implements ByteBufferDestination

- subclasses must pass a ByteBuffer to the constructor
- all write() operations get added to the buffer first before being flushed to the destination
- added separate methods for flushBuffer(), flushDestination() and writeToDestination(), subclasses may override


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/f29d6fd1
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/f29d6fd1
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/f29d6fd1

Branch: refs/heads/LOG4J2-1343-no-gc-os-appenders-bytebuffered
Commit: f29d6fd1e3ff852b7fa9fdf1a3b2bc2087591b31
Parents: 7c3aa06
Author: rpopma <rp...@apache.org>
Authored: Tue Apr 12 02:29:37 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Tue Apr 12 02:29:37 2016 +0900

----------------------------------------------------------------------
 .../core/appender/OutputStreamManager.java      | 178 ++++++++++++-------
 1 file changed, 112 insertions(+), 66 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/f29d6fd1/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java
index aff8573..7379804 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java
@@ -19,23 +19,38 @@ package org.apache.logging.log4j.core.appender;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.nio.ByteBuffer;
+import java.util.Objects;
 
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.layout.ByteBufferDestination;
-import org.apache.logging.log4j.core.util.Constants;
 
 /**
  * Manages an OutputStream so that it can be shared by multiple Appenders and will
  * allow appenders to reconfigure without requiring a new stream.
  */
-public class OutputStreamManager extends AbstractManager {
+public class OutputStreamManager extends AbstractManager implements ByteBufferDestination {
+    protected static final int DEFAULT_BUFFER_SIZE = 8 * 1024;
 
     private volatile OutputStream os;
     protected final Layout<?> layout;
-    private ByteBufferDestination byteBufferDestination;
+    protected ByteBuffer byteBuffer;
 
     protected OutputStreamManager(final OutputStream os, final String streamName, final Layout<?> layout,
             final boolean writeHeader) {
+        this(os, streamName, layout, writeHeader, ByteBuffer.wrap(new byte[DEFAULT_BUFFER_SIZE]));
+    }
+
+    /**
+     *
+     * @param os
+     * @param streamName
+     * @param layout
+     * @param writeHeader
+     * @param byteBuffer
+     * @since 2.6
+     */
+    protected OutputStreamManager(final OutputStream os, final String streamName, final Layout<?> layout,
+            final boolean writeHeader, final ByteBuffer byteBuffer) {
         super(streamName);
         this.os = os;
         this.layout = layout;
@@ -49,6 +64,7 @@ public class OutputStreamManager extends AbstractManager {
                 }
             }
         }
+        this.byteBuffer = Objects.requireNonNull(byteBuffer, "byteBuffer");
     }
 
     /**
@@ -114,6 +130,25 @@ public class OutputStreamManager extends AbstractManager {
     }
 
     /**
+     * Some output streams synchronize writes while others do not.
+     * @param bytes The serialized Log event.
+     * @throws AppenderLoggingException if an error occurs.
+     */
+    protected void write(final byte[] bytes)  {
+        write(bytes, 0, bytes.length, false);
+    }
+
+    /**
+     * Some output streams synchronize writes while others do not.
+     * @param bytes The serialized Log event.
+     * @param immediateFlush If true, flushes after writing.
+     * @throws AppenderLoggingException if an error occurs.
+     */
+    protected void write(final byte[] bytes, boolean immediateFlush)  {
+        write(bytes, 0, bytes.length, immediateFlush);
+    }
+
+    /**
      * Some output streams synchronize writes while others do not. Synchronizing here insures that
      * log events won't be intertwined.
      * @param bytes The serialized Log event.
@@ -122,7 +157,6 @@ public class OutputStreamManager extends AbstractManager {
      * @throws AppenderLoggingException if an error occurs.
      */
     protected void write(final byte[] bytes, final int offset, final int length) {
-        flushBuffer();
         write(bytes, offset, length, false);
     }
 
@@ -137,11 +171,32 @@ public class OutputStreamManager extends AbstractManager {
      */
     protected synchronized void write(final byte[] bytes, final int offset, final int length, boolean immediateFlush) {
         // System.out.println("write " + count);
+        if (length >= byteBuffer.capacity()) {
+            // if request length exceeds buffer capacity, flush the buffer and write the data directly
+            flush();
+            writeToDestination(bytes, offset, length);
+        } else {
+            if (length > byteBuffer.remaining()) {
+                flush();
+            }
+            byteBuffer.put(bytes, offset, length);
+        }
+        if (immediateFlush) {
+            flush();
+        }
+    }
+
+    /**
+     * Writes the specified section of the specified byte array to the stream.
+     *
+     * @param bytes the array containing data
+     * @param offset from where to write
+     * @param length how many bytes to write
+     * @since 2.6
+     */
+    protected synchronized void writeToDestination(final byte[] bytes, final int offset, final int length) {
         try {
             os.write(bytes, offset, length);
-            if (immediateFlush) {
-                os.flush();
-            }
         } catch (final IOException ex) {
             final String msg = "Error writing to stream " + getName();
             throw new AppenderLoggingException(msg, ex);
@@ -149,24 +204,40 @@ public class OutputStreamManager extends AbstractManager {
     }
 
     /**
-     * Some output streams synchronize writes while others do not.
-     * @param bytes The serialized Log event.
-     * @throws AppenderLoggingException if an error occurs.
+     * Calls {@code flush()} on the underlying output stream.
+     * @since 2.6
      */
-    protected void write(final byte[] bytes)  {
-        flushBuffer();
-        write(bytes, 0, bytes.length, false);
+    protected synchronized void flushDestination() {
+        try {
+            os.flush();
+        } catch (final IOException ex) {
+            final String msg = "Error flushing stream " + getName();
+            throw new AppenderLoggingException(msg, ex);
+        }
     }
 
     /**
-     * Some output streams synchronize writes while others do not.
-     * @param bytes The serialized Log event.
-     * @param immediateFlush If true, flushes after writing.
-     * @throws AppenderLoggingException if an error occurs.
+     * Drains the ByteBufferDestination's buffer into the destination. By default this calls
+     * {@link OutputStreamManager#write(byte[], int, int, boolean)} with the buffer contents.
+     * The underlying stream is not {@linkplain OutputStream#flush() flushed}.
+     *
+     * @see #flushDestination()
+     * @since 2.6
      */
-    protected void write(final byte[] bytes, boolean immediateFlush)  {
-        flushBuffer();
-        write(bytes, 0, bytes.length, immediateFlush);
+    protected synchronized void flushBuffer(final ByteBuffer buf) {
+        buf.flip();
+        if (buf.limit() > 0) {
+            writeToDestination(buf.array(), 0, buf.limit());
+        }
+        buf.clear();
+    }
+
+    /**
+     * Flushes any buffers.
+     */
+    public synchronized void flush() {
+        flushBuffer(byteBuffer);
+        flushDestination();
     }
 
     protected synchronized void close() {
@@ -183,60 +254,35 @@ public class OutputStreamManager extends AbstractManager {
     }
 
     /**
-     * Flushes any buffers.
+     * Returns this {@code ByteBufferDestination}'s buffer.
+     * @return the buffer
+     * @since 2.6
      */
-    public synchronized void flush() {
-        try {
-            flushBuffer();
-            os.flush();
-        } catch (final IOException ex) {
-            final String msg = "Error flushing stream " + getName();
-            throw new AppenderLoggingException(msg, ex);
-        }
+    @Override
+    public ByteBuffer getByteBuffer() {
+        return byteBuffer;
     }
 
     /**
      * Drains the ByteBufferDestination's buffer into the destination. By default this calls
-     * {@link OutputStreamManager#write(byte[], int, int, boolean)} with the buffer contents and the Appender's
-     * {@link AbstractOutputStreamAppender#immediateFlush} value.
+     * {@link #flushBuffer(ByteBuffer)} with the specified buffer. Subclasses may override.
      * <p>
-     * This method has no effect if the garbage-free Layout encode mechanism is not enabled.
+     * Do not call this method lightly! For some subclasses this is a very expensive operation. For example,
+     * {@link MemoryMappedFileManager} will assume this method was called because the end of the mapped region
+     * was reached during a text encoding operation and will {@linkplain MemoryMappedFileManager#remap() remap} its
+     * buffer.
+     * </p><p>
+     * To just flush the buffered contents to the underlying stream, call
+     * {@link #flushBuffer(ByteBuffer)} directly instead.
      * </p>
-     */
-    protected void flushBuffer() {
-        if (Constants.ENABLE_DIRECT_ENCODERS) {
-            final ByteBufferDestination destination = getByteBufferDestination();
-            synchronized (destination) {
-                destination.drain(destination.getByteBuffer());
-            }
-        }
-    }
-
-    /**
-     * Subclasses that do buffered IO should override.
-     * @return this implementation always returns {@code false}
-     */
-    protected boolean isBufferedIO() {
-        return false;
-    }
-
-    public ByteBufferDestination getByteBufferDestination() {
-        return byteBufferDestination;
-    }
-
-    public void setByteBufferDestination(final ByteBufferDestination byteBufferDestination) {
-        this.byteBufferDestination = byteBufferDestination;
-    }
-
-    /**
-     * When the garbage-free Layout.encode mechanism is used, this method is called to create a ByteBufferDestination
-     * for this OutputStreamManager.
      *
-     * @param immediateFlush the value to pass to the {@link #write(byte[], int, int, boolean)} method when the
-     *          ByteBufferDestination is {@link ByteBufferDestination#drain(ByteBuffer) drained}
-     * @return a new ByteBufferDestination that drains into this OutputStreamManager
+     * @param buf the buffer whose contents to write the the destination
+     * @return the specified buffer
+     * @since 2.6
      */
-    protected ByteBufferDestination createByteBufferDestination(final boolean immediateFlush) {
-        return new OutputStreamManagerDestination(immediateFlush, this);
+    @Override
+    public ByteBuffer drain(final ByteBuffer buf) {
+        flushBuffer(buf);
+        return buf;
     }
 }


[03/11] logging-log4j2 git commit: LOG4J2-1343 pass immediateFlush boolean to FileManager constructor

Posted by rp...@apache.org.
LOG4J2-1343 pass immediateFlush boolean to FileManager constructor


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/73e601c3
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/73e601c3
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/73e601c3

Branch: refs/heads/LOG4J2-1343-no-gc-os-appenders-bytebuffered
Commit: 73e601c3c42c8167527946a582e56257ae88f28d
Parents: f29d6fd
Author: rpopma <rp...@apache.org>
Authored: Tue Apr 12 02:30:36 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Tue Apr 12 02:30:36 2016 +0900

----------------------------------------------------------------------
 .../org/apache/logging/log4j/core/appender/FileAppender.java   | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/73e601c3/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java
index 587ba80..90c088e 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java
@@ -47,7 +47,7 @@ public final class FileAppender extends AbstractOutputStreamAppender<FileManager
     private FileAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
             final FileManager manager, final String filename, final boolean ignoreExceptions,
             final boolean immediateFlush, final Advertiser advertiser) {
-        
+
         super(name, layout, filter, ignoreExceptions, immediateFlush, manager);
         if (advertiser != null) {
             final Map<String, String> configuration = new HashMap<>(layout.getContentFormat());
@@ -145,12 +145,12 @@ public final class FileAppender extends AbstractOutputStreamAppender<FileManager
         }
 
         final FileManager manager = FileManager.getFileManager(fileName, isAppend, isLocking, isBuffered, advertiseUri,
-            layout, bufferSize);
+                layout, bufferSize, isFlush);
         if (manager == null) {
             return null;
         }
 
-        return new FileAppender(name, layout, filter, manager, fileName, ignoreExceptions, isFlush,
+        return new FileAppender(name, layout, filter, manager, fileName, ignoreExceptions, !isBuffered || isFlush,
                 isAdvertise ? config.getAdvertiser() : null);
     }
 }