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/15 18:42:43 UTC
logging-log4j2 git commit: LOG4J2-1334 allow
AsyncLoggerConfigDisruptor ringbuffer to be pre-allocated with
MutableLogEvents, add translator that updates instead of replaces LogEvents
Repository: logging-log4j2
Updated Branches:
refs/heads/master afb720740 -> 65480fdde
LOG4J2-1334 allow AsyncLoggerConfigDisruptor ringbuffer to be pre-allocated with MutableLogEvents, add translator that updates instead of replaces LogEvents
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/65480fdd
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/65480fdd
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/65480fdd
Branch: refs/heads/master
Commit: 65480fdde64bb38de19dbfcedfb56bc40c7b62da
Parents: afb7207
Author: rpopma <rp...@apache.org>
Authored: Sat Apr 16 01:42:41 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Sat Apr 16 01:42:41 2016 +0900
----------------------------------------------------------------------
.../log4j/core/async/AsyncLoggerConfig.java | 1 +
.../core/async/AsyncLoggerConfigDelegate.java | 10 +++
.../core/async/AsyncLoggerConfigDisruptor.java | 66 +++++++++++++++++---
3 files changed, 70 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/65480fdd/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfig.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfig.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfig.java
index f1c6800..15d3491 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfig.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfig.java
@@ -78,6 +78,7 @@ public class AsyncLoggerConfig extends LoggerConfig {
super(name, appenders, filter, level, additive, properties, config,
includeLocation);
delegate = config.getAsyncLoggerConfigDelegate();
+ delegate.setLogEventFactory(getLogEventFactory());
}
/**
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/65480fdd/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigDelegate.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigDelegate.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigDelegate.java
index 5cbe0e4..0e230bb 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigDelegate.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigDelegate.java
@@ -19,6 +19,7 @@ package org.apache.logging.log4j.core.async;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.impl.LogEventFactory;
import org.apache.logging.log4j.core.jmx.RingBufferAdmin;
/**
@@ -48,4 +49,13 @@ public interface AsyncLoggerConfigDelegate {
void enqueueEvent(LogEvent event, AsyncLoggerConfig asyncLoggerConfig);
boolean tryEnqueue(LogEvent event, AsyncLoggerConfig asyncLoggerConfig);
+
+ /**
+ * Notifies the delegate what LogEventFactory an AsyncLoggerConfig is using, so the delegate can determine
+ * whether to populate the ring buffer with mutable log events or not. This method may be invoced multiple times
+ * for all AsyncLoggerConfigs that use this delegate.
+ *
+ * @param logEventFactory the factory used
+ */
+ void setLogEventFactory(LogEventFactory logEventFactory);
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/65480fdd/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigDisruptor.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigDisruptor.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigDisruptor.java
index 8f5cec7..2c1b84f 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigDisruptor.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigDisruptor.java
@@ -24,6 +24,9 @@ import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
+import org.apache.logging.log4j.core.impl.LogEventFactory;
+import org.apache.logging.log4j.core.impl.MutableLogEvent;
+import org.apache.logging.log4j.core.impl.ReusableLogEventFactory;
import org.apache.logging.log4j.core.jmx.RingBufferAdmin;
import org.apache.logging.log4j.core.util.Constants;
import org.apache.logging.log4j.message.ReusableMessage;
@@ -57,13 +60,17 @@ public class AsyncLoggerConfigDisruptor implements AsyncLoggerConfigDelegate {
private static final int SLEEP_MILLIS_BETWEEN_DRAIN_ATTEMPTS = 50;
private static final Logger LOGGER = StatusLogger.getLogger();
- private int ringBufferSize;
- private AsyncEventRouter asyncEventRouter;
-
/**
* RingBuffer events contain all information necessary to perform the work in a separate thread.
*/
public static class Log4jEventWrapper {
+ public Log4jEventWrapper() {
+ }
+
+ public Log4jEventWrapper(MutableLogEvent mutableLogEvent) {
+ event = mutableLogEvent;
+ }
+
private AsyncLoggerConfig loggerConfig;
private LogEvent event;
@@ -72,7 +79,11 @@ public class AsyncLoggerConfigDisruptor implements AsyncLoggerConfigDelegate {
*/
public void clear() {
loggerConfig = null;
- event = null;
+ if (event instanceof MutableLogEvent) {
+ ((MutableLogEvent) event).clear();
+ } else {
+ event = null;
+ }
}
@Override
@@ -128,6 +139,17 @@ public class AsyncLoggerConfigDisruptor implements AsyncLoggerConfigDelegate {
};
/**
+ * Factory used to populate the RingBuffer with events. These event objects are then re-used during the life of the
+ * RingBuffer.
+ */
+ private static final EventFactory<Log4jEventWrapper> MUTABLE_FACTORY = new EventFactory<Log4jEventWrapper>() {
+ @Override
+ public Log4jEventWrapper newInstance() {
+ return new Log4jEventWrapper(new MutableLogEvent());
+ }
+ };
+
+ /**
* Object responsible for passing on data to a specific RingBuffer event.
*/
private static final EventTranslatorTwoArg<Log4jEventWrapper, LogEvent, AsyncLoggerConfig> TRANSLATOR =
@@ -141,15 +163,43 @@ public class AsyncLoggerConfigDisruptor implements AsyncLoggerConfigDelegate {
}
};
+ /**
+ * Object responsible for passing on data to a RingBuffer event with a MutableLogEvent.
+ */
+ private static final EventTranslatorTwoArg<Log4jEventWrapper, LogEvent, AsyncLoggerConfig> MUTABLE_TRANSLATOR =
+ new EventTranslatorTwoArg<Log4jEventWrapper, LogEvent, AsyncLoggerConfig>() {
+
+ @Override
+ public void translateTo(final Log4jEventWrapper ringBufferElement, final long sequence,
+ final LogEvent logEvent, final AsyncLoggerConfig loggerConfig) {
+ ((MutableLogEvent) ringBufferElement.event).initFrom(logEvent);
+ ringBufferElement.loggerConfig = loggerConfig;
+ }
+ };
+
private static final ThreadFactory THREAD_FACTORY = new DaemonThreadFactory("AsyncLoggerConfig-");
+ private int ringBufferSize;
+ private AsyncEventRouter asyncEventRouter;
+ private Boolean mutable = Boolean.FALSE;
+
private volatile Disruptor<Log4jEventWrapper> disruptor;
private ExecutorService executor;
private long backgroundThreadId; // LOG4J2-471
+ private EventFactory<Log4jEventWrapper> factory;
+ private EventTranslatorTwoArg<Log4jEventWrapper, LogEvent, AsyncLoggerConfig> translator;
public AsyncLoggerConfigDisruptor() {
}
+ // called from AsyncLoggerConfig constructor
+ @Override
+ public void setLogEventFactory(final LogEventFactory logEventFactory) {
+ // if any AsyncLoggerConfig uses a ReusableLogEventFactory
+ // then we need to populate our ringbuffer with MutableLogEvents
+ this.mutable = mutable || (logEventFactory instanceof ReusableLogEventFactory);
+ }
+
/**
* Increases the reference count and creates and starts a new Disruptor and associated thread if none currently
* exists.
@@ -169,7 +219,9 @@ public class AsyncLoggerConfigDisruptor implements AsyncLoggerConfigDelegate {
backgroundThreadId = DisruptorUtil.getExecutorThreadId(executor);
asyncEventRouter = AsyncEventRouterFactory.create();
- disruptor = new Disruptor<>(FACTORY, ringBufferSize, executor, ProducerType.MULTI, waitStrategy);
+ translator = mutable ? MUTABLE_TRANSLATOR : TRANSLATOR;
+ factory = mutable ? MUTABLE_FACTORY : FACTORY;
+ disruptor = new Disruptor<>(factory, ringBufferSize, executor, ProducerType.MULTI, waitStrategy);
final ExceptionHandler<Log4jEventWrapper> errorHandler = DisruptorUtil.getAsyncLoggerConfigExceptionHandler();
disruptor.handleExceptionsWith(errorHandler);
@@ -279,13 +331,13 @@ public class AsyncLoggerConfigDisruptor implements AsyncLoggerConfigDelegate {
}
private void enqueue(final LogEvent logEvent, final AsyncLoggerConfig asyncLoggerConfig) {
- disruptor.getRingBuffer().publishEvent(TRANSLATOR, logEvent, asyncLoggerConfig);
+ disruptor.getRingBuffer().publishEvent(translator, logEvent, asyncLoggerConfig);
}
@Override
public boolean tryEnqueue(final LogEvent event, final AsyncLoggerConfig asyncLoggerConfig) {
final LogEvent logEvent = prepareEvent(event);
- return disruptor.getRingBuffer().tryPublishEvent(TRANSLATOR, logEvent, asyncLoggerConfig);
+ return disruptor.getRingBuffer().tryPublishEvent(translator, logEvent, asyncLoggerConfig);
}
private LogEvent ensureImmutable(final LogEvent event) {