diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestCachedThreadName.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestCachedThreadName.java deleted file mode 100644 index 639d519a67f..00000000000 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestCachedThreadName.java +++ /dev/null @@ -1,63 +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.async; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.core.impl.Log4jPropertyKey; -import org.apache.logging.log4j.core.test.CoreLoggerContexts; -import org.apache.logging.log4j.core.test.junit.ContextSelectorType; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.junitpioneer.jupiter.SetSystemProperty; - -@Tag("async") -@ContextSelectorType(AsyncLoggerContextSelector.class) -@SetSystemProperty(key = Log4jPropertyKey.Constant.CONFIG_LOCATION, value = "AsyncLoggerTest.xml") -public class AsyncLoggerTestCachedThreadName { - - @Test - public void testAsyncLogUsesCachedThreadName() throws Exception { - final File file = new File("target", "AsyncLoggerTest.log"); - // System.out.println(f.getAbsolutePath()); - file.delete(); - final Logger log = LogManager.getLogger("com.foo.Bar"); - final String msg = "Async logger msg"; - log.info(msg); - Thread.currentThread().setName("MODIFIED-THREADNAME"); - log.info(msg); - CoreLoggerContexts.stopLoggerContext(file); // stop async thread - - final BufferedReader reader = new BufferedReader(new FileReader(file)); - final String line1 = reader.readLine(); - final String line2 = reader.readLine(); - // System.out.println(line1); - // System.out.println(line2); - reader.close(); - file.delete(); - assertNotNull(line1, "line1"); - assertNotNull(line2, "line2"); - assertTrue(line1.endsWith(" INFO c.f.Bar [main] Async logger msg "), "line1"); - assertTrue(line2.endsWith(" INFO c.f.Bar [main] Async logger msg "), "line2"); - } -} diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestUncachedThreadName.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestUncachedThreadName.java deleted file mode 100644 index e9295b45ad1..00000000000 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestUncachedThreadName.java +++ /dev/null @@ -1,62 +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.async; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.core.impl.Log4jPropertyKey; -import org.apache.logging.log4j.core.test.CoreLoggerContexts; -import org.apache.logging.log4j.core.test.junit.ContextSelectorType; -import org.junit.jupiter.api.Test; -import org.junitpioneer.jupiter.SetSystemProperty; - -@SetSystemProperty(key = Log4jPropertyKey.Constant.ASYNC_LOGGER_THREAD_NAME_STRATEGY, value = "UNCACHED") -@SetSystemProperty(key = Log4jPropertyKey.Constant.CONFIG_LOCATION, value = "AsyncLoggerTest.xml") -@ContextSelectorType(AsyncLoggerContextSelector.class) -public class AsyncLoggerTestUncachedThreadName { - - @Test - public void testAsyncLogUsesCurrentThreadName() throws Exception { - final File file = new File("target", "AsyncLoggerTest.log"); - // System.out.println(f.getAbsolutePath()); - file.delete(); - final Logger log = LogManager.getLogger("com.foo.Bar"); - final String msg = "Async logger msg"; - log.info(msg); - Thread.currentThread().setName("MODIFIED-THREADNAME"); - log.info(msg); - CoreLoggerContexts.stopLoggerContext(file); // stop async thread - - final BufferedReader reader = new BufferedReader(new FileReader(file)); - final String line1 = reader.readLine(); - final String line2 = reader.readLine(); - // System.out.println(line1); - // System.out.println(line2); - reader.close(); - file.delete(); - assertNotNull(line1, "line1"); - assertNotNull(line2, "line2"); - assertTrue(line1.endsWith(" INFO c.f.Bar [main] Async logger msg "), "line1"); - assertTrue(line2.endsWith(" INFO c.f.Bar [MODIFIED-THREADNAME] Async logger msg "), "line2"); - } -} diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAbstractTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAbstractTest.java index 62a7a722184..6b1f3a1464e 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAbstractTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAbstractTest.java @@ -302,9 +302,11 @@ protected static void assertAsyncLoggerConfig(final LoggerContext ctx, final int final Configuration config = ctx.getConfiguration(); assertThat(config).isNotNull(); assertThat(config.getRootLogger()).isInstanceOf(AsyncLoggerConfig.class); - final AsyncLoggerConfigDisruptor disruptor = (AsyncLoggerConfigDisruptor) config.getAsyncLoggerConfigDelegate(); - final Field sizeField = field(AsyncLoggerConfigDisruptor.class, "ringBufferSize"); - assertThat(sizeField.get(disruptor)).isEqualTo(expectedBufferSize); + final AsyncLoggerConfigDisruptor disruptorWrapper = + (AsyncLoggerConfigDisruptor) config.getAsyncLoggerConfigDelegate(); + final Disruptor disruptor = (Disruptor) + field(AsyncLoggerConfigDisruptor.class, "disruptor").get(disruptorWrapper); + assertThat(disruptor.getBufferSize()).isEqualTo(expectedBufferSize); } protected static void assertFormatMessagesInBackground() { diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java index e2c8008a577..e9f0aed2a4e 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java @@ -38,7 +38,6 @@ import org.apache.logging.log4j.message.ReusableMessageFactory; import org.apache.logging.log4j.message.SimpleMessage; import org.apache.logging.log4j.spi.MutableThreadContextStack; -import org.apache.logging.log4j.util.StringMap; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -80,7 +79,7 @@ public void testIsPopulated() { level, data, t, - (StringMap) evt.getContextData(), + evt.getContextData(), contextStack, -1, threadName, @@ -116,7 +115,7 @@ public void testGetLevelReturnsOffIfNullLevelSet() { level, data, t, - (StringMap) evt.getContextData(), + evt.getContextData(), contextStack, -1, threadName, @@ -147,7 +146,7 @@ public void testGetMessageReturnsNonNullMessage() { level, data, t, - (StringMap) evt.getContextData(), + evt.getContextData(), contextStack, -1, threadName, @@ -178,7 +177,7 @@ public void testGetMillisReturnsConstructorMillisForNormalMessage() { level, data, t, - (StringMap) evt.getContextData(), + evt.getContextData(), contextStack, -1, threadName, @@ -210,7 +209,7 @@ public void testCreateMementoReturnsCopy() { level, data, t, - (StringMap) evt.getContextData(), + evt.getContextData(), contextStack, -1, threadName, @@ -218,7 +217,7 @@ public void testCreateMementoReturnsCopy() { location, new FixedPreciseClock(12345, 678), new DummyNanoClock(1)); - ((StringMap) evt.getContextData()).putValue("key", "value"); + evt.getContextData().putValue("key", "value"); final LogEvent actual = evt.toMemento(); assertEquals(evt.getLoggerName(), actual.getLoggerName()); @@ -261,7 +260,7 @@ public void testCreateMementoRetainsParametersAndFormat() { level, message, t, - (StringMap) evt.getContextData(), + evt.getContextData(), contextStack, -1, threadName, @@ -269,7 +268,7 @@ public void testCreateMementoRetainsParametersAndFormat() { location, new FixedPreciseClock(12345, 678), new DummyNanoClock(1)); - ((StringMap) evt.getContextData()).putValue("key", "value"); + evt.getContextData().putValue("key", "value"); final Message actual = evt.toMemento().getMessage(); assertEquals("Hello {}!", actual.getFormat()); @@ -304,7 +303,7 @@ public void testMementoReuse() { level, message, t, - (StringMap) evt.getContextData(), + evt.getContextData(), contextStack, -1, threadName, @@ -312,7 +311,7 @@ public void testMementoReuse() { location, new FixedPreciseClock(12345, 678), new DummyNanoClock(1)); - ((StringMap) evt.getContextData()).putValue("key", "value"); + evt.getContextData().putValue("key", "value"); final Message memento1 = evt.memento(); final Message memento2 = evt.memento(); diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java index 4aef03e08bf..5515fcbb348 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java @@ -16,15 +16,14 @@ */ package org.apache.logging.log4j.core.async; -import com.lmax.disruptor.EventTranslatorVararg; import java.util.List; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.ThreadContext; -import org.apache.logging.log4j.ThreadContext.ContextStack; import org.apache.logging.log4j.core.ContextDataInjector; import org.apache.logging.log4j.core.Logger; import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.ReusableLogEvent; import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.config.LoggerConfig; import org.apache.logging.log4j.core.config.Property; @@ -58,7 +57,7 @@ * and they will flush to disk at the end of each batch. This means that even with immediateFlush=false, there will * never be any items left in the buffer; all log events will all be written to disk in a very efficient manner. */ -public class AsyncLogger extends Logger implements EventTranslatorVararg { +public class AsyncLogger extends Logger { // Implementation note: many methods in this class are tuned for performance. MODIFY WITH CARE! // Specifically, try to keep the hot methods to 35 bytecodes or less: // this is within the MaxInlineSize threshold and makes these methods candidates for @@ -276,46 +275,6 @@ private StackTraceElement calcLocationIfRequested(final String fqcn) { return includeLocation ? StackLocatorUtil.calcLocation(fqcn) : null; } - /* - * (non-Javadoc) - * - * @see com.lmax.disruptor.EventTranslatorVararg#translateTo(java.lang.Object, long, java.lang.Object[]) - */ - @Override - public void translateTo(final RingBufferLogEvent event, final long sequence, final Object... args) { - // Implementation note: candidate for optimization: exceeds 35 bytecodes. - final AsyncLogger asyncLogger = (AsyncLogger) args[0]; - final StackTraceElement location = (StackTraceElement) args[1]; - final String fqcn = (String) args[2]; - final Level level = (Level) args[3]; - final Marker marker = (Marker) args[4]; - final Message message = (Message) args[5]; - final Throwable thrown = (Throwable) args[6]; - - // needs shallow copy to be fast (LOG4J2-154) - final ContextStack contextStack = ThreadContext.getImmutableStack(); - - final Thread currentThread = Thread.currentThread(); - event.setValues( - asyncLogger, - asyncLogger.getName(), - marker, - fqcn, - level, - message, - thrown, - // config properties are taken care of in the EventHandler thread - // in the AsyncLogger#actualAsyncLog method - contextDataInjector.injectContextData(null, (StringMap) event.getContextData()), - contextStack, - currentThread.getId(), - currentThread.getName(), - currentThread.getPriority(), - location, - clock, - nanoClock); - } - /** * LOG4J2-471: prevent deadlock when RingBuffer is full and object being logged calls Logger.log() from its * toString() method @@ -340,7 +299,7 @@ void logMessageInCurrentThread( * * @param event the event to log */ - public void actualAsyncLog(final RingBufferLogEvent event) { + public void actualAsyncLog(final ReusableLogEvent event) { final LoggerConfig privateConfigLoggerConfig = privateConfig.loggerConfig; final List properties = privateConfigLoggerConfig.getPropertyList(); @@ -352,7 +311,7 @@ public void actualAsyncLog(final RingBufferLogEvent event) { } @SuppressWarnings("ForLoopReplaceableByForEach") // Avoid iterator allocation - private void onPropertiesPresent(final RingBufferLogEvent event, final List properties) { + private void onPropertiesPresent(final ReusableLogEvent event, final List properties) { final StringMap contextData = getContextData(event); for (int i = 0, size = properties.size(); i < size; i++) { final Property prop = properties.get(i); @@ -367,7 +326,7 @@ private void onPropertiesPresent(final RingBufferLogEvent event, final List disruptor; private long backgroundThreadId; // LOG4J2-471 - private EventFactory factory; private EventTranslatorTwoArg translator; private volatile boolean alreadyLoggedWarning; private final AsyncWaitStrategyFactory asyncWaitStrategyFactory; @@ -207,7 +204,8 @@ public void start() { return; } LOGGER.trace("AsyncLoggerConfigDisruptor creating new disruptor for this configuration."); - ringBufferSize = DisruptorUtil.calculateRingBufferSize(Log4jPropertyKey.ASYNC_CONFIG_RING_BUFFER_SIZE); + final int ringBufferSize = + DisruptorUtil.calculateRingBufferSize(Log4jPropertyKey.ASYNC_CONFIG_RING_BUFFER_SIZE); waitStrategy = DisruptorUtil.createWaitStrategy( Log4jPropertyKey.ASYNC_CONFIG_WAIT_STRATEGY, asyncWaitStrategyFactory); @@ -223,7 +221,7 @@ public Thread newThread(final Runnable r) { asyncQueueFullPolicy = AsyncQueueFullPolicyFactory.create(); translator = mutable ? MUTABLE_TRANSLATOR : TRANSLATOR; - factory = mutable ? MUTABLE_FACTORY : FACTORY; + final EventFactory factory = mutable ? MUTABLE_FACTORY : FACTORY; disruptor = new Disruptor<>(factory, ringBufferSize, threadFactory, ProducerType.MULTI, waitStrategy); final ExceptionHandler errorHandler = diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerDisruptor.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerDisruptor.java index fb477901870..2edf4bb9bb2 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerDisruptor.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerDisruptor.java @@ -103,7 +103,8 @@ public void start() { } setStarting(); LOGGER.trace("[{}] AsyncLoggerDisruptor creating new disruptor for this context.", contextName); - int ringBufferSize = DisruptorUtil.calculateRingBufferSize(Log4jPropertyKey.ASYNC_LOGGER_RING_BUFFER_SIZE); + final int ringBufferSize = + DisruptorUtil.calculateRingBufferSize(Log4jPropertyKey.ASYNC_LOGGER_RING_BUFFER_SIZE); final AsyncWaitStrategyFactory factory = waitStrategyFactorySupplier.get(); // get factory from configuration waitStrategy = DisruptorUtil.createWaitStrategy(Log4jPropertyKey.ASYNC_LOGGER_WAIT_STRATEGY, factory); diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/InternalAsyncUtil.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/InternalAsyncUtil.java index aa82a0dfe3e..8cff3d79d02 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/InternalAsyncUtil.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/InternalAsyncUtil.java @@ -26,7 +26,10 @@ * Consider this class private. *

*/ -public class InternalAsyncUtil { +public final class InternalAsyncUtil { + + private InternalAsyncUtil() {} + /** * Returns the specified message, with its content frozen unless system property * {@code log4j.format.msg.async} is true or the message class is annotated with diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventHandler.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventHandler.java index 9b350bf4b62..f141846591f 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventHandler.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventHandler.java @@ -77,7 +77,4 @@ public long getThreadId() { public void onStart() { threadId = Thread.currentThread().getId(); } - - @Override - public void onShutdown() {} } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java index 837cae9ca8c..15b2b652bcb 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java @@ -24,7 +24,6 @@ import org.apache.logging.log4j.core.time.Clock; import org.apache.logging.log4j.core.time.NanoClock; import org.apache.logging.log4j.message.Message; -import org.apache.logging.log4j.util.ReadOnlyStringMap; import org.apache.logging.log4j.util.StringMap; /** @@ -55,7 +54,7 @@ public class RingBufferLogEventTranslator implements EventTranslator