You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by vy...@apache.org on 2024/01/10 08:59:57 UTC
(logging-log4j2) branch main updated: Remove `log4j2.enable.threadlocals` property (#2171)
This is an automated email from the ASF dual-hosted git repository.
vy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/main by this push:
new 0d6876d11e Remove `log4j2.enable.threadlocals` property (#2171)
0d6876d11e is described below
commit 0d6876d11e4089d5e12b4a334ead59f6ca624b0c
Author: Volkan Yazıcı <vo...@yazi.ci>
AuthorDate: Wed Jan 10 09:59:49 2024 +0100
Remove `log4j2.enable.threadlocals` property (#2171)
---
.../apache/log4j/layout/Log4j1SyslogLayout.java | 3 +-
.../apache/logging/log4j/AbstractLoggerTest.java | 6 +-
.../org/apache/logging/log4j/LogManagerTest.java | 11 +-
.../java/org/apache/logging/log4j/LoggerTest.java | 24 +-
.../internal/recycler/RecyclerFactoryTestUtil.java | 11 +-
.../ThreadLocalRecyclerFactoryProviderTest.java | 6 +-
.../log4j/spi/DefaultThreadContextMapTest.java | 225 ----------------
.../util/LegacyPropertiesCompatibilityTest.java | 1 -
.../logging/log4j/util/Unbox2ConfigurableTest.java | 5 -
.../org/apache/logging/log4j/ThreadContext.java | 8 -
.../ThreadLocalRecyclerFactoryProvider.java | 7 +-
.../logging/log4j/message/MessageFactory.java | 13 -
.../logging/log4j/message/MessageFactory2.java | 1 -
.../log4j/message/ParameterizedMessageFactory.java | 191 --------------
.../log4j/message/ReusableMessageFactory.java | 10 +-
.../logging/log4j/spi/DefaultThreadContextMap.java | 228 -----------------
.../apache/logging/log4j/spi/LoggingSystem.java | 16 +-
.../logging/log4j/spi/LoggingSystemProperty.java | 12 +-
.../logging/log4j/spi/PropertyComponent.java | 2 -
.../org/apache/logging/log4j/util/Constants.java | 22 --
.../java/org/apache/logging/log4j/util/Unbox.java | 29 +--
.../src/main/resources/log4j2.propertyMapping.json | 2 -
.../core/async/perftest/ResponseTimeTest.java | 5 -
.../log4j/core/async/perftest/SimplePerfTest.java | 16 --
.../org/apache/logging/log4j/core/LoggerTest.java | 4 +-
.../appender/rolling/PatternProcessorTest.java | 55 ++--
.../RollingRandomAccessFileManagerTest.java | 4 +
.../async/AsyncLoggerThreadNameStrategyTest.java | 78 ------
.../log4j/core/async/AsyncThreadContextTest.java | 2 -
...llAsyncLoggerConfigLoggingFromToStringTest.java | 2 -
.../core/impl/ThreadContextDataInjectorTest.java | 11 +-
...TestBase.java => DatePatternConverterTest.java} | 78 +++---
.../DatePatternConverterWithThreadLocalsTest.java | 31 ---
...atePatternConverterWithoutThreadLocalsTest.java | 28 --
.../src/test/resources/perf/SimplePerfTest.sh | 1 -
.../src/test/resources/perf/runResponseTm.sh | 1 -
.../appender/rolling/DefaultRolloverStrategy.java | 5 +-
.../rolling/DirectWriteRolloverStrategy.java | 11 +-
.../core/appender/rolling/PatternProcessor.java | 9 +-
.../core/appender/rolling/RollingFileManager.java | 7 +-
.../rolling/RollingRandomAccessFileManager.java | 6 +-
.../logging/log4j/core/async/AsyncLogger.java | 283 ++-------------------
.../log4j/core/async/AsyncLoggerContext.java | 8 -
.../log4j/core/async/AsyncLoggerDisruptor.java | 89 +------
.../logging/log4j/core/async/DisruptorUtil.java | 6 +-
.../log4j/core/async/RingBufferLogEvent.java | 16 +-
.../core/async/ThreadNameCachingStrategy.java | 95 -------
.../core/impl/ContextDataInjectorFactory.java | 3 +-
.../logging/log4j/core/impl/DefaultBundle.java | 10 +-
.../log4j/core/impl/ReusableLogEventFactory.java | 9 +-
.../logging/log4j/core/layout/HtmlLayout.java | 2 +-
.../log4j/core/pattern/DatePatternConverter.java | 140 +++-------
.../core/pattern/FileDatePatternConverter.java | 11 +-
.../log4j/gctests/GcFreeLoggingTestUtil.java | 3 -
.../gctests/JsonTemplateLayoutGcFreeTest.java | 1 -
.../resources/gcFreeJsonTemplateLayoutLogging.xml | 2 +-
.../template/json/JsonTemplateLayoutTest.java | 13 +-
.../perf/jmh/AsyncLoggersLocationBenchmark.java | 1 -
.../log4j/perf/jmh/ThreadContextBenchmark.java | 3 -
.../ThreadLocalVsConcurrentHashMapBenchmark.java | 92 -------
.../log4j/perf/jmh/ThreadLocalVsPoolBenchmark.java | 200 ---------------
.../java/org/apache/logging/slf4j/LoggerTest.java | 4 +-
.../.3.x.x/remove_thread_locals_property.xml | 8 +
src/site/_release-notes/_3.x.x.adoc | 3 +
src/site/asciidoc/manual/extending.adoc | 3 +-
src/site/asciidoc/manual/systemproperties.adoc | 4 +-
66 files changed, 241 insertions(+), 1955 deletions(-)
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/layout/Log4j1SyslogLayout.java b/log4j-1.2-api/src/main/java/org/apache/log4j/layout/Log4j1SyslogLayout.java
index 03ee98a514..1e15c300c3 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/layout/Log4j1SyslogLayout.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/layout/Log4j1SyslogLayout.java
@@ -146,7 +146,7 @@ public final class Log4j1SyslogLayout extends AbstractStringLayout {
*/
private static final String[] dateFormatOptions = {"MMM dd HH:mm:ss", null, "en"};
- private final LogEventPatternConverter dateConverter = DatePatternConverter.newInstance(dateFormatOptions);
+ private final LogEventPatternConverter dateConverter;
private Log4j1SyslogLayout(
final Configuration config,
@@ -160,6 +160,7 @@ public final class Log4j1SyslogLayout extends AbstractStringLayout {
this.facilityPrinting = facilityPrinting;
this.header = header;
this.messageLayout = messageLayout;
+ this.dateConverter = DatePatternConverter.newInstance(config, dateFormatOptions);
}
/**
diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/AbstractLoggerTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/AbstractLoggerTest.java
index 5cd1119a41..0f1d4f0078 100644
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/AbstractLoggerTest.java
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/AbstractLoggerTest.java
@@ -28,7 +28,7 @@ import java.util.List;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.ObjectMessage;
import org.apache.logging.log4j.message.ParameterizedMessage;
-import org.apache.logging.log4j.message.ParameterizedMessageFactory;
+import org.apache.logging.log4j.message.ReusableMessageFactory;
import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.spi.AbstractLogger;
import org.apache.logging.log4j.status.StatusData;
@@ -964,7 +964,7 @@ public class AbstractLoggerTest {
private int objectCount;
CountingLogger() {
- super("CountingLogger", ParameterizedMessageFactory.INSTANCE);
+ super("CountingLogger", new ReusableMessageFactory());
}
void setCurrentLevel(final Level currentLevel) {
@@ -1261,7 +1261,7 @@ public class AbstractLoggerTest {
private final boolean expectingThrowables;
ThrowableExpectingLogger(final boolean expectingThrowables) {
- super("ThrowableExpectingLogger", ParameterizedMessageFactory.INSTANCE);
+ super("ThrowableExpectingLogger", new ReusableMessageFactory());
this.expectingThrowables = expectingThrowables;
}
diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/LogManagerTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/LogManagerTest.java
index 111b6c77cc..2e767bc7cf 100644
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/LogManagerTest.java
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/LogManagerTest.java
@@ -21,7 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.io.Closeable;
import java.io.IOException;
-import org.apache.logging.log4j.message.ParameterizedMessageFactory;
+import org.apache.logging.log4j.message.ReusableMessageFactory;
import org.apache.logging.log4j.spi.LoggerContext;
import org.junit.jupiter.api.Test;
import org.junitpioneer.jupiter.ReadsSystemProperty;
@@ -52,25 +52,26 @@ public class LogManagerTest {
Logger logger = LogManager.getLogger();
assertNotNull(logger, "No Logger returned");
assertEquals(LogManagerTest.class.getName(), logger.getName(), "Incorrect Logger name: " + logger.getName());
- logger = LogManager.getLogger(ParameterizedMessageFactory.INSTANCE);
+ final ReusableMessageFactory messageFactory = new ReusableMessageFactory();
+ logger = LogManager.getLogger(messageFactory);
assertNotNull(logger, "No Logger returned");
assertEquals(LogManagerTest.class.getName(), logger.getName(), "Incorrect Logger name: " + logger.getName());
logger = LogManager.getLogger((Class<?>) null);
assertNotNull(logger, "No Logger returned");
assertEquals(LogManagerTest.class.getName(), logger.getName(), "Incorrect Logger name: " + logger.getName());
- logger = LogManager.getLogger((Class<?>) null, ParameterizedMessageFactory.INSTANCE);
+ logger = LogManager.getLogger((Class<?>) null, messageFactory);
assertNotNull(logger, "No Logger returned");
assertEquals(LogManagerTest.class.getName(), logger.getName(), "Incorrect Logger name: " + logger.getName());
logger = LogManager.getLogger((String) null);
assertNotNull(logger, "No Logger returned");
assertEquals(LogManagerTest.class.getName(), logger.getName(), "Incorrect Logger name: " + logger.getName());
- logger = LogManager.getLogger((String) null, ParameterizedMessageFactory.INSTANCE);
+ logger = LogManager.getLogger((String) null, messageFactory);
assertNotNull(logger, "No Logger returned");
assertEquals(LogManagerTest.class.getName(), logger.getName(), "Incorrect Logger name: " + logger.getName());
logger = LogManager.getLogger((Object) null);
assertNotNull(logger, "No Logger returned");
assertEquals(LogManagerTest.class.getName(), logger.getName(), "Incorrect Logger name: " + logger.getName());
- logger = LogManager.getLogger((Object) null, ParameterizedMessageFactory.INSTANCE);
+ logger = LogManager.getLogger((Object) null, messageFactory);
assertNotNull(logger, "No Logger returned");
assertEquals(LogManagerTest.class.getName(), logger.getName(), "Incorrect Logger name: " + logger.getName());
}
diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/LoggerTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/LoggerTest.java
index c1cb6d7751..7f4d6b8b37 100644
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/LoggerTest.java
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/LoggerTest.java
@@ -34,7 +34,7 @@ import org.apache.logging.log4j.message.JsonMessage;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MessageFactory;
import org.apache.logging.log4j.message.ObjectMessage;
-import org.apache.logging.log4j.message.ParameterizedMessageFactory;
+import org.apache.logging.log4j.message.ReusableMessageFactory;
import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.message.SimpleMessageFactory;
import org.apache.logging.log4j.message.StringFormatterMessageFactory;
@@ -61,7 +61,7 @@ public class LoggerTest {
public static final LoggerContextFactoryExtension EXTENSION =
new LoggerContextFactoryExtension(new TestLoggerContextFactory());
- private static class TestParameterizedMessageFactory {
+ private static class TestReusableMessageFactory {
// empty
}
@@ -344,12 +344,12 @@ public class LoggerTest {
@Test
@ResourceLock("log4j2.TestLogger")
- public void getLogger_Class_ParameterizedMessageFactory() {
+ public void getLogger_Class_ReusableMessageFactory() {
// The TestLogger logger was already created in an instance variable for this class.
// The message factory is only used when the logger is created.
- final ParameterizedMessageFactory messageFactory = ParameterizedMessageFactory.INSTANCE;
+ final MessageFactory messageFactory = new ReusableMessageFactory();
final TestLogger testLogger =
- (TestLogger) LogManager.getLogger(TestParameterizedMessageFactory.class, messageFactory);
+ (TestLogger) LogManager.getLogger(TestReusableMessageFactory.class, messageFactory);
assertNotNull(testLogger);
assertEqualMessageFactory(messageFactory, testLogger);
testLogger.debug("{}", Integer.MAX_VALUE);
@@ -375,12 +375,12 @@ public class LoggerTest {
@Test
@ResourceLock("log4j2.TestLogger")
- public void getLogger_Object_ParameterizedMessageFactory() {
+ public void getLogger_Object_ReusableMessageFactory() {
// The TestLogger logger was already created in an instance variable for this class.
// The message factory is only used when the logger is created.
- final ParameterizedMessageFactory messageFactory = ParameterizedMessageFactory.INSTANCE;
+ final MessageFactory messageFactory = new ReusableMessageFactory();
final TestLogger testLogger =
- (TestLogger) LogManager.getLogger(new TestParameterizedMessageFactory(), messageFactory);
+ (TestLogger) LogManager.getLogger(new TestReusableMessageFactory(), messageFactory);
assertNotNull(testLogger);
assertEqualMessageFactory(messageFactory, testLogger);
testLogger.debug("{}", Integer.MAX_VALUE);
@@ -419,7 +419,7 @@ public class LoggerTest {
assertNotNull(testLogger);
assertEqualMessageFactory(messageFactory, testLogger);
final TestLogger testLogger2 = (TestLogger)
- LogManager.getLogger("getLogger_String_MessageFactoryMismatch", ParameterizedMessageFactory.INSTANCE);
+ LogManager.getLogger("getLogger_String_MessageFactoryMismatch", new ReusableMessageFactory());
assertNotNull(testLogger2);
// TODO: How to test?
// This test context always creates new loggers, other test context impls I tried fail other tests.
@@ -433,10 +433,10 @@ public class LoggerTest {
@Test
@ResourceLock("log4j2.TestLogger")
- public void getLogger_String_ParameterizedMessageFactory() {
- final ParameterizedMessageFactory messageFactory = ParameterizedMessageFactory.INSTANCE;
+ public void getLogger_String_ReusableMessageFactory() {
+ final MessageFactory messageFactory = new ReusableMessageFactory();
final TestLogger testLogger =
- (TestLogger) LogManager.getLogger("getLogger_String_ParameterizedMessageFactory", messageFactory);
+ (TestLogger) LogManager.getLogger("getLogger_String_ReusableMessageFactory", messageFactory);
assertNotNull(testLogger);
assertEqualMessageFactory(messageFactory, testLogger);
testLogger.debug("{}", Integer.MAX_VALUE);
diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/internal/recycler/RecyclerFactoryTestUtil.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/internal/recycler/RecyclerFactoryTestUtil.java
index a6c8f99a2c..85ec0c3cdb 100644
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/internal/recycler/RecyclerFactoryTestUtil.java
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/internal/recycler/RecyclerFactoryTestUtil.java
@@ -18,6 +18,7 @@ package org.apache.logging.log4j.internal.recycler;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.util.Properties;
+import org.apache.logging.log4j.spi.LoggingSystemProperty;
import org.apache.logging.log4j.spi.recycler.RecyclerFactory;
import org.apache.logging.log4j.spi.recycler.RecyclerFactoryRegistry;
import org.apache.logging.log4j.util.PropertiesUtil;
@@ -29,16 +30,16 @@ final class RecyclerFactoryTestUtil {
@Nullable
static RecyclerFactory createForEnvironment(
- @Nullable Boolean threadLocalsEnabled, @Nullable final String factory, @Nullable final Integer capacity) {
+ @Nullable Boolean webApp, @Nullable final String factory, @Nullable final Integer capacity) {
final Properties properties = new Properties();
- if (threadLocalsEnabled != null) {
- properties.setProperty("log4j2.*.ThreadLocals.enable", "" + threadLocalsEnabled);
+ if (webApp != null) {
+ properties.setProperty(LoggingSystemProperty.IS_WEBAPP.getSystemKey(), webApp + "");
}
if (factory != null) {
- properties.setProperty("log4j2.*.Recycler.factory", factory);
+ properties.setProperty(LoggingSystemProperty.RECYCLER_FACTORY.getSystemKey(), factory);
}
if (capacity != null) {
- properties.setProperty("log4j2.*.Recycler.capacity", "" + capacity);
+ properties.setProperty(LoggingSystemProperty.RECYCLER_CAPACITY.getSystemKey(), capacity + "");
}
final PropertyEnvironment env = new PropertiesUtil(properties);
return RecyclerFactoryRegistry.findRecyclerFactory(env);
diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/internal/recycler/ThreadLocalRecyclerFactoryProviderTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/internal/recycler/ThreadLocalRecyclerFactoryProviderTest.java
index 147a84e52c..2d2bdf3710 100644
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/internal/recycler/ThreadLocalRecyclerFactoryProviderTest.java
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/internal/recycler/ThreadLocalRecyclerFactoryProviderTest.java
@@ -44,7 +44,7 @@ class ThreadLocalRecyclerFactoryProviderTest {
@BeforeEach
void setUp() {
- final RecyclerFactory recyclerFactory = createForEnvironment(null, "threadLocal", CAPACITY);
+ final RecyclerFactory recyclerFactory = createForEnvironment(false, "threadLocal", CAPACITY);
assertThat(recyclerFactory).isInstanceOf(ThreadLocalRecyclerFactory.class);
assert recyclerFactory != null;
recycler = (ThreadLocalRecycler<RecyclableObject>) recyclerFactory.create(RecyclableObject::new);
@@ -52,8 +52,8 @@ class ThreadLocalRecyclerFactoryProviderTest {
}
@Test
- void should_not_be_configured_when_TLs_are_disabled() {
- assertThatThrownBy(() -> createForEnvironment(false, "threadLocal", null))
+ void should_not_be_configured_for_webapps() {
+ assertThatThrownBy(() -> createForEnvironment(true, "threadLocal", null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageStartingWith("failed to configure recycler");
}
diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/spi/DefaultThreadContextMapTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/spi/DefaultThreadContextMapTest.java
deleted file mode 100644
index 7fcb329afd..0000000000
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/spi/DefaultThreadContextMapTest.java
+++ /dev/null
@@ -1,225 +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.spi;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-import java.util.HashMap;
-import java.util.Map;
-import org.apache.logging.log4j.test.junit.UsingThreadContextMap;
-import org.junit.jupiter.api.Test;
-
-/**
- * Tests the {@code DefaultThreadContextMap} class.
- */
-@UsingThreadContextMap
-public class DefaultThreadContextMapTest {
-
- @Test
- public void testEqualsVsSameKind() {
- final DefaultThreadContextMap map1 = createMap();
- final DefaultThreadContextMap map2 = createMap();
- assertEquals(map1, map1);
- assertEquals(map2, map2);
- assertEquals(map1, map2);
- assertEquals(map2, map1);
- }
-
- @Test
- public void testHashCodeVsSameKind() {
- final DefaultThreadContextMap map1 = createMap();
- final DefaultThreadContextMap map2 = createMap();
- assertEquals(map1.hashCode(), map2.hashCode());
- }
-
- @Test
- public void testDoesNothingIfConstructedWithUseMapIsFalse() {
- final DefaultThreadContextMap map = new DefaultThreadContextMap(false);
- assertTrue(map.isEmpty());
- assertFalse(map.containsKey("key"));
- map.put("key", "value");
-
- assertTrue(map.isEmpty());
- assertFalse(map.containsKey("key"));
- assertNull(map.get("key"));
- }
-
- @Test
- public void testPut() {
- final DefaultThreadContextMap map = new DefaultThreadContextMap(true);
- assertTrue(map.isEmpty());
- assertFalse(map.containsKey("key"));
- map.put("key", "value");
-
- assertFalse(map.isEmpty());
- assertTrue(map.containsKey("key"));
- assertEquals("value", map.get("key"));
- }
-
- @Test
- public void testPutAll() {
- final DefaultThreadContextMap map = new DefaultThreadContextMap(true);
- assertTrue(map.isEmpty());
- assertFalse(map.containsKey("key"));
- final int mapSize = 10;
- final Map<String, String> newMap = new HashMap<>(mapSize);
- for (int i = 1; i <= mapSize; i++) {
- newMap.put("key" + i, "value" + i);
- }
- map.putAll(newMap);
- assertFalse(map.isEmpty());
- for (int i = 1; i <= mapSize; i++) {
- assertTrue(map.containsKey("key" + i));
- assertEquals("value" + i, map.get("key" + i));
- }
- }
-
- /**
- * Test method for
- * {@link org.apache.logging.log4j.spi.DefaultThreadContextMap#remove(java.lang.String)}
- * .
- */
- @Test
- public void testRemove() {
- final DefaultThreadContextMap map = createMap();
- assertEquals("value", map.get("key"));
- assertEquals("value2", map.get("key2"));
-
- map.remove("key");
- assertFalse(map.containsKey("key"));
- assertEquals("value2", map.get("key2"));
- }
-
- @Test
- public void testClear() {
- final DefaultThreadContextMap map = createMap();
-
- map.clear();
- assertTrue(map.isEmpty());
- assertFalse(map.containsKey("key"));
- assertFalse(map.containsKey("key2"));
- }
-
- /**
- * @return
- */
- private DefaultThreadContextMap createMap() {
- final DefaultThreadContextMap map = new DefaultThreadContextMap(true);
- assertTrue(map.isEmpty());
- map.put("key", "value");
- map.put("key2", "value2");
- assertEquals("value", map.get("key"));
- assertEquals("value2", map.get("key2"));
- return map;
- }
-
- @Test
- public void testGetCopyReturnsMutableMap() {
- final DefaultThreadContextMap map = new DefaultThreadContextMap(true);
- assertTrue(map.isEmpty());
- final Map<String, String> copy = map.getCopy();
- assertTrue(copy.isEmpty());
-
- copy.put("key", "value"); // mutable
- assertEquals("value", copy.get("key"));
-
- // thread context map not affected
- assertTrue(map.isEmpty());
- }
-
- @Test
- public void testGetCopyReturnsMutableCopy() {
- final DefaultThreadContextMap map = new DefaultThreadContextMap(true);
- map.put("key1", "value1");
- assertFalse(map.isEmpty());
- final Map<String, String> copy = map.getCopy();
- assertEquals("value1", copy.get("key1")); // copy has values too
-
- copy.put("key", "value"); // copy is mutable
- assertEquals("value", copy.get("key"));
-
- // thread context map not affected
- assertFalse(map.containsKey("key"));
-
- // clearing context map does not affect copy
- map.clear();
- assertTrue(map.isEmpty());
-
- assertFalse(copy.isEmpty());
- }
-
- @Test
- public void testGetImmutableMapReturnsNullIfEmpty() {
- final DefaultThreadContextMap map = new DefaultThreadContextMap(true);
- assertTrue(map.isEmpty());
- assertNull(map.getImmutableMapOrNull());
- }
-
- @Test
- public void testGetImmutableMapReturnsImmutableMapIfNonEmpty() {
- final DefaultThreadContextMap map = new DefaultThreadContextMap(true);
- map.put("key1", "value1");
- assertFalse(map.isEmpty());
-
- final Map<String, String> immutable = map.getImmutableMapOrNull();
- assertEquals("value1", immutable.get("key1")); // copy has values too
-
- // immutable
- assertThrows(UnsupportedOperationException.class, () -> immutable.put("key", "value"));
- }
-
- @Test
- public void testGetImmutableMapCopyNotAffectedByContextMapChanges() {
- final DefaultThreadContextMap map = new DefaultThreadContextMap(true);
- map.put("key1", "value1");
- assertFalse(map.isEmpty());
-
- final Map<String, String> immutable = map.getImmutableMapOrNull();
- assertEquals("value1", immutable.get("key1")); // copy has values too
-
- // clearing context map does not affect copy
- map.clear();
- assertTrue(map.isEmpty());
-
- assertFalse(immutable.isEmpty());
- }
-
- @Test
- public void testToStringShowsMapContext() {
- final DefaultThreadContextMap map = new DefaultThreadContextMap(true);
- assertEquals("{}", map.toString());
-
- map.put("key1", "value1");
- assertEquals("{key1=value1}", map.toString());
-
- map.remove("key1");
- map.put("key2", "value2");
- assertEquals("{key2=value2}", map.toString());
- }
-
- @Test
- public void testThreadLocalNotInheritableByDefault() {
- final ThreadLocal<Map<String, String>> threadLocal = DefaultThreadContextMap.createThreadLocalMap(true, false);
- assertFalse(threadLocal instanceof InheritableThreadLocal<?>);
- }
-
- @Test
- public void testThreadLocalInheritableIfConfigured() {
- final ThreadLocal<Map<String, String>> threadLocal = DefaultThreadContextMap.createThreadLocalMap(true, true);
- assertTrue(threadLocal instanceof InheritableThreadLocal<?>);
- }
-}
diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/util/LegacyPropertiesCompatibilityTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/util/LegacyPropertiesCompatibilityTest.java
index 4067a0bced..399e09a57d 100644
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/util/LegacyPropertiesCompatibilityTest.java
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/util/LegacyPropertiesCompatibilityTest.java
@@ -63,7 +63,6 @@ public class LegacyPropertiesCompatibilityTest {
{"log4j2.asyncQueueFullPolicy", "AsyncLogger.queueFullPolicy"},
{"log4j2.discardThreshold", "AsyncLogger.discardThreshold"},
{"log4j2.isWebapp", "Web.isWebApp"},
- {"log4j2.enableThreadlocals", "ThreadLocals.enable"},
{"log4j2.enableDirectEncoders", "GC.enableDirectEncoders"},
{"log4j2.initialReusableMsgSize", "GC.initialReusableMsgSize"},
{"log4j2.maxReusableMsgSize", "GC.maxReusableMsgSize"},
diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/util/Unbox2ConfigurableTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/util/Unbox2ConfigurableTest.java
index 02f5ec427b..b5ee10aa63 100644
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/util/Unbox2ConfigurableTest.java
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/util/Unbox2ConfigurableTest.java
@@ -47,11 +47,6 @@ public class Unbox2ConfigurableTest {
FieldUtils.writeDeclaredField(field, "modifiers", field.getModifiers() & ~Modifier.FINAL);
field.set(null, 32); // reset to default
-
- final Field threadLocalField = FieldUtils.getDeclaredField(Unbox.class, "threadLocalState", true);
- final ThreadLocal<?> threadLocal = (ThreadLocal<?>) threadLocalField.get(null);
- threadLocal.remove();
- threadLocalField.set(null, new ThreadLocal<>());
}
@Test
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/ThreadContext.java b/log4j-api/src/main/java/org/apache/logging/log4j/ThreadContext.java
index 4ac8f0706a..e5a3056b6d 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/ThreadContext.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/ThreadContext.java
@@ -24,7 +24,6 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.apache.logging.log4j.message.ParameterizedMessage;
-import org.apache.logging.log4j.spi.DefaultThreadContextMap;
import org.apache.logging.log4j.spi.LoggingSystem;
import org.apache.logging.log4j.spi.LoggingSystemProperty;
import org.apache.logging.log4j.spi.ReadOnlyThreadContextMap;
@@ -311,15 +310,8 @@ public final class ThreadContext {
* Returns a read-only view of the internal data structure used to store thread context key-value pairs,
* or {@code null} if the internal data structure does not implement the
* {@code ReadOnlyThreadContextMap} interface.
- * <p>
- * The {@link DefaultThreadContextMap} implementation does not implement {@code ReadOnlyThreadContextMap}, so by
- * default this method returns {@code null}.
- * </p>
*
* @return the internal data structure used to store thread context key-value pairs or {@code null}
- * @see DefaultThreadContextMap
- * @see org.apache.logging.log4j.spi.CopyOnWriteSortedArrayThreadContextMap
- * @see org.apache.logging.log4j.spi.GarbageFreeSortedArrayThreadContextMap
* @since 2.8
*/
public static ReadOnlyThreadContextMap getThreadContextMap() {
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/internal/recycler/ThreadLocalRecyclerFactoryProvider.java b/log4j-api/src/main/java/org/apache/logging/log4j/internal/recycler/ThreadLocalRecyclerFactoryProvider.java
index 6cdbba0863..ebc9b7895e 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/internal/recycler/ThreadLocalRecyclerFactoryProvider.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/internal/recycler/ThreadLocalRecyclerFactoryProvider.java
@@ -55,11 +55,10 @@ public final class ThreadLocalRecyclerFactoryProvider implements RecyclerFactory
@Nullable
@Override
- public RecyclerFactory createForEnvironment(PropertyEnvironment environment) {
+ public RecyclerFactory createForEnvironment(final PropertyEnvironment environment) {
requireNonNull(environment, "environment");
- final boolean threadLocalEnabled =
- environment.getBooleanProperty(LoggingSystemProperty.THREAD_LOCALS_ENABLE, true);
- if (!threadLocalEnabled) {
+ final boolean webApp = environment.getBooleanProperty(LoggingSystemProperty.IS_WEBAPP, false);
+ if (webApp) {
return null;
}
final int capacity = environment.getIntegerProperty(LoggingSystemProperty.RECYCLER_CAPACITY, DEFAULT_CAPACITY);
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFactory.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFactory.java
index 21176cd0c5..b63f61a5ce 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFactory.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFactory.java
@@ -23,7 +23,6 @@ import org.apache.logging.log4j.spi.recycler.Recycler;
* If messages created by an implementation are reusable, then the {@link #recycle(Message)} method must
* be implemented and consistently used for returning objects to be reused.
*
- * @see ParameterizedMessageFactory
* @see StringFormatterMessageFactory
*/
public interface MessageFactory {
@@ -58,8 +57,6 @@ public interface MessageFactory {
* @param params
* the message parameters
* @return a new message
- * @see ParameterizedMessageFactory
- * @see StringFormatterMessageFactory
*/
Message newMessage(String message, Object... params);
@@ -78,7 +75,6 @@ public interface MessageFactory {
* @param message a message template, the kind of message template depends on the implementation.
* @param p0 a message parameter
* @return a new message
- * @see ParameterizedMessageFactory
*/
default Message newMessage(final String message, final Object p0) {
return newMessage(message, new Object[] {p0});
@@ -91,7 +87,6 @@ public interface MessageFactory {
* @param p0 a message parameter
* @param p1 a message parameter
* @return a new message
- * @see ParameterizedMessageFactory
*/
default Message newMessage(final String message, final Object p0, final Object p1) {
return newMessage(message, new Object[] {p0, p1});
@@ -105,7 +100,6 @@ public interface MessageFactory {
* @param p1 a message parameter
* @param p2 a message parameter
* @return a new message
- * @see ParameterizedMessageFactory
*/
default Message newMessage(final String message, final Object p0, final Object p1, final Object p2) {
return newMessage(message, new Object[] {p0, p1, p2});
@@ -120,7 +114,6 @@ public interface MessageFactory {
* @param p2 a message parameter
* @param p3 a message parameter
* @return a new message
- * @see ParameterizedMessageFactory
*/
default Message newMessage(
final String message, final Object p0, final Object p1, final Object p2, final Object p3) {
@@ -137,7 +130,6 @@ public interface MessageFactory {
* @param p3 a message parameter
* @param p4 a message parameter
* @return a new message
- * @see ParameterizedMessageFactory
*/
default Message newMessage(
final String message, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4) {
@@ -155,7 +147,6 @@ public interface MessageFactory {
* @param p4 a message parameter
* @param p5 a message parameter
* @return a new message
- * @see ParameterizedMessageFactory
*/
default Message newMessage(
final String message,
@@ -180,7 +171,6 @@ public interface MessageFactory {
* @param p5 a message parameter
* @param p6 a message parameter
* @return a new message
- * @see ParameterizedMessageFactory
*/
default Message newMessage(
final String message,
@@ -207,7 +197,6 @@ public interface MessageFactory {
* @param p6 a message parameter
* @param p7 a message parameter
* @return a new message
- * @see ParameterizedMessageFactory
*/
default Message newMessage(
final String message,
@@ -236,7 +225,6 @@ public interface MessageFactory {
* @param p7 a message parameter
* @param p8 a message parameter
* @return a new message
- * @see ParameterizedMessageFactory
*/
default Message newMessage(
final String message,
@@ -267,7 +255,6 @@ public interface MessageFactory {
* @param p8 a message parameter
* @param p9 a message parameter
* @return a new message
- * @see ParameterizedMessageFactory
*/
default Message newMessage(
final String message,
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFactory2.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFactory2.java
index 612b38f996..23b280ab12 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFactory2.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFactory2.java
@@ -19,7 +19,6 @@ package org.apache.logging.log4j.message;
/**
* Creates messages. Implementations can provide different message format syntaxes.
*
- * @see ParameterizedMessageFactory
* @deprecated MessageFactory now contains all interface methods.
* @since 2.6
*/
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterizedMessageFactory.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterizedMessageFactory.java
deleted file mode 100644
index 344e8fe01d..0000000000
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterizedMessageFactory.java
+++ /dev/null
@@ -1,191 +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.message;
-
-/**
- * Creates {@link FormattedMessage} instances for {@link MessageFactory}.
- * <p>
- * Enables the use of <code>{}</code> parameter markers in message strings.
- * </p>
- * <p>
- * Creates {@link ParameterizedMessage} instances for {@link #newMessage(String, Object...)}.
- * </p>
- * <p>
- * This class is immutable.
- * </p>
- *
- * <p>
- * <strong>Note to implementors:</strong>
- * </p>
- * <p>
- * This class implements all {@link MessageFactory} methods.
- * </p>
- */
-public final class ParameterizedMessageFactory implements MessageFactory {
- /**
- * Instance of ParameterizedMessageFactory.
- */
- public static final ParameterizedMessageFactory INSTANCE = new ParameterizedMessageFactory();
-
- /**
- * Constructs a message factory.
- */
- public ParameterizedMessageFactory() {
- super();
- }
-
- /**
- * Creates {@link ParameterizedMessage} instances.
- *
- * @param message The message pattern.
- * @param params The message parameters.
- * @return The Message.
- *
- * @see MessageFactory#newMessage(String, Object...)
- */
- @Override
- public Message newMessage(final String message, final Object... params) {
- return new ParameterizedMessage(message, params);
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(final String message, final Object p0) {
- return new ParameterizedMessage(message, p0);
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1) {
- return new ParameterizedMessage(message, p0, p1);
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1, final Object p2) {
- return new ParameterizedMessage(message, p0, p1, p2);
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(
- final String message, final Object p0, final Object p1, final Object p2, final Object p3) {
- return new ParameterizedMessage(message, p0, p1, p2, p3);
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(
- final String message, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4) {
- return new ParameterizedMessage(message, p0, p1, p2, p3, p4);
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(
- final String message,
- final Object p0,
- final Object p1,
- final Object p2,
- final Object p3,
- final Object p4,
- final Object p5) {
- return new ParameterizedMessage(message, p0, p1, p2, p3, p4, p5);
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(
- final String message,
- final Object p0,
- final Object p1,
- final Object p2,
- final Object p3,
- final Object p4,
- final Object p5,
- final Object p6) {
- return new ParameterizedMessage(message, p0, p1, p2, p3, p4, p5, p6);
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(
- final String message,
- final Object p0,
- final Object p1,
- final Object p2,
- final Object p3,
- final Object p4,
- final Object p5,
- final Object p6,
- final Object p7) {
- return new ParameterizedMessage(message, p0, p1, p2, p3, p4, p5, p6, p7);
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(
- final String message,
- final Object p0,
- final Object p1,
- final Object p2,
- final Object p3,
- final Object p4,
- final Object p5,
- final Object p6,
- final Object p7,
- final Object p8) {
- return new ParameterizedMessage(message, p0, p1, p2, p3, p4, p5, p6, p7, p8);
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(
- final String message,
- final Object p0,
- final Object p1,
- final Object p2,
- final Object p3,
- final Object p4,
- final Object p5,
- final Object p6,
- final Object p7,
- final Object p8,
- final Object p9) {
- return new ParameterizedMessage(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
- }
-}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableMessageFactory.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableMessageFactory.java
index 7abd8ac064..3b71f2896f 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableMessageFactory.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableMessageFactory.java
@@ -23,9 +23,8 @@ import org.apache.logging.log4j.util.PerformanceSensitive;
/**
* Implementation of the {@link MessageFactory} interface that avoids allocating temporary objects where possible.
- * Message instances are cached in a ThreadLocal and reused when a new message is requested within the same thread.
+ * Message instances are cached in a {@link Recycler} and reused when a new message is requested.
* Messages returned from this factory must be {@linkplain #recycle(Message) recycled} when done using.
- * @see ParameterizedMessageFactory
* @see ReusableSimpleMessage
* @see ReusableObjectMessage
* @see ReusableParameterizedMessage
@@ -33,15 +32,10 @@ import org.apache.logging.log4j.util.PerformanceSensitive;
* @since 2.6
*/
@PerformanceSensitive("allocation")
-/*
- * https://errorprone.info/bugpattern/ThreadLocalUsage
- * Instance thread locals are not a problem here, since this class is almost a singleton.
- */
-@SuppressWarnings("ThreadLocalUsage")
public final class ReusableMessageFactory implements MessageFactory {
/**
- * Instance of ReusableMessageFactory..
+ * Instance of {@link ReusableMessageFactory}.
*/
public static final ReusableMessageFactory INSTANCE = new ReusableMessageFactory();
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/DefaultThreadContextMap.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/DefaultThreadContextMap.java
deleted file mode 100644
index c9ec6b1f2b..0000000000
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/DefaultThreadContextMap.java
+++ /dev/null
@@ -1,228 +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.spi;
-
-import static org.apache.logging.log4j.spi.LoggingSystemProperty.THREAD_CONTEXT_MAP_INHERITABLE;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import org.apache.logging.log4j.util.BiConsumer;
-import org.apache.logging.log4j.util.Cast;
-import org.apache.logging.log4j.util.PropertiesUtil;
-import org.apache.logging.log4j.util.ReadOnlyStringMap;
-import org.apache.logging.log4j.util.TriConsumer;
-
-/**
- * The actual ThreadContext Map. A new ThreadContext Map is created each time it is updated and the Map stored is always
- * immutable. This means the Map can be passed to other threads without concern that it will be updated. Since it is
- * expected that the Map will be passed to many more log events than the number of keys it contains the performance
- * should be much better than if the Map was copied for each event.
- */
-public class DefaultThreadContextMap implements ThreadContextMap, ReadOnlyStringMap {
-
- private final boolean useMap;
- private final ThreadLocal<Map<String, String>> localMap;
-
- static ThreadLocal<Map<String, String>> createThreadLocalMap(
- final boolean isMapEnabled, final boolean inheritableMap) {
- if (inheritableMap) {
- return new InheritableThreadLocal<>() {
- @Override
- protected Map<String, String> childValue(final Map<String, String> parentValue) {
- return parentValue != null && isMapEnabled ? Map.copyOf(parentValue) : null;
- }
- };
- }
- // if not inheritable, return plain ThreadLocal with null as initial value
- return new ThreadLocal<>();
- }
-
- public DefaultThreadContextMap() {
- this(true);
- }
-
- public DefaultThreadContextMap(final boolean useMap) {
- this(useMap, PropertiesUtil.getProperties().getBooleanProperty(THREAD_CONTEXT_MAP_INHERITABLE));
- }
-
- DefaultThreadContextMap(final boolean useMap, final boolean inheritableMap) {
- this.useMap = useMap;
- this.localMap = createThreadLocalMap(useMap, inheritableMap);
- }
-
- @Override
- public void put(final String key, final String value) {
- if (!useMap) {
- return;
- }
- Map<String, String> map = localMap.get();
- map = map == null ? new HashMap<>(1) : new HashMap<>(map);
- map.put(key, value);
- localMap.set(Collections.unmodifiableMap(map));
- }
-
- @Override
- public void putAll(final Map<String, String> m) {
- if (!useMap) {
- return;
- }
- Map<String, String> map = localMap.get();
- map = map == null ? new HashMap<>(m.size()) : new HashMap<>(map);
- map.putAll(m);
- localMap.set(Collections.unmodifiableMap(map));
- }
-
- @Override
- public String get(final String key) {
- final Map<String, String> map = localMap.get();
- return map == null ? null : map.get(key);
- }
-
- @Override
- public void remove(final String key) {
- final Map<String, String> map = localMap.get();
- if (map != null) {
- final Map<String, String> copy = new HashMap<>(map);
- copy.remove(key);
- localMap.set(Collections.unmodifiableMap(copy));
- }
- }
-
- @Override
- public void removeAll(final Iterable<String> keys) {
- final Map<String, String> map = localMap.get();
- if (map != null) {
- final Map<String, String> copy = new HashMap<>(map);
- for (final String key : keys) {
- copy.remove(key);
- }
- localMap.set(Collections.unmodifiableMap(copy));
- }
- }
-
- @Override
- public void clear() {
- localMap.remove();
- }
-
- @Override
- public Map<String, String> toMap() {
- return getCopy();
- }
-
- @Override
- public boolean containsKey(final String key) {
- final Map<String, String> map = localMap.get();
- return map != null && map.containsKey(key);
- }
-
- @Override
- public <V> void forEach(final BiConsumer<String, ? super V> action) {
- final Map<String, String> map = localMap.get();
- if (map == null) {
- return;
- }
- for (final Map.Entry<String, String> entry : map.entrySet()) {
- // BiConsumer should be able to handle values of any type V. In our case the values are of type String.
- final V value = Cast.cast(entry.getValue());
- action.accept(entry.getKey(), value);
- }
- }
-
- @Override
- public <V, S> void forEach(final TriConsumer<String, ? super V, S> action, final S state) {
- final Map<String, String> map = localMap.get();
- if (map == null) {
- return;
- }
- for (final Map.Entry<String, String> entry : map.entrySet()) {
- // TriConsumer should be able to handle values of any type V. In our case the values are of type String.
- final V value = Cast.cast(entry.getValue());
- action.accept(entry.getKey(), value, state);
- }
- }
-
- @Override
- public <V> V getValue(final String key) {
- final Map<String, String> map = localMap.get();
- return map == null ? null : Cast.cast(map.get(key));
- }
-
- @Override
- public Map<String, String> getCopy() {
- final Map<String, String> map = localMap.get();
- return map == null ? new HashMap<>() : new HashMap<>(map);
- }
-
- @Override
- public Map<String, String> getImmutableMapOrNull() {
- return localMap.get();
- }
-
- @Override
- public boolean isEmpty() {
- final Map<String, String> map = localMap.get();
- return map == null || map.isEmpty();
- }
-
- @Override
- public int size() {
- final Map<String, String> map = localMap.get();
- return map == null ? 0 : map.size();
- }
-
- @Override
- public String toString() {
- final Map<String, String> map = localMap.get();
- return map == null ? "{}" : map.toString();
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- final Map<String, String> map = this.localMap.get();
- result = prime * result + ((map == null) ? 0 : map.hashCode());
- result = prime * result + Boolean.valueOf(this.useMap).hashCode();
- return result;
- }
-
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (obj instanceof DefaultThreadContextMap) {
- final DefaultThreadContextMap other = (DefaultThreadContextMap) obj;
- if (this.useMap != other.useMap) {
- return false;
- }
- }
- if (!(obj instanceof ThreadContextMap)) {
- return false;
- }
- final ThreadContextMap other = (ThreadContextMap) obj;
- final Map<String, String> map = this.localMap.get();
- final Map<String, String> otherMap = other.getImmutableMapOrNull();
- return Objects.equals(map, otherMap);
- }
-}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggingSystem.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggingSystem.java
index 46cf2ae91f..02ad1242e7 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggingSystem.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggingSystem.java
@@ -44,12 +44,10 @@ import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.message.DefaultFlowMessageFactory;
import org.apache.logging.log4j.message.FlowMessageFactory;
import org.apache.logging.log4j.message.MessageFactory;
-import org.apache.logging.log4j.message.ParameterizedMessageFactory;
import org.apache.logging.log4j.message.ReusableMessageFactory;
import org.apache.logging.log4j.simple.SimpleLoggerContextFactory;
import org.apache.logging.log4j.spi.recycler.RecyclerFactory;
import org.apache.logging.log4j.spi.recycler.RecyclerFactoryRegistry;
-import org.apache.logging.log4j.util.Constants;
import org.apache.logging.log4j.util.Lazy;
import org.apache.logging.log4j.util.LoaderUtil;
import org.apache.logging.log4j.util.LowLevelLogUtil;
@@ -90,7 +88,7 @@ public class LoggingSystem {
return factory;
}
}
- return Constants.isThreadLocalsEnabled() ? new ReusableMessageFactory() : new ParameterizedMessageFactory();
+ return new ReusableMessageFactory();
});
private final Lazy<FlowMessageFactory> flowMessageFactoryLazy = environmentLazy.map(environment -> {
final String className = environment.getStringProperty(LOGGER_FLOW_MESSAGE_FACTORY_CLASS);
@@ -312,7 +310,7 @@ public class LoggingSystem {
/**
* Creates the ThreadContextMap instance used by the ThreadContext.
* <p>
- * If {@linkplain Constants#isThreadLocalsEnabled() Log4j can use ThreadLocals}, a garbage-free StringMap-based context map can
+ * A garbage-free StringMap-based context map can
* be installed by setting system property {@link LoggingSystemProperty#THREAD_CONTEXT_GARBAGE_FREE_ENABLED} to {@code true}.
* </p><p>
* Furthermore, any custom {@code ThreadContextMap} can be installed by setting system property
@@ -351,18 +349,14 @@ public class LoggingSystem {
return map;
}
}
- final boolean threadLocalsEnabled = Constants.isThreadLocalsEnabled();
final boolean garbageFreeEnabled = environment.getBooleanProperty(THREAD_CONTEXT_GARBAGE_FREE_ENABLED);
final boolean inheritableMap = environment.getBooleanProperty(THREAD_CONTEXT_MAP_INHERITABLE);
final int initialCapacity = environment.getIntegerProperty(
THREAD_CONTEXT_INITIAL_CAPACITY, THREAD_CONTEXT_DEFAULT_INITIAL_CAPACITY);
- if (threadLocalsEnabled) {
- if (garbageFreeEnabled) {
- return new GarbageFreeSortedArrayThreadContextMap(inheritableMap, initialCapacity);
- }
- return new CopyOnWriteSortedArrayThreadContextMap(inheritableMap, initialCapacity);
+ if (garbageFreeEnabled) {
+ return new GarbageFreeSortedArrayThreadContextMap(inheritableMap, initialCapacity);
}
- return new DefaultThreadContextMap(true, inheritableMap);
+ return new CopyOnWriteSortedArrayThreadContextMap(inheritableMap, initialCapacity);
}
public ThreadContextStack createContextStack(final PropertyEnvironment environment) {
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggingSystemProperty.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggingSystemProperty.java
index 90ae13311d..fa839f076c 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggingSystemProperty.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggingSystemProperty.java
@@ -45,13 +45,6 @@ public enum LoggingSystemProperty implements PropertyKey {
*/
// GC.maxReusableMsgSize
GC_REUSABLE_MESSAGE_MAX_SIZE(PropertyComponent.GC, Constant.MAX_REUSABLE_MSG_SIZE),
- /**
- * Property to override the use of thread-local values for garbage-free logging.
- *
- * @see <a href="https://issues.apache.org/jira/browse/LOG4J2-1270">LOG4J2-1270</a>
- */
- // ThreadLocals.enabled : calculate | true | false
- THREAD_LOCALS_ENABLE(PropertyComponent.THREAD_LOCALs, Constant.ENABLE),
/**
* Property to ignore the thread context ClassLoader when set to {@code true}.
@@ -280,12 +273,9 @@ public enum LoggingSystemProperty implements PropertyKey {
*
* @see <a href="https://issues.apache.org/jira/browse/LOG4J2-1270">LOG4J2-1270</a>
*/
- // ThreadLocals.enabled : calculate | true | false
+ // ThreadContext.enabled : calculate | true | false
static final String ENABLE = "enable";
- public static final String THREAD_LOCALS_ENABLE =
- SYSTEM_PROPERTY_PREFIX + PropertyComponent.Constant.THREAD_LOCALS + DELIM + ENABLE;
-
/**
* Property to ignore the thread context ClassLoader when set to {@code true}.
*
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/PropertyComponent.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/PropertyComponent.java
index 5dd99ef77a..b359b60c64 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/PropertyComponent.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/PropertyComponent.java
@@ -41,7 +41,6 @@ public enum PropertyComponent {
STATUS_LOGGER(Constant.STATUS_LOGGER),
SYSTEM(Constant.SYSTEM),
THREAD_CONTEXT(Constant.THREAD_CONTEXT),
- THREAD_LOCALs(Constant.THREAD_LOCALS),
TRANSPORT_SECURITY(Constant.TRANSPORT_SECURITY),
UUID(Constant.UUID),
WEB(Constant.WEB);
@@ -81,7 +80,6 @@ public enum PropertyComponent {
public static final String STATUS_LOGGER = "StatusLogger";
public static final String SYSTEM = "System";
public static final String THREAD_CONTEXT = "ThreadContext";
- public static final String THREAD_LOCALS = "ThreadLocals";
public static final String TRANSPORT_SECURITY = "TransportSecurity";
public static final String UUID = "UUID";
public static final String WEB = "Web";
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/Constants.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/Constants.java
index c2e47aba35..78fd2eccc1 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/Constants.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/Constants.java
@@ -49,28 +49,6 @@ public final class Constants {
isWebApp.reset();
}
- private static final LazyBoolean threadLocalsEnabled = new LazyBoolean(() -> !isWebApp()
- && PropertiesUtil.getProperties().getBooleanProperty(LoggingSystemProperty.THREAD_LOCALS_ENABLE, true));
-
- /**
- * Kill switch for object pooling in ThreadLocals that enables much of the LOG4J2-1270 no-GC behaviour.
- * <p>
- * {@code True} for non-{@link #isWebApp()} web apps}, disable by setting system property
- * "log4j2.enable.threadlocals" to "false".
- * </p>
- */
- public static boolean isThreadLocalsEnabled() {
- return threadLocalsEnabled.getAsBoolean();
- }
-
- public static void setThreadLocalsEnabled(final boolean enabled) {
- threadLocalsEnabled.setAsBoolean(enabled);
- }
-
- public static void resetThreadLocalsEnabled() {
- threadLocalsEnabled.reset();
- }
-
public static final int JAVA_MAJOR_VERSION = getMajorVersion();
/**
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/Unbox.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/Unbox.java
index 9984f53d4d..e08b3609db 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/Unbox.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/Unbox.java
@@ -90,24 +90,6 @@ public class Unbox {
}
}
- private static class State {
- private final StringBuilder[] ringBuffer = new StringBuilder[RINGBUFFER_SIZE];
- private int current;
-
- State() {
- for (int i = 0; i < ringBuffer.length; i++) {
- ringBuffer[i] = new StringBuilder(21);
- }
- }
-
- public StringBuilder getStringBuilder() {
- final StringBuilder result = ringBuffer[MASK & current++];
- result.setLength(0);
- return result;
- }
- }
-
- private static final ThreadLocal<State> threadLocalState = new ThreadLocal<>();
private static final WebSafeState webSafeState = new WebSafeState();
private Unbox() {
@@ -243,17 +225,8 @@ public class Unbox {
return getSB().append(value);
}
- private static State getState() {
- State state = threadLocalState.get();
- if (state == null) {
- state = new State();
- threadLocalState.set(state);
- }
- return state;
- }
-
private static StringBuilder getSB() {
- return Constants.isThreadLocalsEnabled() ? getState().getStringBuilder() : webSafeState.getStringBuilder();
+ return webSafeState.getStringBuilder();
}
/** For testing. */
diff --git a/log4j-api/src/main/resources/log4j2.propertyMapping.json b/log4j-api/src/main/resources/log4j2.propertyMapping.json
index 6a07494108..5edb3f7bf9 100644
--- a/log4j-api/src/main/resources/log4j2.propertyMapping.json
+++ b/log4j-api/src/main/resources/log4j2.propertyMapping.json
@@ -4,7 +4,6 @@
"debug": ["StatusLogger", "enableDebug"],
"defaultStatusLevel": ["StatusLogger", "defaultLevel"],
"garbagefreeThreadContextMap": ["ThreadContext", "garbageFreeMap"],
- "enableThreadlocals": ["ThreadLocals", "enable"],
"forceTCLOnly": ["Loader", "forceTCLOnly"],
"ignoreTCL": ["Loader", "ignoreTCL"],
"initialReusableMsgSize": ["GC", "initialReusableMsgSize"],
@@ -36,7 +35,6 @@
"DEBUG": ["StatusLogger", "enableDebug"],
"DEFAULT_STATUS_LEVEL": ["StatusLogger", "defaultLevel"],
"GARBAGEFREE_THREAD_CONTEXT_MAP": ["ThreadContext", "garbageFreeMap"],
- "ENABLE_THREADLOCALS": ["ThreadLocals", "enable"],
"FORCE_TCL_ONLY": ["Loader", "forceTCLOnly"],
"IGNORE_TCL": ["Loader", "ignoreTCL"],
"INITIAL_REUSABLE_MSG_SIZE": ["GC", "initialReusableMsgSize"],
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/async/perftest/ResponseTimeTest.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/async/perftest/ResponseTimeTest.java
index b67d39e2a5..f1c7d5e7d9 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/async/perftest/ResponseTimeTest.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/async/perftest/ResponseTimeTest.java
@@ -28,7 +28,6 @@ import org.HdrHistogram.Histogram;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.async.DefaultAsyncQueueFullPolicy;
import org.apache.logging.log4j.core.async.EventRoute;
-import org.apache.logging.log4j.core.util.Constants;
import org.apache.logging.log4j.core.util.Integers;
import org.apache.logging.log4j.core.util.Loader;
@@ -160,10 +159,6 @@ public class ResponseTimeTest {
warmupResponseTmHistograms,
threadCount);
System.out.println("-----------------Warmup done. load=" + loadMessagesPerSec);
- if (!Constants.ENABLE_DIRECT_ENCODERS || !Constants.ENABLE_THREADLOCALS) {
- // System.gc();
- // Thread.sleep(5000);
- }
System.out.println("-----------------Starting measured run. load=" + loadMessagesPerSec);
final long start = System.currentTimeMillis();
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/async/perftest/SimplePerfTest.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/async/perftest/SimplePerfTest.java
index d1de5621d2..11ac9f5801 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/async/perftest/SimplePerfTest.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/async/perftest/SimplePerfTest.java
@@ -19,15 +19,12 @@ package org.apache.logging.log4j.core.async.perftest;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
-import java.lang.reflect.Method;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.async.AsyncLogger;
-import org.apache.logging.log4j.core.async.AsyncLoggerContext;
import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
-import org.apache.logging.log4j.spi.LoggerContext;
/**
* Created by remko on 2/26/2016.
@@ -44,8 +41,6 @@ public class SimplePerfTest {
if (!(logger instanceof AsyncLogger)) {
throw new IllegalStateException();
}
- // work around a bug in Log4j-2.5
- workAroundLog4j2_5Bug();
logger.error("Starting...");
System.out.println("Starting...");
@@ -143,15 +138,4 @@ public class SimplePerfTest {
logger.error("simple text message");
}
}
-
- private static void workAroundLog4j2_5Bug() {
- // use reflection so we can use the same test with older versions of log4j2
- try {
- final Method setUseThreadLocals =
- AsyncLoggerContext.class.getDeclaredMethod("setUseThreadLocals", boolean.class);
- final LoggerContext context = LogManager.getContext(false);
- setUseThreadLocals.invoke(context, Boolean.TRUE);
- } catch (final Throwable ignored) {
- }
- }
}
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/LoggerTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
index f7ed642eaa..4226c55734 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
@@ -41,7 +41,7 @@ import org.apache.logging.log4j.core.test.junit.Named;
import org.apache.logging.log4j.core.test.junit.ReconfigurationPolicy;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MessageFactory;
-import org.apache.logging.log4j.message.ParameterizedMessageFactory;
+import org.apache.logging.log4j.message.ReusableMessageFactory;
import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.message.StringFormatterMessageFactory;
import org.apache.logging.log4j.message.StructuredDataMessage;
@@ -383,7 +383,7 @@ public class LoggerTest {
final Logger testLogger = testMessageFactoryMismatch(
testInfo.getTestMethod().map(Method::getName).orElseThrow(AssertionError::new),
StringFormatterMessageFactory.INSTANCE,
- ParameterizedMessageFactory.INSTANCE);
+ new ReusableMessageFactory());
testLogger.debug("%,d", Integer.MAX_VALUE);
final List<LogEvent> events = app.getEvents();
assertEventCount(events, 1);
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessorTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessorTest.java
index b63486caec..3a776f9417 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessorTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessorTest.java
@@ -25,6 +25,7 @@ import java.time.ZoneId;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
+import org.apache.logging.log4j.core.config.NullConfiguration;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.ResourceAccessMode;
import org.junit.jupiter.api.parallel.ResourceLock;
@@ -42,7 +43,7 @@ public class PatternProcessorTest {
@Test
@ResourceLock(value = Resources.LOCALE, mode = ResourceAccessMode.READ)
public void testDontInterpretBackslashAsEscape() {
- final PatternProcessor pp = new PatternProcessor("c:\\test\\new/app-%d{HH-mm-ss}.log");
+ final PatternProcessor pp = createPatternProcessor("c:\\test\\new/app-%d{HH-mm-ss}.log");
final Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 16);
cal.set(Calendar.MINUTE, 2);
@@ -56,7 +57,7 @@ public class PatternProcessorTest {
@Test
@ResourceLock(value = Resources.LOCALE, mode = ResourceAccessMode.READ)
public void testGetNextTimeHourlyReturnsFirstMinuteOfNextHour() {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-dd-HH}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-dd-HH}.log.gz");
final Instant initial = parseLocalDateTime("2014-03-04T10:31:59");
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -67,7 +68,7 @@ public class PatternProcessorTest {
@Test
@ResourceLock(value = Resources.LOCALE, mode = ResourceAccessMode.READ)
public void testGetNextTimeHourlyReturnsFirstMinuteOfNextHour2() {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-dd-HH}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-dd-HH}.log.gz");
final Instant initial = parseLocalDateTime("2014-03-04T23:31:59");
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -81,7 +82,7 @@ public class PatternProcessorTest {
// America/Chicago 2014 - DST start - Mar 9 02:00
// during winter GMT-6
// during summer GMT-5
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-dd-HH}{America/Chicago}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-dd-HH}{America/Chicago}.log.gz");
final Instant initial =
OffsetDateTime.parse("2014-03-09T01:31:59-06:00").toInstant();
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -97,7 +98,7 @@ public class PatternProcessorTest {
// America/Chicago 2014 - DST end - Nov 2 02:00
// during summer GMT-5
// during winter GMT-6
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-dd-HH}{America/Chicago}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-dd-HH}{America/Chicago}.log.gz");
final Instant initial =
OffsetDateTime.parse("2014-11-02T01:31:59-05:00").toInstant();
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -111,7 +112,7 @@ public class PatternProcessorTest {
@Test
@ResourceLock(value = Resources.LOCALE, mode = ResourceAccessMode.READ)
public void testGetNextTimeHourlyReturnsFirstMinuteOfNextYear() {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-dd-HH}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-dd-HH}.log.gz");
final Instant initial = parseLocalDateTime("2015-12-31T23:31:59");
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -122,7 +123,7 @@ public class PatternProcessorTest {
@Test
@ResourceLock(value = Resources.LOCALE, mode = ResourceAccessMode.READ)
public void testGetNextTimeMillisecondlyReturnsNextMillisec() {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-dd-HH-mm-ss.SSS}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-dd-HH-mm-ss.SSS}.log.gz");
final Instant initial = parseLocalDateTime("2014-03-04T10:31:53.123");
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -133,7 +134,7 @@ public class PatternProcessorTest {
@Test
@ResourceLock(value = Resources.LOCALE, mode = ResourceAccessMode.READ)
public void testGetNextTimeMinutelyReturnsFirstSecondOfNextMinute() {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-dd-HH-mm}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-dd-HH-mm}.log.gz");
final Instant initial = parseLocalDateTime("2014-03-04T10:31:59");
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -144,7 +145,7 @@ public class PatternProcessorTest {
@Test
@ResourceLock(value = Resources.LOCALE, mode = ResourceAccessMode.READ)
public void testGetNextTimeMonthlyReturnsFirstDayOfNextMonth() {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM}.log.gz");
final Instant initial = parseLocalDateTime("2014-10-15T10:31:59");
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -155,7 +156,7 @@ public class PatternProcessorTest {
@Test
@ResourceLock(value = Resources.LOCALE, mode = ResourceAccessMode.READ)
public void testGetNextTimeMonthlyReturnsFirstDayOfNextMonth2() {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM}.log.gz");
final Instant initial = parseLocalDateTime("2014-01-31T10:31:59");
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -167,7 +168,7 @@ public class PatternProcessorTest {
@Test
@ResourceLock(value = Resources.LOCALE, mode = ResourceAccessMode.READ)
public void testGetNextTimeMonthlyReturnsFirstDayOfNextMonth3() {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM}.log.gz");
final Instant initial = parseLocalDateTime("2014-12-31T10:31:59");
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -179,7 +180,7 @@ public class PatternProcessorTest {
@Test
@ResourceLock(value = Resources.LOCALE, mode = ResourceAccessMode.READ)
public void testGetNextTimeMonthlyReturnsFirstDayOfNextYear() {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM}.log.gz");
final Instant initial = parseLocalDateTime("2015-12-28T00:00:00");
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -191,7 +192,7 @@ public class PatternProcessorTest {
@Test
@ResourceLock(value = Resources.LOCALE, mode = ResourceAccessMode.READ)
public void testGetNextTimeSecondlyReturnsFirstMillisecOfNextSecond() {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-dd-HH-mm-ss}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-dd-HH-mm-ss}.log.gz");
final Instant initial = parseLocalDateTime("2014-03-04T10:31:53.123");
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -206,7 +207,7 @@ public class PatternProcessorTest {
Locale.setDefault(Locale.FRANCE); // force 1st day of the week to be Monday
try {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-W}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-W}.log.gz");
final Instant initial = parseLocalDateTime("2014-03-04T10:31:59");
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -224,7 +225,7 @@ public class PatternProcessorTest {
Locale.setDefault(Locale.US); // force 1st day of the week to be Sunday
try {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-W}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-W}.log.gz");
final Instant initial = parseLocalDateTime("2014-03-04T10:31:59");
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -244,7 +245,7 @@ public class PatternProcessorTest {
final Locale old = Locale.getDefault();
Locale.setDefault(Locale.US); // force 1st day of the week to be Sunday
try {
- final PatternProcessor pp = new PatternProcessor("logs/market_data_msg.log-%d{yyyy-MM-'W'W}");
+ final PatternProcessor pp = createPatternProcessor("logs/market_data_msg.log-%d{yyyy-MM-'W'W}");
final Instant initial = parseLocalDateTime("2015-12-28T00:00:00");
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -258,7 +259,7 @@ public class PatternProcessorTest {
@Test
@ResourceLock(value = Resources.LOCALE, mode = ResourceAccessMode.READ)
public void testGetNextTimeDailyReturnsFirstHourOfNextDay() {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-dd}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-dd}.log.gz");
final Instant initial = parseLocalDateTime("2014-03-04T02:31:59");
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -269,7 +270,7 @@ public class PatternProcessorTest {
@Test
@ResourceLock(value = Resources.LOCALE, mode = ResourceAccessMode.READ)
public void testGetNextTimeDailyReturnsFirstHourOfNextDayHonoringTimeZoneOption1() {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-dd}{GMT-6}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-dd}{GMT-6}.log.gz");
final Instant initial =
OffsetDateTime.parse("2014-03-04T02:31:59-06:00").toInstant();
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -286,7 +287,7 @@ public class PatternProcessorTest {
final TimeZone old = TimeZone.getDefault();
TimeZone.setDefault(TimeZone.getTimeZone("GMT+10")); // default is ignored if pattern contains timezone
try {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-dd}{GMT-6}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-dd}{GMT-6}.log.gz");
final Instant initial =
OffsetDateTime.parse("2014-03-04T02:31:59-06:00").toInstant();
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -306,7 +307,7 @@ public class PatternProcessorTest {
final TimeZone old = TimeZone.getDefault();
TimeZone.setDefault(TimeZone.getTimeZone("GMT-10")); // default is ignored if pattern contains timezone
try {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-dd}{GMT-6}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-dd}{GMT-6}.log.gz");
final Instant initial =
OffsetDateTime.parse("2014-03-04T02:31:59-06:00").toInstant();
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -322,7 +323,7 @@ public class PatternProcessorTest {
@Test
@ResourceLock(value = Resources.LOCALE, mode = ResourceAccessMode.READ)
public void testGetNextTimeDailyReturnsFirstHourOfNextDayDstJan() {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-dd}{America/Chicago}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-dd}{America/Chicago}.log.gz");
final Instant initial =
OffsetDateTime.parse("2014-01-04T00:31:59-06:00").toInstant();
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -335,7 +336,7 @@ public class PatternProcessorTest {
@Test
@ResourceLock(value = Resources.LOCALE, mode = ResourceAccessMode.READ)
public void testGetNextTimeDailyReturnsFirstHourOfNextDayDstJun() {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-dd}{America/Chicago}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-dd}{America/Chicago}.log.gz");
final Instant initial =
OffsetDateTime.parse("2014-06-04T00:31:59-05:00").toInstant();
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -351,7 +352,7 @@ public class PatternProcessorTest {
// America/Chicago 2014 - DST start - Mar 9 02:00
// during winter GMT-6
// during summer GMT-5
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-dd}{America/Chicago}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-dd}{America/Chicago}.log.gz");
final Instant initial =
OffsetDateTime.parse("2014-03-09T00:31:59-06:00").toInstant();
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -367,7 +368,7 @@ public class PatternProcessorTest {
// America/Chicago 2014 - DST end - Nov 2 02:00
// during summer GMT-5
// during winter GMT-6
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-dd}{America/Chicago}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-dd}{America/Chicago}.log.gz");
final Instant initial =
OffsetDateTime.parse("2014-11-02T00:31:59-05:00").toInstant();
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -384,7 +385,7 @@ public class PatternProcessorTest {
final TimeZone old = TimeZone.getDefault();
TimeZone.setDefault(TimeZone.getTimeZone("GMT-10")); // default is ignored even if timezone option invalid
try {
- final PatternProcessor pp = new PatternProcessor("logs/app-%d{yyyy-MM-dd}{NOTVALID}.log.gz");
+ final PatternProcessor pp = createPatternProcessor("logs/app-%d{yyyy-MM-dd}{NOTVALID}.log.gz");
final Instant initial = Instant.parse("2014-03-04T02:31:59Z");
final long actual = pp.getNextTime(initial.toEpochMilli(), 1, false);
@@ -394,4 +395,8 @@ public class PatternProcessorTest {
TimeZone.setDefault(old);
}
}
+
+ private static PatternProcessor createPatternProcessor(final String pattern) {
+ return new PatternProcessor(new NullConfiguration(), pattern);
+ }
}
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerTest.java
index 35ec4b01bb..875f88173f 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerTest.java
@@ -41,6 +41,7 @@ import java.nio.file.attribute.PosixFilePermissions;
import java.util.Set;
import java.util.concurrent.locks.LockSupport;
import org.apache.logging.log4j.core.config.DefaultConfiguration;
+import org.apache.logging.log4j.core.config.NullConfiguration;
import org.apache.logging.log4j.core.util.Closer;
import org.apache.logging.log4j.core.util.FileUtils;
import org.apache.logging.log4j.util.Strings;
@@ -68,6 +69,7 @@ public class RollingRandomAccessFileManagerTest {
final TriggeringPolicy triggerPolicy = new SizeBasedTriggeringPolicy(triggerSize);
final RolloverStrategy rolloverStrategy = null;
final RollingRandomAccessFileManager manager = new RollingRandomAccessFileManager(
+ new NullConfiguration(),
null,
raf,
file.getName(),
@@ -113,6 +115,7 @@ public class RollingRandomAccessFileManagerTest {
final TriggeringPolicy triggerPolicy = new SizeBasedTriggeringPolicy(triggerSize);
final RolloverStrategy rolloverStrategy = null;
final RollingRandomAccessFileManager manager = new RollingRandomAccessFileManager(
+ new NullConfiguration(),
null,
raf,
file.getName(),
@@ -157,6 +160,7 @@ public class RollingRandomAccessFileManagerTest {
assertNotEquals(bufferSize, RollingRandomAccessFileManager.DEFAULT_BUFFER_SIZE);
final RolloverStrategy rolloverStrategy = null;
final RollingRandomAccessFileManager manager = new RollingRandomAccessFileManager(
+ new NullConfiguration(),
null,
raf,
file.getName(),
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadNameStrategyTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadNameStrategyTest.java
deleted file mode 100644
index 96d4d54adf..0000000000
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadNameStrategyTest.java
+++ /dev/null
@@ -1,78 +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.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertSame;
-
-import org.apache.logging.log4j.core.impl.Log4jPropertyKey;
-import org.junit.jupiter.api.Tag;
-import org.junit.jupiter.api.Test;
-import org.junitpioneer.jupiter.SetSystemProperty;
-
-@Tag("async")
-public class AsyncLoggerThreadNameStrategyTest {
-
- @Test
- public void testDefaultIfNotConfigured() throws Exception {
- final ThreadNameCachingStrategy tns = ThreadNameCachingStrategy.create();
- assertSame(ThreadNameCachingStrategy.DEFAULT_STRATEGY, tns);
- }
-
- @Test
- @SetSystemProperty(key = Log4jPropertyKey.Constant.ASYNC_LOGGER_THREAD_NAME_STRATEGY, value = "\\%%InValid ")
- public void testDefaultIfInvalidConfig() throws Exception {
- final ThreadNameCachingStrategy tns = ThreadNameCachingStrategy.create();
- assertSame(ThreadNameCachingStrategy.DEFAULT_STRATEGY, tns);
- }
-
- @Test
- @SetSystemProperty(key = Log4jPropertyKey.Constant.ASYNC_LOGGER_THREAD_NAME_STRATEGY, value = "CACHED")
- public void testUseCachedThreadNameIfConfigured() throws Exception {
- final ThreadNameCachingStrategy tns = ThreadNameCachingStrategy.create();
- assertSame(ThreadNameCachingStrategy.CACHED, tns);
- }
-
- @Test
- @SetSystemProperty(key = Log4jPropertyKey.Constant.ASYNC_LOGGER_THREAD_NAME_STRATEGY, value = "UNCACHED")
- public void testUseUncachedThreadNameIfConfigured() throws Exception {
- final ThreadNameCachingStrategy tns = ThreadNameCachingStrategy.create();
- assertSame(ThreadNameCachingStrategy.UNCACHED, tns);
- }
-
- @Test
- public void testUncachedThreadNameStrategyReturnsCurrentThreadName() throws Exception {
- final String name1 = "MODIFIED-THREADNAME1";
- Thread.currentThread().setName(name1);
- assertEquals(name1, ThreadNameCachingStrategy.UNCACHED.getThreadName());
-
- final String name2 = "OTHER-THREADNAME2";
- Thread.currentThread().setName(name2);
- assertEquals(name2, ThreadNameCachingStrategy.UNCACHED.getThreadName());
- }
-
- @Test
- public void testCachedThreadNameStrategyReturnsCachedThreadName() throws Exception {
- final String original = "Original-ThreadName";
- Thread.currentThread().setName(original);
- assertEquals(original, ThreadNameCachingStrategy.CACHED.getThreadName());
-
- final String name2 = "OTHER-THREADNAME2";
- Thread.currentThread().setName(name2);
- assertEquals(original, ThreadNameCachingStrategy.CACHED.getThreadName());
- }
-}
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncThreadContextTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncThreadContextTest.java
index 8a86a4628f..af93e2615e 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncThreadContextTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncThreadContextTest.java
@@ -37,7 +37,6 @@ import org.apache.logging.log4j.core.selector.ContextSelector;
import org.apache.logging.log4j.core.test.CoreLoggerContexts;
import org.apache.logging.log4j.core.util.NetUtils;
import org.apache.logging.log4j.plugins.di.DI;
-import org.apache.logging.log4j.spi.DefaultThreadContextMap;
import org.apache.logging.log4j.spi.LoggingSystemProperty;
import org.apache.logging.log4j.spi.ReadOnlyThreadContextMap;
import org.apache.logging.log4j.test.TestProperties;
@@ -98,7 +97,6 @@ public class AsyncThreadContextTest {
public String implClassSimpleName() {
switch (this) {
case WEBAPP:
- return DefaultThreadContextMap.class.getSimpleName();
case GARBAGE_FREE:
return "GarbageFreeSortedArrayThreadContextMap";
case COPY_ON_WRITE:
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 6b0d2e2aac..e0b722a913 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
@@ -28,7 +28,6 @@ import org.junit.jupiter.api.Test;
/**
* Tests queue full scenarios with AsyncLoggers in configuration.
*/
-@SetTestProperty(key = "ThreadLocals.enable", value = "true")
@SetTestProperty(key = "Web.isWebApp", value = "false")
@SetTestProperty(key = "AsyncLoggerConfig.ringBufferSize", value = "128")
public class QueueFullAsyncLoggerConfigLoggingFromToStringTest extends QueueFullAbstractTest {
@@ -45,6 +44,5 @@ public class QueueFullAsyncLoggerConfigLoggingFromToStringTest extends QueueFull
protected void checkConfig(final LoggerContext ctx) throws ReflectiveOperationException {
assertAsyncLoggerConfig(ctx, 128);
assertThat(Constants.isWebApp()).isFalse();
- assertThat(Constants.isThreadLocalsEnabled()).isTrue();
}
}
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjectorTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjectorTest.java
index 16953436b7..5bb6691169 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjectorTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjectorTest.java
@@ -35,7 +35,6 @@ import java.util.concurrent.ExecutionException;
import java.util.function.Function;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.ContextDataInjector;
-import org.apache.logging.log4j.spi.DefaultThreadContextMap;
import org.apache.logging.log4j.spi.LoggingSystem;
import org.apache.logging.log4j.spi.ReadOnlyThreadContextMap;
import org.apache.logging.log4j.spi.ThreadContextMap;
@@ -68,8 +67,7 @@ public class ThreadContextDataInjectorTest {
{
(Function<Boolean, ThreadContextMap>) ThreadContextDataInjectorTest::createGarbageFreeMap,
GARBAGE_FREE_MAP_CLASS_NAME
- },
- {(Function<Boolean, ThreadContextMap>) ThreadContextDataInjectorTest::createDefaultMap, null}
+ }
};
}
@@ -169,11 +167,4 @@ public class ThreadContextDataInjectorTest {
return assertDoesNotThrow(
() -> constructor.newInstance(inheritable, LoggingSystem.THREAD_CONTEXT_DEFAULT_INITIAL_CAPACITY));
}
-
- private static ThreadContextMap createDefaultMap(final boolean inheritable) {
- final Constructor<DefaultThreadContextMap> constructor = assertDoesNotThrow(
- () -> DefaultThreadContextMap.class.getDeclaredConstructor(Boolean.TYPE, Boolean.TYPE));
- assertTrue(constructor.trySetAccessible(), "Unable to construct DefaultThreadContextMap");
- return assertDoesNotThrow(() -> constructor.newInstance(true, inheritable));
- }
}
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/DatePatternConverterTestBase.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/DatePatternConverterTest.java
similarity index 85%
rename from log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/DatePatternConverterTestBase.java
rename to log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/DatePatternConverterTest.java
index d84599d4dd..d908f8013f 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/DatePatternConverterTestBase.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/DatePatternConverterTest.java
@@ -25,15 +25,15 @@ import java.util.Date;
import java.util.TimeZone;
import org.apache.logging.log4j.core.AbstractLogEvent;
import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.NullConfiguration;
import org.apache.logging.log4j.core.time.Instant;
import org.apache.logging.log4j.core.time.MutableInstant;
import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat;
import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat.FixedTimeZoneFormat;
-import org.apache.logging.log4j.util.Constants;
import org.apache.logging.log4j.util.Strings;
import org.junit.jupiter.api.Test;
-abstract class DatePatternConverterTestBase {
+class DatePatternConverterTest {
private static final class MyLogEvent extends AbstractLogEvent {
@@ -77,12 +77,6 @@ abstract class DatePatternConverterTestBase {
private static final String[] ISO8601_FORMAT_OPTIONS = {ISO8601};
- private final boolean threadLocalsEnabled;
-
- DatePatternConverterTestBase(final boolean threadLocalsEnabled) {
- this.threadLocalsEnabled = threadLocalsEnabled;
- }
-
private static Date date(final int year, final int month, final int date) {
final Calendar cal = Calendar.getInstance();
cal.set(year, month, date, 14, 15, 16);
@@ -98,11 +92,6 @@ abstract class DatePatternConverterTestBase {
return seconds + "nnnnnnnnn".substring(0, precision) + remainder;
}
- @Test
- void testThreadLocalsConstant() {
- assertEquals(threadLocalsEnabled, Constants.isThreadLocalsEnabled());
- }
-
@Test
public void testFormatDateStringBuilderDefaultPattern() {
assertDatePattern(null, date(2001, 1, 1), "2001-02-01 14:15:16,123");
@@ -110,7 +99,7 @@ abstract class DatePatternConverterTestBase {
@Test
public void testFormatDateStringBuilderIso8601() {
- final DatePatternConverter converter = DatePatternConverter.newInstance(ISO8601_FORMAT_OPTIONS);
+ final DatePatternConverter converter = createConverter(ISO8601_FORMAT_OPTIONS);
final StringBuilder sb = new StringBuilder();
converter.format(date(2001, 1, 1), sb);
@@ -133,7 +122,7 @@ abstract class DatePatternConverterTestBase {
@Test
public void testFormatDateStringBuilderIso8601WithPeriodMicroseconds() {
final String[] pattern = {FixedDateFormat.FixedFormat.ISO8601_PERIOD_MICROS.name(), "Z"};
- final DatePatternConverter converter = DatePatternConverter.newInstance(pattern);
+ final DatePatternConverter converter = createConverter(pattern);
final StringBuilder sb = new StringBuilder();
final MutableInstant instant = new MutableInstant();
instant.initFromEpochMilli(
@@ -154,7 +143,7 @@ abstract class DatePatternConverterTestBase {
@Test
public void testFormatLogEventStringBuilderDefaultPattern() {
final LogEvent event = new MyLogEvent();
- final DatePatternConverter converter = DatePatternConverter.newInstance(null);
+ final DatePatternConverter converter = createConverter(null);
final StringBuilder sb = new StringBuilder();
converter.format(event, sb);
@@ -165,7 +154,7 @@ abstract class DatePatternConverterTestBase {
@Test
public void testFormatLogEventStringBuilderIso8601() {
final LogEvent event = new MyLogEvent();
- final DatePatternConverter converter = DatePatternConverter.newInstance(ISO8601_FORMAT_OPTIONS);
+ final DatePatternConverter converter = createConverter(ISO8601_FORMAT_OPTIONS);
final StringBuilder sb = new StringBuilder();
converter.format(event, sb);
@@ -185,7 +174,7 @@ abstract class DatePatternConverterTestBase {
}
private static void assertDatePattern(final String format, final Date date, final String expected) {
- final DatePatternConverter converter = DatePatternConverter.newInstance(new String[] {format});
+ final DatePatternConverter converter = createConverter(new String[] {format});
final StringBuilder sb = new StringBuilder();
converter.format(date, sb);
@@ -196,7 +185,7 @@ abstract class DatePatternConverterTestBase {
public void testFormatLogEventStringBuilderIso8601TimezoneJST() {
final LogEvent event = new MyLogEvent();
final String[] optionsWithTimezone = {ISO8601, "JST"};
- final DatePatternConverter converter = DatePatternConverter.newInstance(optionsWithTimezone);
+ final DatePatternConverter converter = createConverter(optionsWithTimezone);
final StringBuilder sb = new StringBuilder();
converter.format(event, sb);
@@ -214,7 +203,7 @@ abstract class DatePatternConverterTestBase {
public void testFormatLogEventStringBuilderIso8601TimezoneOffsetHHCMM() {
final LogEvent event = new MyLogEvent();
final String[] optionsWithTimezone = {ISO8601_OFFSET_DATE_TIME_HHCMM};
- final DatePatternConverter converter = DatePatternConverter.newInstance(optionsWithTimezone);
+ final DatePatternConverter converter = createConverter(optionsWithTimezone);
final StringBuilder sb = new StringBuilder();
converter.format(event, sb);
@@ -228,7 +217,7 @@ abstract class DatePatternConverterTestBase {
public void testFormatLogEventStringBuilderIso8601TimezoneOffsetHHMM() {
final LogEvent event = new MyLogEvent();
final String[] optionsWithTimezone = {ISO8601_OFFSE_DATE_TIME_HHMM};
- final DatePatternConverter converter = DatePatternConverter.newInstance(optionsWithTimezone);
+ final DatePatternConverter converter = createConverter(optionsWithTimezone);
final StringBuilder sb = new StringBuilder();
converter.format(event, sb);
@@ -241,7 +230,7 @@ abstract class DatePatternConverterTestBase {
@Test
public void testFormatLogEventStringBuilderIso8601TimezoneUTC() {
final LogEvent event = new MyLogEvent();
- final DatePatternConverter converter = DatePatternConverter.newInstance(new String[] {"ISO8601", "UTC"});
+ final DatePatternConverter converter = createConverter(new String[] {"ISO8601", "UTC"});
final StringBuilder sb = new StringBuilder();
converter.format(event, sb);
@@ -258,7 +247,7 @@ abstract class DatePatternConverterTestBase {
public void testFormatLogEventStringBuilderIso8601TimezoneZ() {
final LogEvent event = new MyLogEvent();
final String[] optionsWithTimezone = {ISO8601, "Z"};
- final DatePatternConverter converter = DatePatternConverter.newInstance(optionsWithTimezone);
+ final DatePatternConverter converter = createConverter(optionsWithTimezone);
final StringBuilder sb = new StringBuilder();
converter.format(event, sb);
@@ -273,7 +262,7 @@ abstract class DatePatternConverterTestBase {
@Test
public void testFormatObjectStringBuilderDefaultPattern() {
- final DatePatternConverter converter = DatePatternConverter.newInstance(null);
+ final DatePatternConverter converter = createConverter(null);
final StringBuilder sb = new StringBuilder();
converter.format("nondate", sb);
@@ -283,7 +272,7 @@ abstract class DatePatternConverterTestBase {
@Test
public void testFormatStringBuilderObjectArrayDefaultPattern() {
- final DatePatternConverter converter = DatePatternConverter.newInstance(null);
+ final DatePatternConverter converter = createConverter(null);
final StringBuilder sb = new StringBuilder();
converter.format(sb, date(2001, 1, 1), date(2002, 2, 2), date(2003, 3, 3));
@@ -293,7 +282,7 @@ abstract class DatePatternConverterTestBase {
@Test
public void testFormatStringBuilderObjectArrayIso8601() {
- final DatePatternConverter converter = DatePatternConverter.newInstance(ISO8601_FORMAT_OPTIONS);
+ final DatePatternConverter converter = createConverter(ISO8601_FORMAT_OPTIONS);
final StringBuilder sb = new StringBuilder();
converter.format(sb, date(2001, 1, 1), date(2002, 2, 2), date(2003, 3, 3));
@@ -303,43 +292,40 @@ abstract class DatePatternConverterTestBase {
@Test
public void testGetPatternReturnsDefaultForEmptyOptionsArray() {
- assertEquals(
- DEFAULT_PATTERN, DatePatternConverter.newInstance(new String[0]).getPattern());
+ assertEquals(DEFAULT_PATTERN, createConverter(new String[0]).getPattern());
}
@Test
public void testGetPatternReturnsDefaultForInvalidPattern() {
final String[] invalid = {"ABC I am not a valid date pattern"};
- assertEquals(DEFAULT_PATTERN, DatePatternConverter.newInstance(invalid).getPattern());
+ assertEquals(DEFAULT_PATTERN, createConverter(invalid).getPattern());
}
@Test
public void testGetPatternReturnsDefaultForNullOptions() {
- assertEquals(DEFAULT_PATTERN, DatePatternConverter.newInstance(null).getPattern());
+ assertEquals(DEFAULT_PATTERN, createConverter(null).getPattern());
}
@Test
public void testGetPatternReturnsDefaultForSingleNullElementOptionsArray() {
- assertEquals(
- DEFAULT_PATTERN, DatePatternConverter.newInstance(new String[1]).getPattern());
+ assertEquals(DEFAULT_PATTERN, createConverter(new String[1]).getPattern());
}
@Test
public void testGetPatternReturnsDefaultForTwoNullElementsOptionsArray() {
- assertEquals(
- DEFAULT_PATTERN, DatePatternConverter.newInstance(new String[2]).getPattern());
+ assertEquals(DEFAULT_PATTERN, createConverter(new String[2]).getPattern());
}
@Test
public void testGetPatternReturnsNullForUnix() {
final String[] options = {"UNIX"};
- assertNull(DatePatternConverter.newInstance(options).getPattern());
+ assertNull(createConverter(options).getPattern());
}
@Test
public void testGetPatternReturnsNullForUnixMillis() {
final String[] options = {"UNIX_MILLIS"};
- assertNull(DatePatternConverter.newInstance(options).getPattern());
+ assertNull(createConverter(options).getPattern());
}
@Test
@@ -364,17 +350,17 @@ abstract class DatePatternConverterTestBase {
final String precisePattern;
if (foundIndex < 0) {
precisePattern = pattern;
- preciseConverter = DatePatternConverter.newInstance(new String[] {precisePattern});
+ preciseConverter = createConverter(new String[] {precisePattern});
} else {
final String subPattern = pattern.substring(0, foundIndex);
final String remainder = pattern.substring(foundIndex + search.length());
precisePattern = subPattern + "nnnnnnnnn" + "n" + remainder; // nanos too long
- preciseConverter = DatePatternConverter.newInstance(new String[] {precisePattern});
+ preciseConverter = createConverter(new String[] {precisePattern});
}
preciseConverter.format(event, preciseBuilder);
final String[] milliOptions = {pattern};
- DatePatternConverter.newInstance(milliOptions).format(event, milliBuilder);
+ createConverter(milliOptions).format(event, milliBuilder);
final FixedTimeZoneFormat timeZoneFormat = format.getTimeZoneFormat();
final int truncateLen = 3 + (timeZoneFormat != null ? timeZoneFormat.getLength() : 0);
final String tz = timeZoneFormat != null
@@ -396,7 +382,7 @@ abstract class DatePatternConverterTestBase {
@Test
public void testNewInstanceAllowsNullParameter() {
- DatePatternConverter.newInstance(null); // no errors
+ createConverter(null); // no errors
}
// test with all formats from one 'n' (100s of millis) to 'nnnnnnnnn' (nanosecond precision)
@@ -423,11 +409,11 @@ abstract class DatePatternConverterTestBase {
final String precisePattern = precisePattern(pattern, i);
final String[] preciseOptions = {precisePattern, timeZone};
- final DatePatternConverter preciseConverter = DatePatternConverter.newInstance(preciseOptions);
+ final DatePatternConverter preciseConverter = createConverter(preciseOptions);
preciseConverter.format(event, preciseBuilder);
final String[] milliOptions = {pattern, timeZone};
- DatePatternConverter.newInstance(milliOptions).format(event, milliBuilder);
+ createConverter(milliOptions).format(event, milliBuilder);
final FixedTimeZoneFormat timeZoneFormat = format.getTimeZoneFormat();
final int truncateLen = 3 + (timeZoneFormat != null ? timeZoneFormat.getLength() : 0);
final String tz = timeZoneFormat != null
@@ -452,7 +438,7 @@ abstract class DatePatternConverterTestBase {
public void testPredefinedFormatWithoutTimezone() {
for (final FixedDateFormat.FixedFormat format : FixedDateFormat.FixedFormat.values()) {
final String[] options = {format.name()};
- final DatePatternConverter converter = DatePatternConverter.newInstance(options);
+ final DatePatternConverter converter = createConverter(options);
assertEquals(format.getPattern(), converter.getPattern());
}
}
@@ -461,8 +447,12 @@ abstract class DatePatternConverterTestBase {
public void testPredefinedFormatWithTimezone() {
for (final FixedDateFormat.FixedFormat format : FixedDateFormat.FixedFormat.values()) {
final String[] options = {format.name(), "PST"}; // Pacific Standard Time=UTC-8:00
- final DatePatternConverter converter = DatePatternConverter.newInstance(options);
+ final DatePatternConverter converter = createConverter(options);
assertEquals(format.getPattern(), converter.getPattern());
}
}
+
+ private static DatePatternConverter createConverter(final String[] options) {
+ return DatePatternConverter.newInstance(new NullConfiguration(), options);
+ }
}
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/DatePatternConverterWithThreadLocalsTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/DatePatternConverterWithThreadLocalsTest.java
deleted file mode 100644
index e632d2785d..0000000000
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/DatePatternConverterWithThreadLocalsTest.java
+++ /dev/null
@@ -1,31 +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.pattern;
-
-import org.apache.logging.log4j.spi.LoggingSystemProperty;
-import org.apache.logging.log4j.test.junit.SetTestProperty;
-import org.apache.logging.log4j.test.junit.UsingTestProperties;
-
-@SetTestProperty(key = LoggingSystemProperty.Constant.WEB_IS_WEBAPP, value = "false")
-@SetTestProperty(key = LoggingSystemProperty.Constant.THREAD_LOCALS_ENABLE, value = "true")
-@UsingTestProperties
-class DatePatternConverterWithThreadLocalsTest extends DatePatternConverterTestBase {
-
- DatePatternConverterWithThreadLocalsTest() {
- super(true);
- }
-}
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/DatePatternConverterWithoutThreadLocalsTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/DatePatternConverterWithoutThreadLocalsTest.java
deleted file mode 100644
index d4d667a523..0000000000
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/DatePatternConverterWithoutThreadLocalsTest.java
+++ /dev/null
@@ -1,28 +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.pattern;
-
-import org.apache.logging.log4j.spi.LoggingSystemProperty;
-import org.junitpioneer.jupiter.SetSystemProperty;
-
-@SetSystemProperty(key = LoggingSystemProperty.Constant.THREAD_LOCALS_ENABLE, value = "false")
-class DatePatternConverterWithoutThreadLocalsTest extends DatePatternConverterTestBase {
-
- DatePatternConverterWithoutThreadLocalsTest() {
- super(false);
- }
-}
diff --git a/log4j-core-test/src/test/resources/perf/SimplePerfTest.sh b/log4j-core-test/src/test/resources/perf/SimplePerfTest.sh
index e7cbcf2c02..ec877a0829 100644
--- a/log4j-core-test/src/test/resources/perf/SimplePerfTest.sh
+++ b/log4j-core-test/src/test/resources/perf/SimplePerfTest.sh
@@ -37,7 +37,6 @@ GC_OPTIONS=
LOG4J_OPTIONS="-Dlog4j.configurationFile=perf-CountingNoOpAppender.xml"
LOG4J_OPTIONS="${LOG4J_OPTIONS} -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"
-LOG4J_OPTIONS="${LOG4J_OPTIONS} -Dlog4j2.enable.threadlocals=true"
LOG4J_OPTIONS="${LOG4J_OPTIONS} -DAsyncLogger.WaitStrategy=Block"
LOG4J_OPTIONS="${LOG4J_OPTIONS} -Dlog4j.format.msg.async=true"
export LOG4J_OPTIONS
diff --git a/log4j-core-test/src/test/resources/perf/runResponseTm.sh b/log4j-core-test/src/test/resources/perf/runResponseTm.sh
index a043a30a51..2860dcd9be 100644
--- a/log4j-core-test/src/test/resources/perf/runResponseTm.sh
+++ b/log4j-core-test/src/test/resources/perf/runResponseTm.sh
@@ -40,7 +40,6 @@ LOG4J_OPTIONS="-Dlog4j.configurationFile=perf5AsyncApndNoLoc.xml"
#LOG4J_OPTIONS="-Dlogback.configurationFile=perf-logback.xml"
#LOG4J_OPTIONS="${LOG4J_OPTIONS} -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"
-LOG4J_OPTIONS="${LOG4J_OPTIONS} -Dlog4j2.enable.threadlocals=true"
LOG4J_OPTIONS="${LOG4J_OPTIONS} -Dlog4j2.enable.direct.encoders=true"
LOG4J_OPTIONS="${LOG4J_OPTIONS} -DAsyncLogger.WaitStrategy=busySpin"
LOG4J_OPTIONS="${LOG4J_OPTIONS} -DAsyncLoggerConfig.WaitStrategy=busySpin"
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
index 27202729ab..316551eca7 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
@@ -330,8 +330,9 @@ public class DefaultRolloverStrategy extends AbstractRolloverStrategy {
this.compressionLevel = compressionLevel;
this.stopCustomActionsOnError = stopCustomActionsOnError;
this.customActions = customActions == null ? Collections.<Action>emptyList() : Arrays.asList(customActions);
- this.tempCompressedFilePattern =
- tempCompressedFilePatternString != null ? new PatternProcessor(tempCompressedFilePatternString) : null;
+ this.tempCompressedFilePattern = tempCompressedFilePatternString != null
+ ? new PatternProcessor(configuration, tempCompressedFilePatternString)
+ : null;
}
public int getCompressionLevel() {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DirectWriteRolloverStrategy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DirectWriteRolloverStrategy.java
index 1d286a61c5..b95c802dcd 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DirectWriteRolloverStrategy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DirectWriteRolloverStrategy.java
@@ -101,7 +101,8 @@ public class DirectWriteRolloverStrategy extends AbstractRolloverStrategy implem
config.getStrSubstitutor(),
customActions,
stopCustomActionsOnError,
- tempCompressedFilePattern);
+ tempCompressedFilePattern,
+ config);
}
public String getMaxFiles() {
@@ -227,14 +228,16 @@ public class DirectWriteRolloverStrategy extends AbstractRolloverStrategy implem
final StrSubstitutor strSubstitutor,
final Action[] customActions,
final boolean stopCustomActionsOnError,
- final String tempCompressedFilePatternString) {
+ final String tempCompressedFilePatternString,
+ final Configuration configuration) {
super(strSubstitutor);
this.maxFiles = maxFiles;
this.compressionLevel = compressionLevel;
this.stopCustomActionsOnError = stopCustomActionsOnError;
this.customActions = customActions == null ? Collections.<Action>emptyList() : Arrays.asList(customActions);
- this.tempCompressedFilePattern =
- tempCompressedFilePatternString != null ? new PatternProcessor(tempCompressedFilePatternString) : null;
+ this.tempCompressedFilePattern = tempCompressedFilePatternString != null
+ ? new PatternProcessor(configuration, tempCompressedFilePatternString)
+ : null;
}
public int getCompressionLevel() {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
index a31d8e73cc..05dd3175c1 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
@@ -23,6 +23,7 @@ import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.lookup.StrSubstitutor;
import org.apache.logging.log4j.core.pattern.ArrayPatternConverter;
import org.apache.logging.log4j.core.pattern.DatePatternConverter;
@@ -77,9 +78,9 @@ public class PatternProcessor {
* Constructor.
* @param pattern The file pattern.
*/
- public PatternProcessor(final String pattern) {
+ public PatternProcessor(final Configuration configuration, final String pattern) {
this.pattern = pattern;
- final PatternParser parser = new PatternParser(null, KEY, ArrayPatternConverter.class);
+ final PatternParser parser = new PatternParser(configuration, KEY, ArrayPatternConverter.class);
final List<PatternConverter> converters = new ArrayList<>();
final List<FormattingInfo> fields = new ArrayList<>();
parser.parse(pattern, converters, fields, false, false, false);
@@ -108,8 +109,8 @@ public class PatternProcessor {
* @param pattern The file pattern.
* @param copy Source pattern processor
*/
- public PatternProcessor(final String pattern, final PatternProcessor copy) {
- this(pattern);
+ public PatternProcessor(final Configuration configuration, final String pattern, final PatternProcessor copy) {
+ this(configuration, pattern);
this.prevFileTime = copy.prevFileTime;
this.nextFileTime = copy.nextFileTime;
this.currentFileTime = copy.currentFileTime;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
index 28d38eefc0..c613fcf5b3 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
@@ -92,6 +92,7 @@ public class RollingFileManager extends FileManager {
* @since 2.9
*/
protected RollingFileManager(
+ final Configuration configuration,
final LoggerContext loggerContext,
final String fileName,
final String pattern,
@@ -127,7 +128,7 @@ public class RollingFileManager extends FileManager {
this.initialTime = initialTime;
this.triggeringPolicy = triggeringPolicy;
this.rolloverStrategy = rolloverStrategy;
- this.patternProcessor = new PatternProcessor(pattern);
+ this.patternProcessor = new PatternProcessor(configuration, pattern);
this.patternProcessor.setPrevFileTime(initialTime);
this.fileName = fileName;
this.directWrite = rolloverStrategy instanceof DirectFileRolloverStrategy;
@@ -744,7 +745,8 @@ public class RollingFileManager extends FileManager {
public void updateData(final Object data) {
final FactoryData factoryData = (FactoryData) data;
setRolloverStrategy(factoryData.getRolloverStrategy());
- setPatternProcessor(new PatternProcessor(factoryData.getPattern(), getPatternProcessor()));
+ setPatternProcessor(
+ new PatternProcessor(factoryData.getConfiguration(), factoryData.getPattern(), getPatternProcessor()));
setTriggeringPolicy(factoryData.getTriggeringPolicy());
}
@@ -791,6 +793,7 @@ public class RollingFileManager extends FileManager {
final boolean writeHeader = file != null && file.exists() && file.length() == 0;
final RollingFileManager rm = new RollingFileManager(
+ data.getConfiguration(),
data.getLoggerContext(),
data.fileName,
data.pattern,
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
index 61fff7da04..05a56cc99a 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
@@ -49,6 +49,7 @@ public class RollingRandomAccessFileManager extends RollingFileManager {
* @since 2.8.3
*/
public RollingRandomAccessFileManager(
+ final Configuration configuration,
final LoggerContext loggerContext,
final RandomAccessFile raf,
final String fileName,
@@ -68,6 +69,7 @@ public class RollingRandomAccessFileManager extends RollingFileManager {
final String fileGroup,
final boolean writeHeader) {
super(
+ configuration,
loggerContext,
fileName,
pattern,
@@ -296,6 +298,7 @@ public class RollingRandomAccessFileManager extends RollingFileManager {
final boolean writeHeader = !data.append || file == null || !file.exists();
final RollingRandomAccessFileManager rrm = new RollingRandomAccessFileManager(
+ data.getConfiguration(),
data.getLoggerContext(),
raf,
name,
@@ -407,7 +410,8 @@ public class RollingRandomAccessFileManager extends RollingFileManager {
public void updateData(final Object data) {
final FactoryData factoryData = (FactoryData) data;
setRolloverStrategy(factoryData.getRolloverStrategy());
- setPatternProcessor(new PatternProcessor(factoryData.getPattern(), getPatternProcessor()));
+ setPatternProcessor(
+ new PatternProcessor(factoryData.getConfiguration(), factoryData.getPattern(), getPatternProcessor()));
setTriggeringPolicy(factoryData.getTriggeringPolicy());
}
}
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 76eb979e29..4aef03e08b 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
@@ -17,7 +17,6 @@
package org.apache.logging.log4j.core.async;
import com.lmax.disruptor.EventTranslatorVararg;
-import com.lmax.disruptor.dsl.Disruptor;
import java.util.List;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
@@ -35,9 +34,8 @@ 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.message.MessageFactory;
-import org.apache.logging.log4j.message.ReusableMessage;
import org.apache.logging.log4j.spi.AbstractLogger;
-import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.spi.recycler.Recycler;
import org.apache.logging.log4j.util.StackLocatorUtil;
import org.apache.logging.log4j.util.StringMap;
@@ -66,13 +64,10 @@ public class AsyncLogger extends Logger implements EventTranslatorVararg<RingBuf
// this is within the MaxInlineSize threshold and makes these methods candidates for
// immediate inlining instead of waiting until they are designated "hot enough".
- private static final StatusLogger LOGGER = StatusLogger.getLogger();
private final Clock clock; // not reconfigurable
private final ContextDataInjector contextDataInjector; // not reconfigurable
- private static final ThreadNameCachingStrategy THREAD_NAME_CACHING_STRATEGY = ThreadNameCachingStrategy.create();
-
- private final ThreadLocal<RingBufferLogEventTranslator> threadLocalTranslator = new ThreadLocal<>();
+ private final Recycler<RingBufferLogEventTranslator> translatorRecycler;
private final AsyncLoggerDisruptor loggerDisruptor;
private volatile boolean includeLocation; // reconfigurable
@@ -92,9 +87,12 @@ public class AsyncLogger extends Logger implements EventTranslatorVararg<RingBuf
final MessageFactory messageFactory,
final AsyncLoggerDisruptor loggerDisruptor) {
super(context, name, messageFactory);
+ final Configuration configuration = context.getConfiguration();
+ this.translatorRecycler = configuration
+ .getRecyclerFactory()
+ .create(RingBufferLogEventTranslator::new, RingBufferLogEventTranslator::clear);
this.loggerDisruptor = loggerDisruptor;
includeLocation = privateConfig.loggerConfig.isIncludeLocation();
- final Configuration configuration = context.getConfiguration();
nanoClock = configuration.getNanoClock();
clock = configuration.getComponent(Clock.KEY);
contextDataInjector = configuration.getComponent(ContextDataInjector.KEY);
@@ -117,107 +115,6 @@ public class AsyncLogger extends Logger implements EventTranslatorVararg<RingBuf
return nanoClock;
}
- private RingBufferLogEventTranslator getCachedTranslator() {
- RingBufferLogEventTranslator result = threadLocalTranslator.get();
- if (result == null) {
- result = new RingBufferLogEventTranslator();
- threadLocalTranslator.set(result);
- }
- return result;
- }
-
- @Override
- public void logMessage(
- final String fqcn, final Level level, final Marker marker, final Message message, final Throwable thrown) {
- getTranslatorType().log(fqcn, level, marker, message, thrown);
- }
-
- @Override
- public void log(
- final Level level,
- final Marker marker,
- final String fqcn,
- final StackTraceElement location,
- final Message message,
- final Throwable throwable) {
- getTranslatorType().log(fqcn, location, level, marker, message, throwable);
- }
-
- abstract class TranslatorType {
-
- abstract void log(
- final String fqcn,
- final StackTraceElement location,
- final Level level,
- final Marker marker,
- final Message message,
- final Throwable thrown);
-
- abstract void log(
- final String fqcn,
- final Level level,
- final Marker marker,
- final Message message,
- final Throwable thrown);
- }
-
- private final TranslatorType threadLocalTranslatorType = new TranslatorType() {
-
- @Override
- void log(
- final String fqcn,
- final StackTraceElement location,
- final Level level,
- final Marker marker,
- final Message message,
- final Throwable thrown) {
- logWithThreadLocalTranslator(fqcn, location, level, marker, message, thrown);
- }
-
- @Override
- void log(
- final String fqcn,
- final Level level,
- final Marker marker,
- final Message message,
- final Throwable thrown) {
- logWithThreadLocalTranslator(fqcn, level, marker, message, thrown);
- }
- };
-
- private final TranslatorType varargTranslatorType = new TranslatorType() {
-
- @Override
- void log(
- final String fqcn,
- final StackTraceElement location,
- final Level level,
- final Marker marker,
- final Message message,
- final Throwable thrown) {
- logWithVarargTranslator(fqcn, location, level, marker, message, thrown);
- }
-
- @Override
- void log(
- final String fqcn,
- final Level level,
- final Marker marker,
- final Message message,
- final Throwable thrown) {
- // LOG4J2-1172: avoid storing non-JDK classes in ThreadLocals to avoid memory leaks in web apps
- logWithVarargTranslator(fqcn, level, marker, message, thrown);
- }
- };
-
- private TranslatorType getTranslatorType() {
- return loggerDisruptor.isUseThreadLocals() ? threadLocalTranslatorType : varargTranslatorType;
- }
-
- private boolean isReused(final Message message) {
- return message instanceof ReusableMessage;
- }
-
/**
* Enqueues the specified log event data for logging in a background thread.
* <p>
@@ -230,14 +127,19 @@ public class AsyncLogger extends Logger implements EventTranslatorVararg<RingBuf
* @param message the log message
* @param thrown a {@code Throwable} or {@code null}
*/
- private void logWithThreadLocalTranslator(
+ @Override
+ public void logMessage(
final String fqcn, final Level level, final Marker marker, final Message message, final Throwable thrown) {
// Implementation note: this method is tuned for performance. MODIFY WITH CARE!
- final RingBufferLogEventTranslator translator = getCachedTranslator();
- initTranslator(translator, fqcn, level, marker, message, thrown);
- initTranslatorThreadValues(translator);
- publish(translator);
+ final RingBufferLogEventTranslator translator = translatorRecycler.acquire();
+ try {
+ initTranslator(translator, fqcn, level, marker, message, thrown);
+ translator.updateThreadValues();
+ publish(translator);
+ } finally {
+ translatorRecycler.release(translator);
+ }
}
/**
@@ -253,23 +155,23 @@ public class AsyncLogger extends Logger implements EventTranslatorVararg<RingBuf
* @param message the log message
* @param thrown a {@code Throwable} or {@code null}
*/
- private void logWithThreadLocalTranslator(
- final String fqcn,
- final StackTraceElement location,
+ @Override
+ public void log(
final Level level,
final Marker marker,
+ final String fqcn,
+ final StackTraceElement location,
final Message message,
final Throwable thrown) {
// Implementation note: this method is tuned for performance. MODIFY WITH CARE!
- final RingBufferLogEventTranslator translator = getCachedTranslator();
- initTranslator(translator, fqcn, location, level, marker, message, thrown);
- initTranslatorThreadValues(translator);
+ final RingBufferLogEventTranslator translator = translatorRecycler.acquire();
try {
+ initTranslator(translator, fqcn, location, level, marker, message, thrown);
+ translator.updateThreadValues();
publish(translator);
- } catch (Throwable ex) {
- translator.clear();
- throw ex;
+ } finally {
+ translatorRecycler.release(translator);
}
}
@@ -361,13 +263,6 @@ public class AsyncLogger extends Logger implements EventTranslatorVararg<RingBuf
contextDataInjector);
}
- private void initTranslatorThreadValues(final RingBufferLogEventTranslator translator) {
- // constant check should be optimized out when using default (CACHED)
- if (THREAD_NAME_CACHING_STRATEGY == ThreadNameCachingStrategy.UNCACHED) {
- translator.updateThreadValues();
- }
- }
-
/**
* Returns the caller location if requested, {@code null} otherwise.
*
@@ -381,94 +276,6 @@ public class AsyncLogger extends Logger implements EventTranslatorVararg<RingBuf
return includeLocation ? StackLocatorUtil.calcLocation(fqcn) : null;
}
- /**
- * Enqueues the specified log event data for logging in a background thread.
- * <p>
- * This creates a new varargs Object array for each invocation, but does not store any non-JDK classes in a
- * {@code ThreadLocal} to avoid memory leaks in web applications (see LOG4J2-1172).
- *
- * @param fqcn fully qualified name of the caller
- * @param level level at which the caller wants to log the message
- * @param marker message marker
- * @param message the log message
- * @param thrown a {@code Throwable} or {@code null}
- */
- private void logWithVarargTranslator(
- final String fqcn, final Level level, final Marker marker, final Message message, final Throwable thrown) {
- // Implementation note: candidate for optimization: exceeds 35 bytecodes.
-
- final Disruptor<RingBufferLogEvent> disruptor = loggerDisruptor.getDisruptor();
- if (disruptor == null) {
- LOGGER.error("Ignoring log event after Log4j has been shut down.");
- return;
- }
- // if the Message instance is reused, there is no point in freezing its message here
- if (!isReused(message)) {
- InternalAsyncUtil.makeMessageImmutable(message);
- }
- StackTraceElement location = null;
- // calls the translateTo method on this AsyncLogger
- if (!disruptor
- .getRingBuffer()
- .tryPublishEvent(
- this,
- this, // asyncLogger: 0
- (location = calcLocationIfRequested(fqcn)), // location: 1
- fqcn, // 2
- level, // 3
- marker, // 4
- message, // 5
- thrown)) { // 6
- handleRingBufferFull(location, fqcn, level, marker, message, thrown);
- }
- }
-
- /**
- * Enqueues the specified log event data for logging in a background thread.
- * <p>
- * This creates a new varargs Object array for each invocation, but does not store any non-JDK classes in a
- * {@code ThreadLocal} to avoid memory leaks in web applications (see LOG4J2-1172).
- *
- * @param fqcn fully qualified name of the caller
- * @param location location of the caller.
- * @param level level at which the caller wants to log the message
- * @param marker message marker
- * @param message the log message
- * @param thrown a {@code Throwable} or {@code null}
- */
- private void logWithVarargTranslator(
- final String fqcn,
- final StackTraceElement location,
- final Level level,
- final Marker marker,
- final Message message,
- final Throwable thrown) {
- // Implementation note: candidate for optimization: exceeds 35 bytecodes.
-
- final Disruptor<RingBufferLogEvent> disruptor = loggerDisruptor.getDisruptor();
- if (disruptor == null) {
- LOGGER.error("Ignoring log event after Log4j has been shut down.");
- return;
- }
- // if the Message instance is reused, there is no point in freezing its message here
- if (!isReused(message)) {
- InternalAsyncUtil.makeMessageImmutable(message);
- }
- // calls the translateTo method on this AsyncLogger
- if (!disruptor
- .getRingBuffer()
- .tryPublishEvent(
- this, this, // asyncLogger: 0
- location, // location: 1
- fqcn, // 2
- level, // 3
- marker, // 4
- message, // 5
- thrown)) { // 6
- handleRingBufferFull(location, fqcn, level, marker, message, thrown);
- }
- }
-
/*
* (non-Javadoc)
*
@@ -489,7 +296,6 @@ public class AsyncLogger extends Logger implements EventTranslatorVararg<RingBuf
final ContextStack contextStack = ThreadContext.getImmutableStack();
final Thread currentThread = Thread.currentThread();
- final String threadName = THREAD_NAME_CACHING_STRATEGY.getThreadName();
event.setValues(
asyncLogger,
asyncLogger.getName(),
@@ -503,7 +309,7 @@ public class AsyncLogger extends Logger implements EventTranslatorVararg<RingBuf
contextDataInjector.injectContextData(null, (StringMap) event.getContextData()),
contextStack,
currentThread.getId(),
- threadName,
+ currentThread.getName(),
currentThread.getPriority(),
location,
clock,
@@ -527,41 +333,6 @@ public class AsyncLogger extends Logger implements EventTranslatorVararg<RingBuf
strategy.log(this, getName(), fqcn, marker, level, message, thrown);
}
- private void handleRingBufferFull(
- final StackTraceElement location,
- final String fqcn,
- final Level level,
- final Marker marker,
- final Message msg,
- final Throwable thrown) {
- if (AbstractLogger.getRecursionDepth() > 1) { // LOG4J2-1518, LOG4J2-2031
- // If queue is full AND we are in a recursive call, call appender directly to prevent deadlock
- AsyncQueueFullMessageUtil.logWarningToStatusLogger();
- logMessageInCurrentThread(fqcn, level, marker, msg, thrown);
- return;
- }
- final EventRoute eventRoute = loggerDisruptor.getEventRoute(level);
- switch (eventRoute) {
- case ENQUEUE:
- loggerDisruptor.enqueueLogMessageWhenQueueFull(
- this, this, // asyncLogger: 0
- location, // location: 1
- fqcn, // 2
- level, // 3
- marker, // 4
- msg, // 5
- thrown); // 6
- break;
- case SYNCHRONOUS:
- logMessageInCurrentThread(fqcn, level, marker, msg, thrown);
- break;
- case DISCARD:
- break;
- default:
- throw new IllegalStateException("Unknown EventRoute " + eventRoute);
- }
- }
-
/**
* This method is called by the EventHandler that processes the RingBufferLogEvent in a separate thread.
* Merges the contents of the configuration map into the contextData, after replacing any variables in the property
@@ -597,7 +368,7 @@ public class AsyncLogger extends Logger implements EventTranslatorVararg<RingBuf
}
private static StringMap getContextData(final RingBufferLogEvent event) {
- final StringMap contextData = (StringMap) event.getContextData();
+ final StringMap contextData = event.getContextData();
if (contextData.isFrozen()) {
final StringMap temp = ContextDataFactory.createContextData();
temp.putAll(contextData);
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerContext.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerContext.java
index f9c964d312..9f6389081d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerContext.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerContext.java
@@ -140,12 +140,4 @@ public class AsyncLoggerContext extends LoggerContext {
public RingBufferAdmin createRingBufferAdmin() {
return loggerDisruptor.createRingBufferAdmin(getName());
}
-
- /**
- * Signals this context whether it is allowed to use ThreadLocal objects for efficiency.
- * @param useThreadLocals whether this context is allowed to use ThreadLocal objects
- */
- public void setUseThreadLocals(final boolean useThreadLocals) {
- loggerDisruptor.setUseThreadLocals(useThreadLocals);
- }
}
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 c739918fc7..fb47790187 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,7 +16,6 @@
*/
package org.apache.logging.log4j.core.async;
-import com.lmax.disruptor.EventTranslatorVararg;
import com.lmax.disruptor.ExceptionHandler;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.TimeoutException;
@@ -30,7 +29,6 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Supplier;
import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.core.AbstractLifeCycle;
import org.apache.logging.log4j.core.impl.Log4jPropertyKey;
import org.apache.logging.log4j.core.jmx.RingBufferAdmin;
@@ -56,10 +54,8 @@ class AsyncLoggerDisruptor extends AbstractLifeCycle {
private String contextName;
private final Supplier<AsyncWaitStrategyFactory> waitStrategyFactorySupplier;
- private boolean useThreadLocalTranslator = true;
private long backgroundThreadId;
private AsyncQueueFullPolicy asyncQueueFullPolicy;
- private int ringBufferSize;
private WaitStrategy waitStrategy;
AsyncLoggerDisruptor(
@@ -107,7 +103,7 @@ class AsyncLoggerDisruptor extends AbstractLifeCycle {
}
setStarting();
LOGGER.trace("[{}] AsyncLoggerDisruptor creating new disruptor for this context.", contextName);
- ringBufferSize = DisruptorUtil.calculateRingBufferSize(Log4jPropertyKey.ASYNC_LOGGER_RING_BUFFER_SIZE);
+ 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);
@@ -141,10 +137,6 @@ class AsyncLoggerDisruptor extends AbstractLifeCycle {
errorHandler);
disruptor.start();
- LOGGER.trace(
- "[{}] AsyncLoggers use a {} translator",
- contextName,
- useThreadLocalTranslator ? "threadlocal" : "vararg");
super.start();
} finally {
startLock.unlock();
@@ -276,55 +268,6 @@ class AsyncLoggerDisruptor extends AbstractLifeCycle {
}
}
- void enqueueLogMessageWhenQueueFull(
- final EventTranslatorVararg<RingBufferLogEvent> translator,
- final AsyncLogger asyncLogger,
- final StackTraceElement location,
- final String fqcn,
- final Level level,
- final Marker marker,
- final Message msg,
- final Throwable thrown) {
- try {
- // Note: we deliberately access the volatile disruptor field afresh here.
- // Avoiding this and using an older reference 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.
- if (synchronizeEnqueueWhenQueueFull()) {
- queueFullEnqueueLock.lock();
- try {
- disruptor
- .getRingBuffer()
- .publishEvent(
- translator,
- asyncLogger, // asyncLogger: 0
- location, // location: 1
- fqcn, // 2
- level, // 3
- marker, // 4
- msg, // 5
- thrown); // 6
- } finally {
- queueFullEnqueueLock.unlock();
- }
- } else {
- disruptor
- .getRingBuffer()
- .publishEvent(
- translator,
- asyncLogger, // asyncLogger: 0
- location, // location: 1
- fqcn, // 2
- level, // 3
- marker, // 4
- msg, // 5
- thrown); // 6
- }
- } catch (final NullPointerException npe) {
- // LOG4J2-639: catch NPE if disruptor field was set to null in stop()
- logWarningOnNpeFromDisruptorPublish(level, fqcn, msg, thrown);
- }
- }
-
private boolean synchronizeEnqueueWhenQueueFull() {
return DisruptorUtil.ASYNC_LOGGER_SYNCHRONIZE_ENQUEUE_WHEN_QUEUE_FULL
// Background thread must never block
@@ -351,34 +294,4 @@ class AsyncLoggerDisruptor extends AbstractLifeCycle {
msg.getFormattedMessage(),
thrown == null ? "" : Throwables.toStringList(thrown));
}
-
- /**
- * Returns whether it is allowed to store non-JDK classes in ThreadLocal objects for efficiency.
- *
- * @return whether AsyncLoggers are allowed to use ThreadLocal objects
- * @since 2.5
- * @see <a href="https://issues.apache.org/jira/browse/LOG4J2-1172">LOG4J2-1172</a>
- */
- public boolean isUseThreadLocals() {
- return useThreadLocalTranslator;
- }
-
- /**
- * Signals this AsyncLoggerDisruptor whether it is allowed to store non-JDK classes in ThreadLocal objects for
- * efficiency.
- * <p>
- * This property may be modified after the {@link #start()} method has been called.
- * </p>
- *
- * @param allow whether AsyncLoggers are allowed to use ThreadLocal objects
- * @since 2.5
- * @see <a href="https://issues.apache.org/jira/browse/LOG4J2-1172">LOG4J2-1172</a>
- */
- public void setUseThreadLocals(final boolean allow) {
- useThreadLocalTranslator = allow;
- LOGGER.trace(
- "[{}] AsyncLoggers have been modified to use a {} translator",
- contextName,
- useThreadLocalTranslator ? "threadlocal" : "vararg");
- }
}
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 b191f9a65d..7d9444e0ef 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
@@ -18,7 +18,6 @@ package org.apache.logging.log4j.core.async;
import static org.apache.logging.log4j.core.impl.Log4jPropertyKey.ASYNC_CONFIG_EXCEPTION_HANDLER_CLASS_NAME;
import static org.apache.logging.log4j.core.impl.Log4jPropertyKey.ASYNC_LOGGER_EXCEPTION_HANDLER_CLASS_NAME;
-import static org.apache.logging.log4j.util.Constants.isThreadLocalsEnabled;
import com.lmax.disruptor.ExceptionHandler;
import com.lmax.disruptor.WaitStrategy;
@@ -38,8 +37,7 @@ import org.apache.logging.log4j.util.PropertyKey;
final class DisruptorUtil {
private static final Logger LOGGER = StatusLogger.getLogger();
private static final int RINGBUFFER_MIN_SIZE = 128;
- private static final int RINGBUFFER_DEFAULT_SIZE = 256 * 1024;
- private static final int RINGBUFFER_NO_GC_DEFAULT_SIZE = 4 * 1024;
+ private static final int RINGBUFFER_DEFAULT_SIZE = 4 * 1024;
/**
* LOG4J2-2606: Users encountered excessive CPU utilization with Disruptor v3.4.2 when the application
@@ -69,7 +67,7 @@ final class DisruptorUtil {
}
static int calculateRingBufferSize(final PropertyKey key) {
- int ringBufferSize = isThreadLocalsEnabled() ? RINGBUFFER_NO_GC_DEFAULT_SIZE : RINGBUFFER_DEFAULT_SIZE;
+ int ringBufferSize = RINGBUFFER_DEFAULT_SIZE;
final String userPreferredRBSize =
PropertiesUtil.getProperties().getStringProperty(key, String.valueOf(ringBufferSize));
try {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java
index 6a8f048d16..4b2f1c46e1 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java
@@ -16,8 +16,6 @@
*/
package org.apache.logging.log4j.core.async;
-import static org.apache.logging.log4j.util.Constants.isThreadLocalsEnabled;
-
import com.lmax.disruptor.EventFactory;
import java.util.Arrays;
import org.apache.logging.log4j.Level;
@@ -498,18 +496,10 @@ public class RingBufferLogEvent implements ReusableLogEvent, ReusableMessage, Ch
}
// ensure that excessively long char[] arrays are not kept in memory forever
- if (isThreadLocalsEnabled()) {
- StringBuilders.trimToMaxSize(messageText, Constants.MAX_REUSABLE_MESSAGE_SIZE);
+ StringBuilders.trimToMaxSize(messageText, Constants.MAX_REUSABLE_MESSAGE_SIZE);
- if (parameters != null) {
- Arrays.fill(parameters, null);
- }
- } else {
- // A user may have manually logged a ReusableMessage implementation, when thread locals are
- // disabled we remove the reference in order to avoid permanently holding references to these
- // buffers.
- messageText = null;
- parameters = null;
+ if (parameters != null) {
+ Arrays.fill(parameters, null);
}
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/ThreadNameCachingStrategy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/ThreadNameCachingStrategy.java
deleted file mode 100644
index bf4a9ed51b..0000000000
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/ThreadNameCachingStrategy.java
+++ /dev/null
@@ -1,95 +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 java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import org.apache.logging.log4j.core.impl.Log4jPropertyKey;
-import org.apache.logging.log4j.status.StatusLogger;
-import org.apache.logging.log4j.util.Constants;
-import org.apache.logging.log4j.util.PropertiesUtil;
-
-/**
- * Strategy for deciding whether thread name should be cached or not.
- */
-public enum ThreadNameCachingStrategy { // LOG4J2-467
- CACHED {
- @Override
- public String getThreadName() {
- String result = THREADLOCAL_NAME.get();
- if (result == null) {
- result = Thread.currentThread().getName();
- THREADLOCAL_NAME.set(result);
- }
- return result;
- }
- },
- UNCACHED {
- @Override
- public String getThreadName() {
- return Thread.currentThread().getName();
- }
- };
-
- private static final StatusLogger LOGGER = StatusLogger.getLogger();
- private static final ThreadLocal<String> THREADLOCAL_NAME = new ThreadLocal<>();
- static final ThreadNameCachingStrategy DEFAULT_STRATEGY = isAllocatingThreadGetName() ? CACHED : UNCACHED;
-
- abstract String getThreadName();
-
- public static ThreadNameCachingStrategy create() {
- final String name =
- PropertiesUtil.getProperties().getStringProperty(Log4jPropertyKey.ASYNC_LOGGER_THREAD_NAME_STRATEGY);
- try {
- final ThreadNameCachingStrategy result =
- name != null ? ThreadNameCachingStrategy.valueOf(name) : DEFAULT_STRATEGY;
- LOGGER.debug(
- "{}={} (user specified {}, default is {})",
- Log4jPropertyKey.ASYNC_LOGGER_THREAD_NAME_STRATEGY,
- result.name(),
- name,
- DEFAULT_STRATEGY.name());
- return result;
- } catch (final Exception ex) {
- LOGGER.debug(
- "Using {}.{}: '{}' not valid: {}",
- Log4jPropertyKey.ASYNC_LOGGER_THREAD_NAME_STRATEGY,
- DEFAULT_STRATEGY.name(),
- name,
- ex.toString());
- return DEFAULT_STRATEGY;
- }
- }
-
- static boolean isAllocatingThreadGetName() {
- // LOG4J2-2052, LOG4J2-2635 JDK 8u102 ("1.8.0_102") removed the String allocation in Thread.getName()
- if (Constants.JAVA_MAJOR_VERSION == 8) {
- try {
- final Pattern javaVersionPattern = Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)_(\\d+)");
- final Matcher m = javaVersionPattern.matcher(System.getProperty("java.version"));
- if (m.matches()) {
- return Integer.parseInt(m.group(3)) == 0 && Integer.parseInt(m.group(4)) < 102;
- }
- return true;
- } catch (final Exception e) {
- return true;
- }
- } else {
- return Constants.JAVA_MAJOR_VERSION < 8;
- }
- }
-}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataInjectorFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataInjectorFactory.java
index 13e16a8c87..6a358a9345 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataInjectorFactory.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataInjectorFactory.java
@@ -20,7 +20,6 @@ import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.ContextDataInjector;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.spi.CopyOnWrite;
-import org.apache.logging.log4j.spi.DefaultThreadContextMap;
import org.apache.logging.log4j.spi.ReadOnlyThreadContextMap;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.LoaderUtil;
@@ -80,7 +79,7 @@ public class ContextDataInjectorFactory {
final ReadOnlyThreadContextMap threadContextMap = ThreadContext.getThreadContextMap();
// note: map may be null (if legacy custom ThreadContextMap was installed by user)
- if (threadContextMap instanceof DefaultThreadContextMap || threadContextMap == null) {
+ if (threadContextMap == null) {
return new ThreadContextDataInjector.ForDefaultThreadContextMap(); // for non StringMap-based context maps
}
if (threadContextMap instanceof CopyOnWrite) {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/DefaultBundle.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/DefaultBundle.java
index 7d9091071b..79ba0674dd 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/DefaultBundle.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/DefaultBundle.java
@@ -16,8 +16,6 @@
*/
package org.apache.logging.log4j.core.impl;
-import static org.apache.logging.log4j.util.Constants.isThreadLocalsEnabled;
-
import java.util.Map;
import java.util.function.Supplier;
import org.apache.logging.log4j.Level;
@@ -91,7 +89,7 @@ public class DefaultBundle {
final ReadOnlyThreadContextMap threadContextMap = ThreadContext.getThreadContextMap();
// note: map may be null (if legacy custom ThreadContextMap was installed by user)
- if (threadContextMap instanceof DefaultThreadContextMap || threadContextMap == null) {
+ if (threadContextMap == null) {
// for non StringMap-based context maps
return new ThreadContextDataInjector.ForDefaultThreadContextMap();
}
@@ -103,14 +101,12 @@ public class DefaultBundle {
@SingletonFactory
@ConditionalOnMissingBinding
- public LogEventFactory defaultLogEventFactory(
+ public LogEventFactory reusableLogEventFactory(
final ContextDataInjector injector,
final Clock clock,
final NanoClock nanoClock,
final RecyclerFactory recyclerFactory) {
- return isThreadLocalsEnabled()
- ? new ReusableLogEventFactory(injector, clock, nanoClock, recyclerFactory)
- : new DefaultLogEventFactory(injector, clock, nanoClock);
+ return new ReusableLogEventFactory(injector, clock, nanoClock, recyclerFactory);
}
@SingletonFactory
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java
index 6f40131165..7a19db87b3 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java
@@ -23,7 +23,6 @@ import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.ContextDataInjector;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.ReusableLogEvent;
-import org.apache.logging.log4j.core.async.ThreadNameCachingStrategy;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.time.Clock;
import org.apache.logging.log4j.core.time.NanoClock;
@@ -38,7 +37,6 @@ import org.apache.logging.log4j.spi.recycler.RecyclerFactory;
* @see Recycler
*/
public class ReusableLogEventFactory implements LogEventFactory {
- private static final ThreadNameCachingStrategy THREAD_NAME_CACHING_STRATEGY = ThreadNameCachingStrategy.create();
private final ContextDataInjector injector;
private final Clock clock;
@@ -125,11 +123,8 @@ public class ReusableLogEventFactory implements LogEventFactory {
result.setContextData(injector.injectContextData(properties, result.getContextData()));
result.setContextStack(
ThreadContext.getDepth() == 0 ? ThreadContext.EMPTY_STACK : ThreadContext.cloneStack()); // mutable copy
-
- if (THREAD_NAME_CACHING_STRATEGY == ThreadNameCachingStrategy.UNCACHED) {
- result.setThreadName(Thread.currentThread().getName()); // Thread.getName() allocates Objects on each call
- result.setThreadPriority(Thread.currentThread().getPriority());
- }
+ result.setThreadName(Thread.currentThread().getName());
+ result.setThreadPriority(Thread.currentThread().getPriority());
return result;
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/HtmlLayout.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/HtmlLayout.java
index f0df168b0c..42fdbd10eb 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/HtmlLayout.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/HtmlLayout.java
@@ -132,7 +132,7 @@ public final class HtmlLayout extends AbstractStringLayout {
this.headerSize = headerSize;
this.datePatternConverter = DEFAULT_DATE_PATTERN.equals(datePattern)
? null
- : DatePatternConverter.newInstance(new String[] {datePattern, timezone});
+ : DatePatternConverter.newInstance(configuration, new String[] {datePattern, timezone});
}
/**
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/DatePatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/DatePatternConverter.java
index e77c9aa599..d923c34f7c 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/DatePatternConverter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/DatePatternConverter.java
@@ -16,15 +16,13 @@
*/
package org.apache.logging.log4j.core.pattern;
-import static org.apache.logging.log4j.util.Constants.isThreadLocalsEnabled;
-
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;
import java.util.Objects;
import java.util.TimeZone;
-import java.util.concurrent.atomic.AtomicReference;
import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.time.Instant;
import org.apache.logging.log4j.core.time.MutableInstant;
import org.apache.logging.log4j.core.time.internal.format.FastDateFormat;
@@ -32,6 +30,7 @@ import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat;
import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat.FixedFormat;
import org.apache.logging.log4j.plugins.Namespace;
import org.apache.logging.log4j.plugins.Plugin;
+import org.apache.logging.log4j.spi.recycler.Recycler;
import org.apache.logging.log4j.util.PerformanceSensitive;
/**
@@ -47,8 +46,6 @@ public final class DatePatternConverter extends LogEventPatternConverter impleme
long previousTime; // for ThreadLocal caching mode
int nanos;
- abstract String format(final Instant instant);
-
abstract void formatToBuffer(final Instant instant, StringBuilder destination);
public String toPattern() {
@@ -70,11 +67,6 @@ public final class DatePatternConverter extends LogEventPatternConverter impleme
this.fastDateFormat = fastDateFormat;
}
- @Override
- String format(final Instant instant) {
- return fastDateFormat.format(instant.getEpochMillisecond());
- }
-
@Override
void formatToBuffer(final Instant instant, final StringBuilder destination) {
final long timeMillis = instant.getEpochMillisecond();
@@ -107,11 +99,6 @@ public final class DatePatternConverter extends LogEventPatternConverter impleme
this.fixedDateFormat = fixedDateFormat;
}
- @Override
- String format(final Instant instant) {
- return fixedDateFormat.formatInstant(instant);
- }
-
@Override
void formatToBuffer(final Instant instant, final StringBuilder destination) {
final long epochSecond = instant.getEpochSecond();
@@ -137,11 +124,6 @@ public final class DatePatternConverter extends LogEventPatternConverter impleme
private static final class UnixFormatter extends Formatter {
- @Override
- String format(final Instant instant) {
- return Long.toString(instant.getEpochSecond());
- }
-
@Override
void formatToBuffer(final Instant instant, final StringBuilder destination) {
destination.append(instant.getEpochSecond()); // no need for caching
@@ -150,29 +132,12 @@ public final class DatePatternConverter extends LogEventPatternConverter impleme
private static final class UnixMillisFormatter extends Formatter {
- @Override
- String format(final Instant instant) {
- return Long.toString(instant.getEpochMillisecond());
- }
-
@Override
void formatToBuffer(final Instant instant, final StringBuilder destination) {
destination.append(instant.getEpochMillisecond()); // no need for caching
}
}
- private final class CachedTime {
- public final long epochSecond;
- public final int nanoOfSecond;
- public final String formatted;
-
- public CachedTime(final Instant instant) {
- this.epochSecond = instant.getEpochSecond();
- this.nanoOfSecond = instant.getNanoOfSecond();
- this.formatted = formatter.format(instant);
- }
- }
-
/**
* UNIX formatter in seconds (standard).
*/
@@ -183,28 +148,31 @@ public final class DatePatternConverter extends LogEventPatternConverter impleme
*/
private static final String UNIX_MILLIS_FORMAT = "UNIX_MILLIS";
- private final String[] options;
- private final ThreadLocal<MutableInstant> threadLocalMutableInstant = new ThreadLocal<>();
- private final ThreadLocal<Formatter> threadLocalFormatter = new ThreadLocal<>();
- private final AtomicReference<CachedTime> cachedTime;
- private final Formatter formatter;
+ private final String pattern;
+
+ private final TimeZone timeZone;
+
+ private final Recycler<MutableInstant> mutableInstantRecycler;
+
+ private final Recycler<Formatter> formatterRecycler;
/**
* Private constructor.
*
* @param options options, may be null.
*/
- private DatePatternConverter(final String[] options) {
+ private DatePatternConverter(final Configuration configuration, final String[] options) {
super("Date", "date");
- this.options = options == null ? null : Arrays.copyOf(options, options.length);
- this.formatter = createFormatter(options);
- cachedTime = new AtomicReference<>(fromEpochMillis(System.currentTimeMillis()));
- }
-
- private CachedTime fromEpochMillis(final long epochMillis) {
- final MutableInstant temp = new MutableInstant();
- temp.initFromEpochMilli(epochMillis, 0);
- return new CachedTime(temp);
+ final String[] safeOptions = options == null ? null : Arrays.copyOf(options, options.length);
+ this.mutableInstantRecycler = configuration.getRecyclerFactory().create(MutableInstant::new);
+ this.formatterRecycler = configuration.getRecyclerFactory().create(() -> createFormatter(safeOptions));
+ final Formatter formatter = formatterRecycler.acquire();
+ try {
+ this.pattern = formatter.toPattern();
+ this.timeZone = formatter.getTimeZone();
+ } finally {
+ formatterRecycler.release(formatter);
+ }
}
private Formatter createFormatter(final String[] options) {
@@ -221,8 +189,8 @@ public final class DatePatternConverter extends LogEventPatternConverter impleme
* @param options options, may be null.
* @return instance of pattern converter.
*/
- public static DatePatternConverter newInstance(final String[] options) {
- return new DatePatternConverter(options);
+ public static DatePatternConverter newInstance(final Configuration configuration, final String[] options) {
+ return new DatePatternConverter(configuration, options);
}
private static Formatter createFixedFormatter(final FixedDateFormat fixedDateFormat) {
@@ -275,7 +243,7 @@ public final class DatePatternConverter extends LogEventPatternConverter impleme
* @param date date
* @param toAppendTo buffer to which formatted date is appended.
*/
- public void format(final Date date, final StringBuilder toAppendTo) {
+ void format(final Date date, final StringBuilder toAppendTo) {
format(date.getTime(), toAppendTo);
}
@@ -287,55 +255,23 @@ public final class DatePatternConverter extends LogEventPatternConverter impleme
format(event.getInstant(), output);
}
- public void format(final long epochMilli, final StringBuilder output) {
- final MutableInstant instant = getMutableInstant();
- instant.initFromEpochMilli(epochMilli, 0);
- format(instant, output);
- }
-
- private MutableInstant getMutableInstant() {
- if (isThreadLocalsEnabled()) {
- MutableInstant result = threadLocalMutableInstant.get();
- if (result == null) {
- result = new MutableInstant();
- threadLocalMutableInstant.set(result);
- }
- return result;
- }
- return new MutableInstant();
- }
-
- public void format(final Instant instant, final StringBuilder output) {
- if (isThreadLocalsEnabled()) {
- formatWithoutAllocation(instant, output);
- } else {
- formatWithoutThreadLocals(instant, output);
- }
- }
-
- private void formatWithoutAllocation(final Instant instant, final StringBuilder output) {
- getThreadLocalFormatter().formatToBuffer(instant, output);
- }
-
- private Formatter getThreadLocalFormatter() {
- Formatter result = threadLocalFormatter.get();
- if (result == null) {
- result = createFormatter(options);
- threadLocalFormatter.set(result);
+ private void format(final long epochMilli, final StringBuilder output) {
+ final MutableInstant instant = mutableInstantRecycler.acquire();
+ try {
+ instant.initFromEpochMilli(epochMilli, 0);
+ format(instant, output);
+ } finally {
+ mutableInstantRecycler.release(instant);
}
- return result;
}
- private void formatWithoutThreadLocals(final Instant instant, final StringBuilder output) {
- final CachedTime effective;
- final CachedTime cached = cachedTime.get();
- if (instant.getEpochSecond() != cached.epochSecond || instant.getNanoOfSecond() != cached.nanoOfSecond) {
- effective = new CachedTime(instant);
- cachedTime.compareAndSet(cached, effective);
- } else {
- effective = cached;
+ void format(final Instant instant, final StringBuilder output) {
+ final Formatter formatter = formatterRecycler.acquire();
+ try {
+ formatter.formatToBuffer(instant, output);
+ } finally {
+ formatterRecycler.release(formatter);
}
- output.append(effective.formatted);
}
/**
@@ -365,7 +301,7 @@ public final class DatePatternConverter extends LogEventPatternConverter impleme
* @return the pattern string describing this date format.
*/
public String getPattern() {
- return formatter.toPattern();
+ return pattern;
}
/**
@@ -374,6 +310,6 @@ public final class DatePatternConverter extends LogEventPatternConverter impleme
* @return the timezone used by this date format.
*/
public TimeZone getTimeZone() {
- return formatter.getTimeZone();
+ return timeZone;
}
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/FileDatePatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/FileDatePatternConverter.java
index 4bdda72055..0e2fbd3efd 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/FileDatePatternConverter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/FileDatePatternConverter.java
@@ -17,6 +17,7 @@
package org.apache.logging.log4j.core.pattern;
import java.util.TimeZone;
+import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.plugins.Namespace;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.util.PerformanceSensitive;
@@ -37,8 +38,8 @@ public final class FileDatePatternConverter implements ArrayPatternConverter {
/**
* Private constructor.
*/
- private FileDatePatternConverter(final String... options) {
- delegate = DatePatternConverter.newInstance(options);
+ private FileDatePatternConverter(final Configuration configuration, final String... options) {
+ delegate = DatePatternConverter.newInstance(configuration, options);
}
/**
@@ -47,12 +48,12 @@ public final class FileDatePatternConverter implements ArrayPatternConverter {
* @param options options, may be null.
* @return instance of pattern converter.
*/
- public static FileDatePatternConverter newInstance(final String[] options) {
+ public static FileDatePatternConverter newInstance(final Configuration configuration, final String[] options) {
if (options == null || options.length == 0) {
- return new FileDatePatternConverter("yyyy-MM-dd");
+ return new FileDatePatternConverter(configuration, "yyyy-MM-dd");
}
- return new FileDatePatternConverter(options);
+ return new FileDatePatternConverter(configuration, options);
}
@Override
diff --git a/log4j-gctests/src/test/java/org/apache/logging/log4j/gctests/GcFreeLoggingTestUtil.java b/log4j-gctests/src/test/java/org/apache/logging/log4j/gctests/GcFreeLoggingTestUtil.java
index 6c248bf6fe..c99c7100f7 100644
--- a/log4j-gctests/src/test/java/org/apache/logging/log4j/gctests/GcFreeLoggingTestUtil.java
+++ b/log4j-gctests/src/test/java/org/apache/logging/log4j/gctests/GcFreeLoggingTestUtil.java
@@ -17,7 +17,6 @@
package org.apache.logging.log4j.gctests;
import static java.lang.System.getProperty;
-import static org.apache.logging.log4j.util.Constants.isThreadLocalsEnabled;
import static org.apache.logging.log4j.util.Constants.isWebApp;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -53,12 +52,10 @@ public enum GcFreeLoggingTestUtil {
public static void executeLogging(final String configurationFile, final Class<?> testClass) throws Exception {
- System.setProperty(LoggingSystemProperty.THREAD_LOCALS_ENABLE.getSystemKey(), "true");
System.setProperty(Log4jPropertyKey.GC_ENABLE_DIRECT_ENCODERS.getSystemKey(), "true");
System.setProperty(LoggingSystemProperty.IS_WEBAPP.getSystemKey(), "false");
System.setProperty(Log4jPropertyKey.CONFIG_LOCATION.getSystemKey(), configurationFile);
- assertTrue(isThreadLocalsEnabled(), "Constants.isThreadLocalsEnabled()");
assertTrue(Constants.ENABLE_DIRECT_ENCODERS, "Constants.ENABLE_DIRECT_ENCODERS");
assertFalse(isWebApp(), "Constants.isWebApp()");
diff --git a/log4j-gctests/src/test/java/org/apache/logging/log4j/gctests/JsonTemplateLayoutGcFreeTest.java b/log4j-gctests/src/test/java/org/apache/logging/log4j/gctests/JsonTemplateLayoutGcFreeTest.java
index c7000fbf7c..8e3579db50 100644
--- a/log4j-gctests/src/test/java/org/apache/logging/log4j/gctests/JsonTemplateLayoutGcFreeTest.java
+++ b/log4j-gctests/src/test/java/org/apache/logging/log4j/gctests/JsonTemplateLayoutGcFreeTest.java
@@ -33,7 +33,6 @@ public class JsonTemplateLayoutGcFreeTest {
* This code runs in a separate process, instrumented with the Google Allocation Instrumenter.
*/
public static void main(final String[] args) throws Exception {
- System.setProperty("log4j.layout.jsonTemplate.recyclerFactory", "threadLocal");
System.setProperty(LoggingSystemProperty.THREAD_CONTEXT_GARBAGE_FREE_ENABLED.getSystemKey(), "true");
GcFreeLoggingTestUtil.executeLogging("gcFreeJsonTemplateLayoutLogging.xml", JsonTemplateLayoutGcFreeTest.class);
}
diff --git a/log4j-gctests/src/test/resources/gcFreeJsonTemplateLayoutLogging.xml b/log4j-gctests/src/test/resources/gcFreeJsonTemplateLayoutLogging.xml
index 498410cd60..6f221e3c9c 100644
--- a/log4j-gctests/src/test/resources/gcFreeJsonTemplateLayoutLogging.xml
+++ b/log4j-gctests/src/test/resources/gcFreeJsonTemplateLayoutLogging.xml
@@ -24,7 +24,7 @@
fileName="target/gcFreeJsonTemplateLayoutLogging.log"
bufferedIO="false"
append="false">
- <JsonTemplateLayout recyclerFactory="threadLocal"/>
+ <JsonTemplateLayout/>
</File>
</Appenders>
<Loggers>
diff --git a/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutTest.java b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutTest.java
index 20f75b4085..fc73019769 100644
--- a/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutTest.java
+++ b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutTest.java
@@ -613,8 +613,7 @@ class JsonTemplateLayoutTest {
// Get toByteArrayOutput().
final byte[] toByteArrayOutputBytes = layout.toByteArray(logEvent);
- final String toByteArrayOutput =
- new String(toByteArrayOutputBytes, 0, toByteArrayOutputBytes.length, layout.getCharset());
+ final String toByteArrayOutput = new String(toByteArrayOutputBytes, layout.getCharset());
// Get encode() output.
final ByteBuffer byteBuffer = ByteBuffer.allocate(512 * 1024);
@@ -1307,16 +1306,6 @@ class JsonTemplateLayoutTest {
});
}
- @Test
- void test_MessageParameterResolver_with_ParameterizedMessageFactory() {
- testMessageParameterResolver(ParameterizedMessageFactory.INSTANCE);
- }
-
- @Test
- void test_MessageParameterResolver_noParameters_with_ParameterizedMessageFactory() {
- testMessageParameterResolverNoParameters(ParameterizedMessageFactory.INSTANCE);
- }
-
@Test
void test_MessageParameterResolver_with_ReusableMessageFactory() {
testMessageParameterResolver(ReusableMessageFactory.INSTANCE);
diff --git a/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/AsyncLoggersLocationBenchmark.java b/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/AsyncLoggersLocationBenchmark.java
index 25cf4cb3be..bc965eedae 100644
--- a/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/AsyncLoggersLocationBenchmark.java
+++ b/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/AsyncLoggersLocationBenchmark.java
@@ -57,7 +57,6 @@ public class AsyncLoggersLocationBenchmark {
System.setProperty("Log4jContextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");
System.setProperty("AsyncLogger.RingBufferSize", "262144");
System.setProperty("AsyncLogger.WaitStrategy", "Yield");
- // System.setProperty("log4j2.enable.threadlocals", "true");
// System.setProperty("log4j.format.msg.async", "true");
logger = LogManager.getLogger(getClass());
diff --git a/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadContextBenchmark.java b/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadContextBenchmark.java
index da5271fb32..787516e76d 100644
--- a/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadContextBenchmark.java
+++ b/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadContextBenchmark.java
@@ -30,7 +30,6 @@ import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.impl.ContextDataInjectorFactory;
import org.apache.logging.log4j.perf.nogc.OpenHashStringMap;
import org.apache.logging.log4j.spi.CopyOnWriteOpenHashMapThreadContextMap;
-import org.apache.logging.log4j.spi.DefaultThreadContextMap;
import org.apache.logging.log4j.spi.GarbageFreeOpenHashMapThreadContextMap;
import org.apache.logging.log4j.spi.LoggingSystemProperty;
import org.apache.logging.log4j.spi.ThreadContextMap;
@@ -71,7 +70,6 @@ import org.openjdk.jmh.annotations.Warmup;
@Fork(1)
@State(Scope.Benchmark)
public class ThreadContextBenchmark {
- private static final String DEFAULT_CONTEXT_MAP = "Default";
private static final String COPY_OPENHASH_MAP = "CopyOpenHash";
private static final String COPY_ARRAY_MAP = "CopySortedArray";
private static final String NO_GC_OPENHASH_MAP = "NoGcOpenHash";
@@ -79,7 +77,6 @@ public class ThreadContextBenchmark {
private static final Map<String, Class<? extends ThreadContextMap>> IMPLEMENTATIONS = new HashMap<>();
static {
- IMPLEMENTATIONS.put(DEFAULT_CONTEXT_MAP, DefaultThreadContextMap.class);
IMPLEMENTATIONS.put(COPY_OPENHASH_MAP, CopyOnWriteOpenHashMapThreadContextMap.class);
IMPLEMENTATIONS.put(
COPY_ARRAY_MAP,
diff --git a/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadLocalVsConcurrentHashMapBenchmark.java b/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadLocalVsConcurrentHashMapBenchmark.java
deleted file mode 100644
index fff26cefd4..0000000000
--- a/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadLocalVsConcurrentHashMapBenchmark.java
+++ /dev/null
@@ -1,92 +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.perf.jmh;
-
-import java.util.concurrent.ConcurrentHashMap;
-import org.openjdk.jmh.annotations.Benchmark;
-import org.openjdk.jmh.annotations.Scope;
-import org.openjdk.jmh.annotations.State;
-
-/**
- * Compares performance of ThreadLocal, vs ConcurrentHashMap<Thread, Object>.
- */
-// ============================== HOW TO RUN THIS TEST: ====================================
-// (Quick build: mvn -DskipTests=true clean package -pl log4j-perf -am )
-//
-// single thread:
-// java -jar log4j-perf/target/benchmarks.jar ".*ThreadLocalVsConcurrentHashMap.*" -f 1 -wi 10 -i 20 -tu ns -bm sample
-//
-// four threads:
-// java -jar log4j-perf/target/benchmarks.jar ".*ThreadLocalVsConcurrentHashMap.*" -f 1 -wi 10 -i 20 -tu ns -bm sample
-// -t 4
-//
-// Usage help:
-// java -jar log4j-perf/target/benchmarks.jar -help
-//
-@State(Scope.Benchmark)
-public class ThreadLocalVsConcurrentHashMapBenchmark {
-
- private static final String VALUE = "value";
- private static ConcurrentHashMap<Thread, StringBuilder> map = new ConcurrentHashMap<>();
- private static ThreadLocal<StringBuilder> threadLocal = new ThreadLocal<>();
-
- @Benchmark
- public String newInstance() {
- final StringBuilder sb = getNew();
- sb.append(VALUE);
- return sb.toString();
- }
-
- @Benchmark
- public String threadLocal() {
- final StringBuilder sb = getThreadLocal();
- sb.append(VALUE);
- return sb.toString();
- }
-
- @Benchmark
- public String concurrentHashMap() {
- final StringBuilder sb = getConcurrentMap();
- sb.append(VALUE);
- return sb.toString();
- }
-
- private StringBuilder getNew() {
- final StringBuilder buf = new StringBuilder();
- return buf;
- }
-
- private StringBuilder getThreadLocal() {
- StringBuilder buf = threadLocal.get();
- if (buf == null) {
- buf = new StringBuilder();
- threadLocal.set(buf);
- }
- buf.setLength(0);
- return buf;
- }
-
- private StringBuilder getConcurrentMap() {
- StringBuilder buf = map.get(Thread.currentThread());
- if (buf == null) {
- buf = new StringBuilder();
- map.put(Thread.currentThread(), buf);
- }
- buf.setLength(0);
- return buf;
- }
-}
diff --git a/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadLocalVsPoolBenchmark.java b/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadLocalVsPoolBenchmark.java
deleted file mode 100644
index 8623eed1b9..0000000000
--- a/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadLocalVsPoolBenchmark.java
+++ /dev/null
@@ -1,200 +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.perf.jmh;
-
-import java.util.List;
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.core.config.DefaultConfiguration;
-import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
-import org.apache.logging.log4j.core.pattern.PatternFormatter;
-import org.apache.logging.log4j.core.pattern.PatternParser;
-import org.apache.logging.log4j.message.Message;
-import org.apache.logging.log4j.message.SimpleMessage;
-import org.jctools.queues.MpmcArrayQueue;
-import org.openjdk.jmh.annotations.Benchmark;
-import org.openjdk.jmh.annotations.Scope;
-import org.openjdk.jmh.annotations.State;
-
-/**
- * Checks {@link PatternFormatter} performance with various StringBuilder
- * caching strategies: no-op, ThreadLocal, and JCTools MPMC queue.
- */
-// ============================== HOW TO RUN THIS TEST: ====================================
-// (Quick build: mvn -DskipTests=true clean package -pl log4j-perf -am )
-//
-// single thread:
-// java -jar log4j-perf/target/benchmarks.jar ".*ThreadLocalVsPool.*" -f 1 -wi 10 -i 20 -tu ns -bm sample
-//
-// four threads:
-// java -jar log4j-perf/target/benchmarks.jar ".*ThreadLocalVsPool.*" -f 1 -wi 10 -i 20 -tu ns -bm sample -t 4
-//
-// Usage help:
-// java -jar log4j-perf/target/benchmarks.jar -help
-//
-@State(Scope.Benchmark)
-public class ThreadLocalVsPoolBenchmark {
-
- private static final LogEvent LOG_EVENT = createLogEvent();
-
- private static final List<PatternFormatter> FORMATTERS = createFormatters();
-
- private static LogEvent createLogEvent() {
- final String loggerName = "name(ignored)";
- final String loggerFqcn = "com.mycom.myproject.mypackage.MyClass";
- final Level level = Level.DEBUG;
- final String messageString = "AB!(%087936DZYXQWEIOP$#^~-=/><nb"; // length=32
- final Message message = new SimpleMessage(messageString);
- final long timestamp = 12345678;
- return Log4jLogEvent.newBuilder()
- .setLoggerName(loggerName)
- .setLoggerFqcn(loggerFqcn)
- .setLevel(level)
- .setMessage(message)
- .setTimeMillis(timestamp)
- .build();
- }
-
- private static List<PatternFormatter> createFormatters() {
- final Configuration config = new DefaultConfiguration();
- final PatternParser parser = new PatternParser(config, "Converter", LogEventPatternConverter.class);
- return parser.parse("%d %5p [%t] %c{1} %X{transactionId} - %m%n", false, true);
- }
-
- private abstract static class StringBuilderPool {
-
- abstract StringBuilder acquire();
-
- abstract void release(StringBuilder stringBuilder);
-
- StringBuilder createStringBuilder() {
- return new StringBuilder(1024 * 32);
- }
- }
-
- private static final class AllocatePool extends StringBuilderPool {
-
- private static final AllocatePool INSTANCE = new AllocatePool();
-
- @Override
- public StringBuilder acquire() {
- return createStringBuilder();
- }
-
- @Override
- public void release(final StringBuilder stringBuilder) {}
- }
-
- private static final class ThreadLocalPool extends StringBuilderPool {
-
- private static final ThreadLocalPool INSTANCE = new ThreadLocalPool();
-
- private final ThreadLocal<StringBuilder> stringBuilderRef = ThreadLocal.withInitial(this::createStringBuilder);
-
- @Override
- public StringBuilder acquire() {
- return stringBuilderRef.get();
- }
-
- @Override
- public void release(final StringBuilder stringBuilder) {
- stringBuilder.setLength(0);
- }
- }
-
- private static final class JcPool extends StringBuilderPool {
-
- private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
-
- private static final int MPMC_REQUIRED_MIN_CAPACITY = 2;
-
- // Putting the under-provisioned instance to a wrapper class to prevent
- // the initialization of JcPool itself when there are insufficient CPU
- // cores.
- private enum UnderProvisionedInstanceHolder {
- ;
-
- private static final JcPool INSTANCE = createInstance();
-
- private static JcPool createInstance() {
- if (CPU_COUNT <= MPMC_REQUIRED_MIN_CAPACITY) {
- throw new IllegalArgumentException("insufficient CPU cores");
- }
- return new JcPool(MPMC_REQUIRED_MIN_CAPACITY);
- }
- }
-
- private static final JcPool RIGHT_PROVISIONED_INSTANCE =
- new JcPool(Math.max(MPMC_REQUIRED_MIN_CAPACITY, CPU_COUNT));
-
- private final MpmcArrayQueue<StringBuilder> stringBuilders;
-
- private JcPool(final int capacity) {
- this.stringBuilders = new MpmcArrayQueue<>(capacity);
- }
-
- @Override
- public StringBuilder acquire() {
- final StringBuilder stringBuilder = stringBuilders.poll();
- return stringBuilder != null ? stringBuilder : createStringBuilder();
- }
-
- @Override
- public void release(final StringBuilder stringBuilder) {
- stringBuilder.setLength(0);
- stringBuilders.offer(stringBuilder);
- }
- }
-
- @Benchmark
- public int allocate() {
- return findSerializedLength(AllocatePool.INSTANCE);
- }
-
- @Benchmark
- public int threadLocal() {
- return findSerializedLength(ThreadLocalPool.INSTANCE);
- }
-
- @Benchmark
- public int rightProvedJc() {
- return findSerializedLength(JcPool.RIGHT_PROVISIONED_INSTANCE);
- }
-
- @Benchmark
- public int underProvedJc() {
- return findSerializedLength(JcPool.UnderProvisionedInstanceHolder.INSTANCE);
- }
-
- private int findSerializedLength(final StringBuilderPool pool) {
- final StringBuilder stringBuilder = pool.acquire();
- serialize(stringBuilder);
- final int length = stringBuilder.length();
- pool.release(stringBuilder);
- return length;
- }
-
- private void serialize(final StringBuilder stringBuilder) {
- // noinspection ForLoopReplaceableByForEach (avoid iterator instantiation)
- for (int formatterIndex = 0; formatterIndex < FORMATTERS.size(); formatterIndex++) {
- final PatternFormatter formatter = FORMATTERS.get(formatterIndex);
- formatter.format(LOG_EVENT, stringBuilder);
- }
- }
-}
diff --git a/log4j-to-slf4j/src/test/java/org/apache/logging/slf4j/LoggerTest.java b/log4j-to-slf4j/src/test/java/org/apache/logging/slf4j/LoggerTest.java
index 47d760aa7b..7be02d63cb 100644
--- a/log4j-to-slf4j/src/test/java/org/apache/logging/slf4j/LoggerTest.java
+++ b/log4j-to-slf4j/src/test/java/org/apache/logging/slf4j/LoggerTest.java
@@ -30,7 +30,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.message.MessageFactory;
-import org.apache.logging.log4j.message.ParameterizedMessageFactory;
+import org.apache.logging.log4j.message.ReusableMessageFactory;
import org.apache.logging.log4j.message.StringFormatterMessageFactory;
import org.apache.logging.log4j.spi.LoggingSystem;
import org.apache.logging.log4j.test.junit.UsingStatusListener;
@@ -102,7 +102,7 @@ public class LoggerTest {
final Logger testLogger = testMessageFactoryMismatch(
"getLogger_String_MessageFactoryMismatch",
StringFormatterMessageFactory.INSTANCE,
- ParameterizedMessageFactory.INSTANCE);
+ new ReusableMessageFactory());
testLogger.debug("%,d", Integer.MAX_VALUE);
assertThat(list.strList, hasSize(1));
assertThat(list.strList, hasItem(String.format("%,d", Integer.MAX_VALUE)));
diff --git a/src/changelog/.3.x.x/remove_thread_locals_property.xml b/src/changelog/.3.x.x/remove_thread_locals_property.xml
new file mode 100644
index 0000000000..deb4701d2a
--- /dev/null
+++ b/src/changelog/.3.x.x/remove_thread_locals_property.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://logging.apache.org/log4j/changelog"
+ xsi:schemaLocation="http://logging.apache.org/log4j/changelog https://logging.apache.org/log4j/changelog-0.1.3.xsd"
+ type="removed">
+ <issue id="2105" link="https://github.com/apache/logging-log4j2/issues/2105"/>
+ <description format="asciidoc">Remove `log4j2.enable.threadlocals` property</description>
+</entry>
diff --git a/src/site/_release-notes/_3.x.x.adoc b/src/site/_release-notes/_3.x.x.adoc
index 6f01ff61f1..138505b155 100644
--- a/src/site/_release-notes/_3.x.x.adoc
+++ b/src/site/_release-notes/_3.x.x.adoc
@@ -24,10 +24,12 @@ This release contains...
=== Added
* Add and update DSLs for setting up dependency injection for test and non-test code. (https://github.com/apache/logging-log4j2/issues/2147[2147])
+* Add a new properties configuration factory based on `jackson-dataformat-properties`.
[#release-notes-3-x-x-changed]
=== Changed
+* Moves legacy `2.x` properties configuration factory to `log4j-config-properties-legacy`.
* Split off YAML configuration into a new `log4j-config-yaml` module.
* Update `com.google.code.java-allocation-instrumenter:java-allocation-instrumenter` to version `3.3.4` (https://github.com/apache/logging-log4j2/pull/2102[2102])
* Update `com.google.guava:guava` to version `33.0.0-jre` (https://github.com/apache/logging-log4j2/pull/2108[2108])
@@ -46,6 +48,7 @@ This release contains...
=== Removed
* Remove `org.apache.logging.log4j.core.parser` and related packages. (https://github.com/apache/logging-log4j2/pull/2154[2154])
+* Remove `log4j2.enable.threadlocals` property (https://github.com/apache/logging-log4j2/issues/2105[2105])
[#release-notes-3-x-x-updated]
=== Updated
diff --git a/src/site/asciidoc/manual/extending.adoc b/src/site/asciidoc/manual/extending.adoc
index b14f319fb4..f00302d16b 100644
--- a/src/site/asciidoc/manual/extending.adoc
+++ b/src/site/asciidoc/manual/extending.adoc
@@ -217,8 +217,7 @@ the `LogEventFactory` is not used.
== MessageFactory
A `MessageFactory` is used to generate `Message` objects. Applications may
-replace the standard `ParameterizedMessageFactory` (or
-`ReusableMessageFactory` in garbage-free mode) by setting the value of the
+replace the standard `ReusableMessageFactory` by setting the value of the
system property `log4j2.messageFactory` to the name of the custom
`MessageFactory` class.
diff --git a/src/site/asciidoc/manual/systemproperties.adoc b/src/site/asciidoc/manual/systemproperties.adoc
index f743494c3f..a1f7fd576f 100644
--- a/src/site/asciidoc/manual/systemproperties.adoc
+++ b/src/site/asciidoc/manual/systemproperties.adoc
@@ -183,9 +183,7 @@ classes with the current thread's context class loader before falling back to th
|factory
|log4j2.messageFactory, LOG4J_MESSAGE_FACTORY
|System/Application
-|org.apache.logging.log4j.message. ParameterizedMessageFactory or
-org.apache.logging.log4j.message. ReusableMessageFactory in garbage-free
-mode
+`org.apache.logging.log4j.message.ReusableMessageFactory`
|Default message factory used by Loggers if no factory was specified.
|Message