@@ -371,6 +375,32 @@
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ test-disruptor-4
+
+ test
+
+
+
+
+ com.lmax
+ disruptor
+ ${disruptor4.version}
+
+
+
+ com.lmax:disruptor
+
+ org.apache.logging.log4j.core.test.categories.AsyncLoggers
+
+
+
+
+
@@ -422,6 +452,20 @@
+
+
+ disruptor-4
+
+
+ com.lmax
+ disruptor
+ ${disruptor4.version}
+
+
+
diff --git a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/Tags.java b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/Tags.java
new file mode 100644
index 00000000000..ddd0695f9b3
--- /dev/null
+++ b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/Tags.java
@@ -0,0 +1,30 @@
+/*
+ * 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.test.junit;
+
+/**
+ * Container for a Junit 5 tags used in tests.
+ */
+public final class Tags {
+
+ /**
+ * Tests that use LMAX Disruptor. Same name as the JUnit 4 category.
+ */
+ public static final String ASYNC_LOGGERS = "org.apache.logging.log4j.core.test.categories.AsyncLoggers";
+
+ private Tags() {}
+}
diff --git a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/package-info.java b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/package-info.java
index e4ee3e70bae..0fedb91e3a2 100644
--- a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/package-info.java
+++ b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/package-info.java
@@ -20,7 +20,7 @@
* @see org.junit.rules.TestRule
*/
@Export
-@Version("2.21.1")
+@Version("2.23.0")
package org.apache.logging.log4j.core.test.junit;
import org.osgi.annotation.bundle.Export;
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerClassLoadDeadlock.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerClassLoadDeadlock.java
index 3e6be938174..fbccd7afcc9 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerClassLoadDeadlock.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerClassLoadDeadlock.java
@@ -18,7 +18,10 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.test.junit.Tags;
+import org.junit.jupiter.api.Tag;
+@Tag(Tags.ASYNC_LOGGERS)
class AsyncLoggerClassLoadDeadlock {
static {
final Logger log = LogManager.getLogger("com.foo.bar.deadlock");
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest.java
index 9c3d7778fab..b8c3fdb9bef 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest.java
@@ -39,13 +39,14 @@
import org.apache.logging.log4j.core.config.NullConfiguration;
import org.apache.logging.log4j.core.test.CoreLoggerContexts;
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.test.junit.Tags;
import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.test.junit.TempLoggingDir;
import org.apache.logging.log4j.test.junit.UsingStatusListener;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
-@Tag("AsyncLoggers")
+@Tag(Tags.ASYNC_LOGGERS)
@UsingStatusListener
public class AsyncLoggerConfigTest {
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextTest.java
index 56f9462252c..93eb835c1c2 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextTest.java
@@ -26,6 +26,7 @@
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.test.CoreLoggerContexts;
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.test.junit.Tags;
import org.apache.logging.log4j.core.util.Constants;
import org.apache.logging.log4j.test.TestProperties;
import org.apache.logging.log4j.test.junit.TempLoggingDir;
@@ -35,7 +36,7 @@
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
-@Tag("AsyncLoggers")
+@Tag(Tags.ASYNC_LOGGERS)
@UsingTestProperties
@UsingStatusListener
public class AsyncLoggerThreadContextTest {
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggersWithAsyncAppenderTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggersWithAsyncAppenderTest.java
index 6e8866d6dcc..9a0ed348177 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggersWithAsyncAppenderTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggersWithAsyncAppenderTest.java
@@ -25,13 +25,14 @@
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.test.appender.ListAppender;
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.test.junit.Tags;
import org.apache.logging.log4j.core.util.Constants;
import org.apache.logging.log4j.test.junit.SetTestProperty;
import org.apache.logging.log4j.test.junit.UsingStatusListener;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
-@Tag("AsyncLoggers")
+@Tag(Tags.ASYNC_LOGGERS)
@SetTestProperty(
key = Constants.LOG4J_CONTEXT_SELECTOR,
value = "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector")
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncThreadContextCopyOnWriteTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncThreadContextCopyOnWriteTest.java
index e69516666aa..d42f350ff51 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncThreadContextCopyOnWriteTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncThreadContextCopyOnWriteTest.java
@@ -17,13 +17,16 @@
package org.apache.logging.log4j.core.async;
import java.nio.file.Path;
+import org.apache.logging.log4j.core.test.junit.Tags;
import org.apache.logging.log4j.test.junit.TempLoggingDir;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
// Note: the different ThreadContextMap implementations cannot be parameterized:
// ThreadContext initialization will result in static final fields being set in various components.
// To use a different ThreadContextMap, the test needs to be run in a new JVM.
+@Tag(Tags.ASYNC_LOGGERS)
public class AsyncThreadContextCopyOnWriteTest extends AbstractAsyncThreadContextTestBase {
@TempLoggingDir
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncThreadContextDefaultTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncThreadContextDefaultTest.java
index d138e27dd68..0e84e2c8deb 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncThreadContextDefaultTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncThreadContextDefaultTest.java
@@ -17,13 +17,16 @@
package org.apache.logging.log4j.core.async;
import java.nio.file.Path;
+import org.apache.logging.log4j.core.test.junit.Tags;
import org.apache.logging.log4j.test.junit.TempLoggingDir;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
// Note: the different ThreadContextMap implementations cannot be parameterized:
// ThreadContext initialization will result in static final fields being set in various components.
// To use a different ThreadContextMap, the test needs to be run in a new JVM.
+@Tag(Tags.ASYNC_LOGGERS)
public class AsyncThreadContextDefaultTest extends AbstractAsyncThreadContextTestBase {
@TempLoggingDir
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncThreadContextGarbageFreeTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncThreadContextGarbageFreeTest.java
index 32241cc5519..4ede8163049 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncThreadContextGarbageFreeTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncThreadContextGarbageFreeTest.java
@@ -17,13 +17,16 @@
package org.apache.logging.log4j.core.async;
import java.nio.file.Path;
+import org.apache.logging.log4j.core.test.junit.Tags;
import org.apache.logging.log4j.test.junit.TempLoggingDir;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
// Note: the different ThreadContextMap implementations cannot be parameterized:
// ThreadContext initialization will result in static final fields being set in various components.
// To use a different ThreadContextMap, the test needs to be run in a new JVM.
+@Tag(Tags.ASYNC_LOGGERS)
public class AsyncThreadContextGarbageFreeTest extends AbstractAsyncThreadContextTestBase {
@TempLoggingDir
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactoryIncorrectConfigGlobalLoggersTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactoryIncorrectConfigGlobalLoggersTest.java
index c00a15dd2a2..9f282de5a95 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactoryIncorrectConfigGlobalLoggersTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactoryIncorrectConfigGlobalLoggersTest.java
@@ -17,7 +17,7 @@
package org.apache.logging.log4j.core.async;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.apache.logging.log4j.LogManager;
@@ -58,10 +58,14 @@ public void testIncorrectConfigWaitStrategyFactory() throws Exception {
final AsyncLogger logger = (AsyncLogger) context.getRootLogger();
final AsyncLoggerDisruptor delegate = logger.getAsyncLoggerDisruptor();
- assertEquals(
- TimeoutBlockingWaitStrategy.class, delegate.getWaitStrategy().getClass());
- assertThat(
- "waitstrategy is TimeoutBlockingWaitStrategy",
- delegate.getWaitStrategy() instanceof TimeoutBlockingWaitStrategy);
+ if (DisruptorUtil.DISRUPTOR_MAJOR_VERSION == 3) {
+ assertEquals(
+ TimeoutBlockingWaitStrategy.class,
+ delegate.getWaitStrategy().getClass());
+ } else {
+ assertEquals(
+ Class.forName("com.lmax.disruptor.TimeoutBlockingWaitStrategy"),
+ delegate.getWaitStrategy().getClass());
+ }
}
}
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigLoggingFromToStringTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigLoggingFromToStringTest.java
index 8542628835d..65fd8d06f9d 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigLoggingFromToStringTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigLoggingFromToStringTest.java
@@ -21,8 +21,10 @@
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
import org.apache.logging.log4j.core.test.junit.Named;
+import org.apache.logging.log4j.core.test.junit.Tags;
import org.apache.logging.log4j.test.junit.SetTestProperty;
import org.apache.logging.log4j.util.Constants;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
/**
@@ -31,6 +33,7 @@
@SetTestProperty(key = "log4j2.enableThreadlocals", value = "true")
@SetTestProperty(key = "log4j2.isWebapp", value = "false")
@SetTestProperty(key = "log4j2.asyncLoggerConfigRingBufferSize", value = "128")
+@Tag(Tags.ASYNC_LOGGERS)
public class QueueFullAsyncLoggerConfigLoggingFromToStringTest extends QueueFullAbstractTest {
@Override
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigLoggingFromToStringTest2.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigLoggingFromToStringTest2.java
index 86d847d6046..54e5a78a97f 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigLoggingFromToStringTest2.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigLoggingFromToStringTest2.java
@@ -17,12 +17,15 @@
package org.apache.logging.log4j.core.async;
import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.test.junit.Tags;
import org.apache.logging.log4j.test.junit.SetTestProperty;
+import org.junit.jupiter.api.Tag;
/**
* Tests queue full scenarios with AsyncLoggers in configuration.
*/
@SetTestProperty(key = "log4j2.formatMsgAsync", value = "true")
+@Tag(Tags.ASYNC_LOGGERS)
public class QueueFullAsyncLoggerConfigLoggingFromToStringTest2
extends QueueFullAsyncLoggerConfigLoggingFromToStringTest {
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigTest.java
index a35edd73841..93db0470ed4 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigTest.java
@@ -19,13 +19,16 @@
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
import org.apache.logging.log4j.core.test.junit.Named;
+import org.apache.logging.log4j.core.test.junit.Tags;
import org.apache.logging.log4j.test.junit.SetTestProperty;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
/**
* Tests queue full scenarios with AsyncLoggers in configuration.
*/
@SetTestProperty(key = "log4j2.asyncLoggerConfigRingBufferSize", value = "128")
+@Tag(Tags.ASYNC_LOGGERS)
public class QueueFullAsyncLoggerConfigTest extends QueueFullAbstractTest {
@Override
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigTest2.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigTest2.java
index b6d21e83a62..4c56595a405 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigTest2.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigTest2.java
@@ -17,12 +17,15 @@
package org.apache.logging.log4j.core.async;
import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.test.junit.Tags;
import org.apache.logging.log4j.test.junit.SetTestProperty;
+import org.junit.jupiter.api.Tag;
/**
* Tests queue full scenarios with AsyncLoggers in configuration.
*/
@SetTestProperty(key = "log4j2.formatMsgAsync", value = "true")
+@Tag(Tags.ASYNC_LOGGERS)
public class QueueFullAsyncLoggerConfigTest2 extends QueueFullAsyncLoggerConfigTest {
@Override
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerLoggingFromToStringTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerLoggingFromToStringTest.java
index 41edbb344ee..8e98f61c4ee 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerLoggingFromToStringTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerLoggingFromToStringTest.java
@@ -19,8 +19,10 @@
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
import org.apache.logging.log4j.core.test.junit.Named;
+import org.apache.logging.log4j.core.test.junit.Tags;
import org.apache.logging.log4j.core.util.Constants;
import org.apache.logging.log4j.test.junit.SetTestProperty;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
/**
@@ -30,6 +32,7 @@
key = Constants.LOG4J_CONTEXT_SELECTOR,
value = "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector")
@SetTestProperty(key = "log4j2.asyncLoggerRingBufferSize", value = "128")
+@Tag(Tags.ASYNC_LOGGERS)
public class QueueFullAsyncLoggerLoggingFromToStringTest extends QueueFullAbstractTest {
@Override
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerLoggingFromToStringTest2.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerLoggingFromToStringTest2.java
index 6b05b83167a..343be641454 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerLoggingFromToStringTest2.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerLoggingFromToStringTest2.java
@@ -19,13 +19,16 @@
import static org.junit.Assert.*;
import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.test.junit.Tags;
import org.apache.logging.log4j.test.junit.SetTestProperty;
import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Tag;
/**
* Tests queue full scenarios with pure AsyncLoggers (all loggers async).
*/
@SetTestProperty(key = "log4j2.formatMsgAsync", value = "true")
+@Tag(Tags.ASYNC_LOGGERS)
public class QueueFullAsyncLoggerLoggingFromToStringTest2 extends QueueFullAsyncLoggerLoggingFromToStringTest {
@Override
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest.java
index 54cfed20d04..1aaabfe48dd 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest.java
@@ -19,8 +19,10 @@
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
import org.apache.logging.log4j.core.test.junit.Named;
+import org.apache.logging.log4j.core.test.junit.Tags;
import org.apache.logging.log4j.core.util.Constants;
import org.apache.logging.log4j.test.junit.SetTestProperty;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
/**
@@ -30,6 +32,7 @@
key = Constants.LOG4J_CONTEXT_SELECTOR,
value = "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector")
@SetTestProperty(key = "log4j2.asyncLoggerRingBufferSize", value = "128")
+@Tag(Tags.ASYNC_LOGGERS)
public class QueueFullAsyncLoggerTest extends QueueFullAbstractTest {
@Override
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest2.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest2.java
index 7827bbff234..6271849278f 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest2.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest2.java
@@ -17,13 +17,16 @@
package org.apache.logging.log4j.core.async;
import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.test.junit.Tags;
import org.apache.logging.log4j.test.junit.SetTestProperty;
+import org.junit.jupiter.api.Tag;
/**
* Needs to be a separate class since {@link org.apache.logging.log4j.core.util.Constants#FORMAT_MESSAGES_IN_BACKGROUND}
* is immutable.
*/
@SetTestProperty(key = "log4j2.formatMsgAsync", value = "true")
+@Tag(Tags.ASYNC_LOGGERS)
public class QueueFullAsyncLoggerTest2 extends QueueFullAsyncLoggerTest {
@Override
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest3.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest3.java
index c9c5d193b77..7a048091d26 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest3.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest3.java
@@ -26,9 +26,11 @@
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
import org.apache.logging.log4j.core.test.junit.Named;
+import org.apache.logging.log4j.core.test.junit.Tags;
import org.apache.logging.log4j.core.util.Constants;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.test.junit.SetTestProperty;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
@@ -41,6 +43,7 @@
@SetTestProperty(key = "log4j2.asyncLoggerRingBufferSize", value = "128")
@SetTestProperty(key = "log4j2.formatMsgAsync", value = "true")
@SetTestProperty(key = "log4j2.asyncQueueFullPolicy", value = "Discard")
+@Tag(Tags.ASYNC_LOGGERS)
public class QueueFullAsyncLoggerTest3 extends QueueFullAbstractTest {
@Override
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 1a1715ae641..35f865a7761 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
@@ -17,6 +17,7 @@
package org.apache.logging.log4j.core.async;
import com.lmax.disruptor.EventFactory;
+import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.EventTranslatorTwoArg;
import com.lmax.disruptor.ExceptionHandler;
import com.lmax.disruptor.RingBuffer;
@@ -40,6 +41,7 @@
import org.apache.logging.log4j.core.util.Log4jThreadFactory;
import org.apache.logging.log4j.core.util.Throwables;
import org.apache.logging.log4j.message.ReusableMessage;
+import org.apache.logging.log4j.util.LoaderUtil;
/**
* Helper class decoupling the {@code AsyncLoggerConfig} class from the LMAX Disruptor library.
@@ -91,13 +93,18 @@ public String toString() {
/**
* EventHandler performs the work in a separate thread.
+ *
+ * Warning: this implementation only works with Disruptor 4.x.
+ *
*/
- private static class Log4jEventWrapperHandler implements SequenceReportingEventHandler {
+ private static class Log4jEventWrapperHandler implements EventHandler {
private static final int NOTIFY_PROGRESS_THRESHOLD = 50;
private Sequence sequenceCallback;
private int counter;
- @Override
+ /*
+ * Overrides a method from Disruptor 4.x. Do not remove.
+ */
public void setSequenceCallback(final Sequence sequenceCallback) {
this.sequenceCallback = sequenceCallback;
}
@@ -124,6 +131,15 @@ private void notifyIntermediateProgress(final long sequence) {
}
}
+ /**
+ * EventHandler performs the work in a separate thread.
+ *
+ * Warning: this implementation only works with Disruptor 3.x.
+ *
+ */
+ private static final class Log4jEventWrapperHandler3 extends Log4jEventWrapperHandler
+ implements SequenceReportingEventHandler {}
+
/**
* Factory used to populate the RingBuffer with events. These event objects are then re-used during the life of the
* RingBuffer.
@@ -155,6 +171,18 @@ private void notifyIntermediateProgress(final long sequence) {
ringBufferElement.loggerConfig = loggerConfig;
};
+ private Log4jEventWrapperHandler createEventHandler() {
+ if (DisruptorUtil.DISRUPTOR_MAJOR_VERSION == 3) {
+ try {
+ return LoaderUtil.newInstanceOf(
+ "org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor$Log4jEventWrapperHandler3");
+ } catch (final ReflectiveOperationException | LinkageError e) {
+ LOGGER.warn("Failed to create event handler for LMAX Disruptor 3.x, trying version 4.x.", e);
+ }
+ }
+ return new Log4jEventWrapperHandler();
+ }
+
private int ringBufferSize;
private AsyncQueueFullPolicy asyncQueueFullPolicy;
private Boolean mutable = Boolean.FALSE;
@@ -220,7 +248,7 @@ public Thread newThread(final Runnable r) {
final ExceptionHandler errorHandler = DisruptorUtil.getAsyncLoggerConfigExceptionHandler();
disruptor.setDefaultExceptionHandler(errorHandler);
- final Log4jEventWrapperHandler[] handlers = {new Log4jEventWrapperHandler()};
+ final Log4jEventWrapperHandler[] handlers = {createEventHandler()};
disruptor.handleEventsWith(handlers);
LOGGER.debug(
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 8cdcf7dc492..7b6b0d8dc13 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
@@ -16,6 +16,7 @@
*/
package org.apache.logging.log4j.core.async;
+import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.EventTranslatorVararg;
import com.lmax.disruptor.ExceptionHandler;
import com.lmax.disruptor.RingBuffer;
@@ -35,6 +36,7 @@
import org.apache.logging.log4j.core.util.Log4jThreadFactory;
import org.apache.logging.log4j.core.util.Throwables;
import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.util.LoaderUtil;
/**
* Helper class for async loggers: AsyncLoggerDisruptor handles the mechanics of working with the LMAX Disruptor, and
@@ -46,6 +48,20 @@ class AsyncLoggerDisruptor extends AbstractLifeCycle {
private static final int SLEEP_MILLIS_BETWEEN_DRAIN_ATTEMPTS = 50;
private static final int MAX_DRAIN_ATTEMPTS_BEFORE_SHUTDOWN = 200;
+ /**
+ * Creates an appropriate event handler for the Disruptor library used.
+ */
+ private static EventHandler createEventHandler() {
+ if (DisruptorUtil.DISRUPTOR_MAJOR_VERSION == 3) {
+ try {
+ return LoaderUtil.newInstanceOf("org.apache.logging.log4j.core.async.RingBufferLogEventHandler");
+ } catch (final ReflectiveOperationException | LinkageError e) {
+ LOGGER.warn("Failed to create event handler for LMAX Disruptor 3.x, trying version 4.x.", e);
+ }
+ }
+ return new RingBufferLogEventHandler4();
+ }
+
private final Object queueFullEnqueueLock = new Object();
private volatile Disruptor disruptor;
@@ -122,8 +138,8 @@ public Thread newThread(final Runnable r) {
final ExceptionHandler errorHandler = DisruptorUtil.getAsyncLoggerExceptionHandler();
disruptor.setDefaultExceptionHandler(errorHandler);
- final RingBufferLogEventHandler[] handlers = {new RingBufferLogEventHandler()};
- disruptor.handleEventsWith(handlers);
+ final EventHandler handler = createEventHandler();
+ disruptor.handleEventsWith(handler);
LOGGER.debug(
"[{}] Starting AsyncLogger disruptor for this context with ringbufferSize={}, waitStrategy={}, "
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DefaultAsyncWaitStrategyFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DefaultAsyncWaitStrategyFactory.java
index 96544d2b55d..eda242feb4d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DefaultAsyncWaitStrategyFactory.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DefaultAsyncWaitStrategyFactory.java
@@ -74,6 +74,19 @@ static WaitStrategy createDefaultWaitStrategy(final String propertyName) {
LOGGER.trace(
"DefaultAsyncWaitStrategyFactory creating TimeoutBlockingWaitStrategy(timeout={}, unit=MILLIS)",
timeoutMillis);
+ // Check for the v 4.x version of the strategy, the version in 3.x is not garbage-free.
+ if (DisruptorUtil.DISRUPTOR_MAJOR_VERSION == 4) {
+ try {
+ return (WaitStrategy) Class.forName("com.lmax.disruptor.TimeoutBlockingWaitStrategy")
+ .getConstructor(long.class, TimeUnit.class)
+ .newInstance(timeoutMillis, TimeUnit.MILLISECONDS);
+ } catch (final ReflectiveOperationException | LinkageError e) {
+ LOGGER.debug(
+ "DefaultAsyncWaitStrategyFactory failed to load 'com.lmax.disruptor.TimeoutBlockingWaitStrategy', using '{}' instead.",
+ TimeoutBlockingWaitStrategy.class.getName());
+ }
+ }
+ // Use our version
return new TimeoutBlockingWaitStrategy(timeoutMillis, TimeUnit.MILLISECONDS);
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorUtil.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorUtil.java
index 07d138a25cf..bdd21bd4ef2 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorUtil.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorUtil.java
@@ -50,6 +50,9 @@ final class DisruptorUtil {
static final boolean ASYNC_CONFIG_SYNCHRONIZE_ENQUEUE_WHEN_QUEUE_FULL = PropertiesUtil.getProperties()
.getBooleanProperty("AsyncLoggerConfig.SynchronizeEnqueueWhenQueueFull", true);
+ static final int DISRUPTOR_MAJOR_VERSION =
+ LoaderUtil.isClassAvailable("com.lmax.disruptor.SequenceReportingEventHandler") ? 3 : 4;
+
private DisruptorUtil() {}
static WaitStrategy createWaitStrategy(
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 6293973b854..a51f0a525ec 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
@@ -17,7 +17,6 @@
package org.apache.logging.log4j.core.async;
import com.lmax.disruptor.LifecycleAware;
-import com.lmax.disruptor.Sequence;
import com.lmax.disruptor.SequenceReportingEventHandler;
/**
@@ -25,60 +24,11 @@
* available. Processing of these messages is done in a separate thread,
* controlled by the {@code Executor} passed to the {@code Disruptor}
* constructor.
+ *
+ * Warning: this class only works with Disruptor 3.x.
+ *
+ * @deprecated Only used internally, will be removed in the next major version.
*/
-public class RingBufferLogEventHandler implements SequenceReportingEventHandler, LifecycleAware {
-
- private static final int NOTIFY_PROGRESS_THRESHOLD = 50;
- private Sequence sequenceCallback;
- private int counter;
- private long threadId = -1;
-
- @Override
- public void setSequenceCallback(final Sequence sequenceCallback) {
- this.sequenceCallback = sequenceCallback;
- }
-
- @Override
- public void onEvent(final RingBufferLogEvent event, final long sequence, final boolean endOfBatch)
- throws Exception {
- try {
- // RingBufferLogEvents are populated by an EventTranslator. If an exception is thrown during event
- // translation, the event may not be fully populated, but Disruptor requires that the associated sequence
- // still be published since a slot has already been claimed in the ring buffer. Ignore any such unpopulated
- // events. The exception that occurred during translation will have already been propagated.
- if (event.isPopulated()) {
- event.execute(endOfBatch);
- }
- } finally {
- 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.
- notifyCallback(sequence);
- }
- }
-
- private void notifyCallback(final long sequence) {
- if (++counter > NOTIFY_PROGRESS_THRESHOLD) {
- sequenceCallback.set(sequence);
- counter = 0;
- }
- }
-
- /**
- * Returns the thread ID of the background consumer thread, or {@code -1} if the background thread has not started
- * yet.
- * @return the thread ID of the background consumer thread, or {@code -1}
- */
- public long getThreadId() {
- return threadId;
- }
-
- @Override
- public void onStart() {
- threadId = Thread.currentThread().getId();
- }
-
- @Override
- public void onShutdown() {}
-}
+@Deprecated
+public class RingBufferLogEventHandler extends RingBufferLogEventHandler4
+ implements SequenceReportingEventHandler, LifecycleAware {}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventHandler4.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventHandler4.java
new file mode 100644
index 00000000000..6cb1e686126
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventHandler4.java
@@ -0,0 +1,93 @@
+/*
+ * 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 com.lmax.disruptor.EventHandler;
+import com.lmax.disruptor.Sequence;
+
+/**
+ * This event handler gets passed messages from the RingBuffer as they become
+ * available. Processing of these messages is done in a separate thread,
+ * controlled by the {@code Executor} passed to the {@code Disruptor}
+ * constructor.
+ * *
+ * * Warning: this class only works with Disruptor 4.x.
+ * *
+ */
+class RingBufferLogEventHandler4 implements EventHandler {
+
+ private static final int NOTIFY_PROGRESS_THRESHOLD = 50;
+ private Sequence sequenceCallback;
+ private int counter;
+ private long threadId = -1;
+
+ /*
+ * Overrides a method from Disruptor 4.x. Do not remove.
+ */
+ public void setSequenceCallback(final Sequence sequenceCallback) {
+ this.sequenceCallback = sequenceCallback;
+ }
+
+ @Override
+ public void onEvent(final RingBufferLogEvent event, final long sequence, final boolean endOfBatch)
+ throws Exception {
+ try {
+ // RingBufferLogEvents are populated by an EventTranslator. If an exception is thrown during event
+ // translation, the event may not be fully populated, but Disruptor requires that the associated sequence
+ // still be published since a slot has already been claimed in the ring buffer. Ignore any such unpopulated
+ // events. The exception that occurred during translation will have already been propagated.
+ if (event.isPopulated()) {
+ event.execute(endOfBatch);
+ }
+ } finally {
+ 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.
+ notifyCallback(sequence);
+ }
+ }
+
+ private void notifyCallback(final long sequence) {
+ if (++counter > NOTIFY_PROGRESS_THRESHOLD) {
+ sequenceCallback.set(sequence);
+ counter = 0;
+ }
+ }
+
+ /**
+ * Returns the thread ID of the background consumer thread, or {@code -1} if the background thread has not started
+ * yet.
+ *
+ * @return the thread ID of the background consumer thread, or {@code -1}
+ */
+ public long getThreadId() {
+ return threadId;
+ }
+
+ /*
+ * Overrides a method from Disruptor 4.x. Do not remove.
+ */
+ public void onStart() {
+ threadId = Thread.currentThread().getId();
+ }
+
+ /*
+ * Overrides a method from Disruptor 4.x. Do not remove.
+ */
+ public void onShutdown() {}
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/package-info.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/package-info.java
index a93e24f2ae1..18545f3065f 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/package-info.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/package-info.java
@@ -18,7 +18,7 @@
* Provides Asynchronous Logger classes and interfaces for low-latency logging.
*/
@Export
-@Version("2.21.0")
+@Version("2.23.0")
package org.apache.logging.log4j.core.async;
import org.osgi.annotation.bundle.Export;
diff --git a/log4j-jpl/pom.xml b/log4j-jpl/pom.xml
index 7ac145daf73..70345ff657e 100644
--- a/log4j-jpl/pom.xml
+++ b/log4j-jpl/pom.xml
@@ -65,30 +65,26 @@