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 2015/08/16 07:09:50 UTC

logging-log4j2 git commit: refactor: break up larger methods to clarify intention and facilitate JVM inlining

Repository: logging-log4j2
Updated Branches:
  refs/heads/master ad0eaf476 -> b2ef74c7e


refactor: break up larger methods to clarify intention and facilitate
JVM inlining

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

Branch: refs/heads/master
Commit: b2ef74c7edd50a0eb8f2f7f2e572c39597695e4f
Parents: ad0eaf4
Author: rpopma <rp...@apache.org>
Authored: Sun Aug 16 14:09:55 2015 +0900
Committer: rpopma <rp...@apache.org>
Committed: Sun Aug 16 14:09:55 2015 +0900

----------------------------------------------------------------------
 .../core/async/AsyncLoggerConfigHelper.java     | 96 ++++++++++++++------
 1 file changed, 66 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b2ef74c7/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigHelper.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigHelper.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigHelper.java
index c4fe1d2..a81d8fa 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigHelper.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigHelper.java
@@ -218,9 +218,15 @@ class AsyncLoggerConfigHelper {
             event.loggerConfig.asyncCallAppenders(event.event);
             event.clear();
 
-            // notify the BatchEventProcessor that the sequence has progressed.
-            // Without this callback the sequence would not be progressed
-            // until the batch has completely finished.
+            notifyIntermediateProgress(sequence);
+        }
+
+        /**
+         * Notify the BatchEventProcessor that the sequence has progressed.
+         * Without this callback the sequence would not be progressed
+         * until the batch has completely finished.
+         */
+        private void notifyIntermediateProgress(final long sequence) {
             if (++counter > NOTIFY_PROGRESS_THRESHOLD) {
                 sequenceCallback.set(sequence);
                 counter = 0;
@@ -312,43 +318,73 @@ class AsyncLoggerConfigHelper {
      *          calling thread needs to process the event itself
      */
     public boolean callAppendersFromAnotherThread(final LogEvent event) {
-        // TODO refactor to reduce size to <= 35 bytecodes to allow JVM to inline it
         final Disruptor<Log4jEventWrapper> temp = disruptor;
-        if (temp == null) { // LOG4J2-639
+        if (!hasLog4jBeenShutDown(temp)) {
+
+            // LOG4J2-471: prevent deadlock when RingBuffer is full and object
+            // being logged calls Logger.log() from its toString() method
+            if (isCalledFromAppenderThreadAndBufferFull(temp)) {
+                // bypass RingBuffer and invoke Appender directly
+                return false;
+            }
+            enqueueEvent(event);
+        }
+        return true;
+    }
+
+    /**
+     * Returns {@code true} if the specified disruptor is null.
+     */
+    private boolean hasLog4jBeenShutDown(final Disruptor<Log4jEventWrapper> aDisruptor) {
+        if (aDisruptor == null) { // LOG4J2-639
             LOGGER.fatal("Ignoring log event after log4j was shut down");
             return true;
         }
+        return false;
+    }
 
-        // LOG4J2-471: prevent deadlock when RingBuffer is full and object
-        // being logged calls Logger.log() from its toString() method
-        if (isAppenderThread.get() == Boolean.TRUE //
-                && temp.getRingBuffer().remainingCapacity() == 0) {
-
-            // bypass RingBuffer and invoke Appender directly
-            return false;
-        }
+    private void enqueueEvent(final LogEvent event) {
         // LOG4J2-639: catch NPE if disruptor field was set to null after our check above
         try {
-            LogEvent logEvent = event;
-            if (event instanceof RingBufferLogEvent) {
-                // Deal with special case where both types of Async Loggers are used together:
-                // RingBufferLogEvents are created by the all-loggers-async type, but
-                // this event is also consumed by the some-loggers-async type (this class).
-                // The original event will be re-used and modified in an application thread later,
-                // so take a snapshot of it, which can be safely processed in the
-                // some-loggers-async background thread.
-                logEvent = ((RingBufferLogEvent) event).createMemento();
-            }
-            logEvent.getMessage().getFormattedMessage(); // LOG4J2-763: ask message to freeze parameters
-
-            // Note: do NOT use the temp variable above!
-            // That could result in adding a log event to the disruptor after it was shut down,
-            // which could cause the publishEvent method to hang and never return.
-            disruptor.getRingBuffer().publishEvent(translator, logEvent, asyncLoggerConfig);
+            final LogEvent logEvent = prepareEvent(event);
+            enqueue(logEvent);
         } catch (final NullPointerException npe) {
             LOGGER.fatal("Ignoring log event after log4j was shut down.");
         }
-        return true;
+    }
+
+    private LogEvent prepareEvent(final LogEvent event) {
+        final LogEvent logEvent = ensureImmutable(event);
+        logEvent.getMessage().getFormattedMessage(); // LOG4J2-763: ask message to freeze parameters
+        return logEvent;
+    }
+
+    private void enqueue(LogEvent logEvent) {
+        // Note: do NOT use the temp variable above!
+        // That could result in adding a log event to the disruptor after it was shut down,
+        // which could cause the publishEvent method to hang and never return.
+        disruptor.getRingBuffer().publishEvent(translator, logEvent, asyncLoggerConfig);
+    }
+
+    private LogEvent ensureImmutable(final LogEvent event) {
+        LogEvent result = event;
+        if (event instanceof RingBufferLogEvent) {
+            // Deal with special case where both types of Async Loggers are used together:
+            // RingBufferLogEvents are created by the all-loggers-async type, but
+            // this event is also consumed by the some-loggers-async type (this class).
+            // The original event will be re-used and modified in an application thread later,
+            // so take a snapshot of it, which can be safely processed in the
+            // some-loggers-async background thread.
+            result = ((RingBufferLogEvent) event).createMemento();
+        }
+        return result;
+    }
+
+    /**
+     * Returns true if the specified ringbuffer is full and the Logger.log() call was made from the appender thread.
+     */
+    private boolean isCalledFromAppenderThreadAndBufferFull(Disruptor<Log4jEventWrapper> disruptor) {
+        return isAppenderThread.get() == Boolean.TRUE && disruptor.getRingBuffer().remainingCapacity() == 0;
     }
 
     /**