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) {