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/03 18:12:50 UTC
[1/3] logging-log4j2 git commit: LOG4J2-1343,
LOG4J2-1344 added OutputStreamByteBufferDestinationAdapter
Repository: logging-log4j2
Updated Branches:
refs/heads/LOG4J2-1344-gc-free-fileappender [created] a0ffd098e
LOG4J2-1343, LOG4J2-1344 added OutputStreamByteBufferDestinationAdapter
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/b7d78338
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/b7d78338
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/b7d78338
Branch: refs/heads/LOG4J2-1344-gc-free-fileappender
Commit: b7d783380d2d6445d33ff68471e7955ef96a3200
Parents: b77edb7
Author: rpopma <rp...@apache.org>
Authored: Mon Apr 4 00:10:55 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Mon Apr 4 00:10:55 2016 +0900
----------------------------------------------------------------------
.../apache/logging/log4j/core/util/Assert.java | 7 ++
...utputStreamByteBufferDestinationAdapter.java | 80 ++++++++++++++++++++
2 files changed, 87 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b7d78338/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Assert.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Assert.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Assert.java
index c7704e2..ff5b1e3 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Assert.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Assert.java
@@ -25,6 +25,13 @@ public final class Assert {
private Assert() {
}
+ public static int valueIsAtLeast(final int value, final int minValue) {
+ if (value < minValue) {
+ throw new IllegalArgumentException("Value should be at least " + minValue + " but was " + value);
+ }
+ return value;
+ }
+
/**
* Throws a {@code NullPointerException} if the specified parameter is
* {@code null}, otherwise returns the specified parameter.
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b7d78338/log4j-core/src/main/java/org/apache/logging/log4j/core/util/OutputStreamByteBufferDestinationAdapter.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/OutputStreamByteBufferDestinationAdapter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/OutputStreamByteBufferDestinationAdapter.java
new file mode 100644
index 0000000..c48582a
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/OutputStreamByteBufferDestinationAdapter.java
@@ -0,0 +1,80 @@
+/*
+ * 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.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.Objects;
+
+import org.apache.logging.log4j.core.layout.ByteBufferDestination;
+import org.apache.logging.log4j.core.util.Assert;
+
+/**
+ * Adapts an OutputStream to the ByteBufferDestination interface.
+ *
+ * @see ByteBufferDestination
+ */
+public class OutputStreamByteBufferDestinationAdapter implements ByteBufferDestination {
+ private static final int DEFAULT_BUFFER_SIZE = 4 * 1024;
+ private final OutputStream out;
+ private final int bufferSize;
+ private ByteBuffer byteBuffer;
+
+ public OutputStreamByteBufferDestinationAdapter(final OutputStream out) {
+ this(out, DEFAULT_BUFFER_SIZE);
+ }
+
+ public OutputStreamByteBufferDestinationAdapter(final OutputStream out, final int bufferSize) {
+ this.out = Objects.requireNonNull(out);
+ this.bufferSize = Assert.valueIsAtLeast(bufferSize, 16);
+ }
+
+ @Override
+ public ByteBuffer getByteBuffer() {
+ if (byteBuffer == null) {
+ byteBuffer = ByteBuffer.wrap(new byte[bufferSize]);
+ }
+ 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}.
+ */
+ public void drain() {
+ drain(getByteBuffer());
+ }
+}
[3/3] logging-log4j2 git commit: LOG4J2-1344 initial gc-free version
(draft)
Posted by rp...@apache.org.
LOG4J2-1344 initial gc-free version (draft)
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/a0ffd098
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/a0ffd098
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/a0ffd098
Branch: refs/heads/LOG4J2-1344-gc-free-fileappender
Commit: a0ffd098ec5b985d70263df8ab6cfab5a77a5be4
Parents: 7aa4dc5
Author: rpopma <rp...@apache.org>
Authored: Mon Apr 4 01:12:42 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Mon Apr 4 01:12:42 2016 +0900
----------------------------------------------------------------------
.../log4j/core/appender/FileManager.java | 21 +++++++++----
.../appender/rolling/RollingFileManager.java | 31 ++++++++++++++++----
2 files changed, 41 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/a0ffd098/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 4de34ad..998695f 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
@@ -29,6 +29,9 @@ 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;
+import org.apache.logging.log4j.core.util.OutputStreamByteBufferDestinationAdapter;
/**
@@ -45,8 +48,8 @@ public class FileManager extends OutputStreamManager {
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);
+ final boolean writeHeader, final ByteBufferDestination destination) {
+ super(os, fileName, layout, writeHeader, destination);
this.isAppend = append;
this.isLocking = locking;
this.advertiseURI = advertiseURI;
@@ -126,7 +129,7 @@ public class FileManager extends OutputStreamManager {
public boolean isLocking() {
return isLocking;
}
-
+
/**
* Returns the buffer size to use if the appender was configured with BufferedIO=true, otherwise returns a negative
* number.
@@ -202,13 +205,21 @@ public class FileManager extends OutputStreamManager {
try {
os = new FileOutputStream(name, data.append);
int bufferSize = data.bufferSize;
+
+ ByteBufferDestination destination = null;
+
+ // if Constants.ENABLE_THREADLOCALS is true, we use ByteBufferDestination to buffer the data
if (data.bufferedIO) {
- os = new BufferedOutputStream(os, bufferSize);
+ if (Constants.ENABLE_THREADLOCALS) {
+ destination = new OutputStreamByteBufferDestinationAdapter(os, bufferSize);
+ } else {
+ 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);
+ writeHeader, destination);
} catch (final FileNotFoundException ex) {
LOGGER.error("FileManager (" + name + ") " + ex, ex);
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/a0ffd098/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 81104e8..314093f 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
@@ -32,7 +32,10 @@ import org.apache.logging.log4j.core.appender.FileManager;
import org.apache.logging.log4j.core.appender.ManagerFactory;
import org.apache.logging.log4j.core.appender.rolling.action.AbstractAction;
import org.apache.logging.log4j.core.appender.rolling.action.Action;
+import org.apache.logging.log4j.core.layout.ByteBufferDestination;
+import org.apache.logging.log4j.core.util.Constants;
import org.apache.logging.log4j.core.util.Log4jThread;
+import org.apache.logging.log4j.core.util.OutputStreamByteBufferDestinationAdapter;
/**
* The Rolling File Manager.
@@ -57,8 +60,9 @@ public class RollingFileManager extends FileManager {
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);
+ final Layout<? extends Serializable> layout, final int bufferSize, final boolean writeHeader,
+ final ByteBufferDestination destination) {
+ super(fileName, os, append, false, advertiseURI, layout, bufferSize, writeHeader, destination);
this.size = size;
this.initialTime = time;
this.triggeringPolicy = triggeringPolicy;
@@ -134,9 +138,16 @@ public class RollingFileManager extends FileManager {
protected void createFileAfterRollover() throws IOException {
final OutputStream os = new FileOutputStream(getFileName(), isAppend());
- if (getBufferSize() > 0) { // negative buffer size means no buffering
- setOutputStream(new BufferedOutputStream(os, getBufferSize()));
+
+ if (getBufferSize() > 0) {
+ if (Constants.ENABLE_THREADLOCALS) {
+ byteBufferDestination.setOutputStream(os);
+ setOutputStream(os);
+ } else {
+ setOutputStream(new BufferedOutputStream(os, getBufferSize()));
+ }
} else {
+ // Negative buffer size means no buffering.
setOutputStream(os);
}
}
@@ -398,18 +409,26 @@ public class RollingFileManager extends FileManager {
}
final long size = data.append ? file.length() : 0;
+ ByteBufferDestination destination = null;
OutputStream os;
try {
os = new FileOutputStream(name, data.append);
int bufferSize = data.bufferSize;
+
+ // if Constants.ENABLE_THREADLOCALS is true,
+ // we use ByteBufferDestination to buffer the data
if (data.bufferedIO) {
- os = new BufferedOutputStream(os, bufferSize);
+ if (Constants.ENABLE_THREADLOCALS) {
+ destination = new OutputStreamByteBufferDestinationAdapter(os, bufferSize);
+ } else {
+ os = new BufferedOutputStream(os, bufferSize);
+ }
} else {
bufferSize = -1; // negative buffer size signals bufferedIO was configured false
}
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, bufferSize, writeHeader, destination);
} catch (final FileNotFoundException ex) {
LOGGER.error("FileManager (" + name + ") " + ex, ex);
}
[2/3] logging-log4j2 git commit: LOG4J2-1343 initial gc-free version
Posted by rp...@apache.org.
LOG4J2-1343 initial gc-free version
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/7aa4dc5a
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/7aa4dc5a
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/7aa4dc5a
Branch: refs/heads/LOG4J2-1344-gc-free-fileappender
Commit: 7aa4dc5ae2b35309f2b84f2d17e4cb909848acc9
Parents: b7d7833
Author: rpopma <rp...@apache.org>
Authored: Mon Apr 4 01:12:02 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Mon Apr 4 01:12:02 2016 +0900
----------------------------------------------------------------------
.../appender/AbstractOutputStreamAppender.java | 21 +++++++++++++++-----
.../core/appender/OutputStreamManager.java | 18 +++++++++++++++++
2 files changed, 34 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7aa4dc5a/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 7ed06d6..3b44efd 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
@@ -20,10 +20,12 @@ 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;
/**
* Appends log events as bytes to a byte output stream. The stream encoding is defined in the layout.
- *
+ *
* @param <M> The kind of {@link OutputStreamManager} under management
*/
public abstract class AbstractOutputStreamAppender<M extends OutputStreamManager> extends AbstractAppender {
@@ -41,7 +43,7 @@ public abstract class AbstractOutputStreamAppender<M extends OutputStreamManager
/**
* Instantiates a WriterAppender and set the output destination to a new {@link java.io.OutputStreamWriter}
* initialized with <code>os</code> as its {@link java.io.OutputStream}.
- *
+ *
* @param name The name of the Appender.
* @param layout The layout to format the message.
* @param manager The OutputStreamManager.
@@ -55,7 +57,7 @@ public abstract class AbstractOutputStreamAppender<M extends OutputStreamManager
/**
* Gets the immediate flush setting.
- *
+ *
* @return immediate flush.
*/
public boolean getImmediateFlush() {
@@ -64,7 +66,7 @@ public abstract class AbstractOutputStreamAppender<M extends OutputStreamManager
/**
* Gets the manager.
- *
+ *
* @return the manager.
*/
public M getManager() {
@@ -93,12 +95,21 @@ public abstract class AbstractOutputStreamAppender<M extends OutputStreamManager
* <p>
* Most subclasses of <code>AbstractOutputStreamAppender</code> will need to override this method.
* </p>
- *
+ *
* @param event The LogEvent.
*/
@Override
public void append(final LogEvent event) {
try {
+ if (Constants.ENABLE_THREADLOCALS) {
+ final ByteBufferDestination destination = manager.getByteBufferDestination();
+ getLayout().encode(event, destination);
+ if (this.immediateFlush || event.isEndOfBatch()) {
+ destination.drain(destination.getByteBuffer()); // write buffer to outputStream
+ manager.flush();
+ }
+ return;
+ }
final byte[] bytes = getLayout().toByteArray(event);
if (bytes != null && bytes.length > 0) {
manager.write(bytes, this.immediateFlush || event.isEndOfBatch());
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7aa4dc5a/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 cb1813e..433c2e0 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
@@ -18,8 +18,11 @@ package org.apache.logging.log4j.core.appender;
import java.io.IOException;
import java.io.OutputStream;
+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.OutputStreamByteBufferDestinationAdapter;
/**
* Manages an OutputStream so that it can be shared by multiple Appenders and will
@@ -29,9 +32,15 @@ public class OutputStreamManager extends AbstractManager {
private volatile OutputStream os;
protected final Layout<?> layout;
+ protected final ByteBufferDestination byteBufferDestination;
protected OutputStreamManager(final OutputStream os, final String streamName, final Layout<?> layout,
final boolean writeHeader) {
+ this(os, streamName, layout, writeHeader, new OutputStreamByteBufferDestinationAdapter(os));
+ }
+
+ protected OutputStreamManager(final OutputStream os, final String streamName, final Layout<?> layout,
+ final boolean writeHeader, final ByteBufferDestination byteBufferDestination) {
super(streamName);
this.os = os;
this.layout = layout;
@@ -45,6 +54,7 @@ public class OutputStreamManager extends AbstractManager {
}
}
}
+ this.byteBufferDestination = Objects.requireNonNull(byteBufferDestination, "byteBufferDestination");
}
/**
@@ -61,6 +71,10 @@ public class OutputStreamManager extends AbstractManager {
return AbstractManager.getManager(name, factory, data);
}
+ public ByteBufferDestination getByteBufferDestination() {
+ return byteBufferDestination;
+ }
+
/**
* Default hook to write footer during close.
*/
@@ -74,6 +88,10 @@ public class OutputStreamManager extends AbstractManager {
* Writes the footer.
*/
protected void writeFooter() {
+ // ensure all buffered data is written to the stream before writing footer
+ final ByteBufferDestination destination = getByteBufferDestination();
+ destination.drain(destination.getByteBuffer());
+
if (layout == null) {
return;
}