You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by pk...@apache.org on 2024/04/04 21:50:48 UTC
(logging-log4j2) 10/14: Move non-API classes to core
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch ScopedContext-replace-with-interface
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 827dbe02b406af66e18178fb916d382d557b1a55
Author: Ralph Goers <rg...@apache.org>
AuthorDate: Thu Apr 4 08:14:49 2024 -0700
Move non-API classes to core
---
.../org/apache/logging/log4j/test/TestLogger.java | 10 +-
.../org/apache/logging/log4j/ScopedContext.java | 123 +++++++++++++--------
.../apache/logging/log4j/simple/SimpleLogger.java | 7 +-
.../logging/log4j/spi/ContextDataProvider.java | 76 -------------
.../log4j/spi/ScopedContextDataProvider.java | 104 -----------------
.../logging/log4j/core/async/AsyncLogger.java | 2 +-
.../core/async/RingBufferLogEventTranslator.java | 2 +-
.../log4j/core/filter/DynamicThresholdFilter.java | 4 +-
.../log4j/core/filter/ThreadContextMapFilter.java | 2 +-
.../logging/log4j/core/impl}/ContextData.java | 5 +-
.../logging/log4j/core/impl/Log4jLogEvent.java | 1 -
.../log4j/core/impl/ReusableLogEventFactory.java | 1 -
.../log4j/core/impl/ScopedContextDataProvider.java | 27 +++--
.../log4j/core/impl/ThreadContextDataInjector.java | 11 +-
.../log4j/core/impl/ThreadContextDataProvider.java | 15 +++
.../log4j/core/lookup/ContextMapLookup.java | 2 +-
.../apache/logging/log4j/core/osgi/Activator.java | 6 +-
.../log4j/core/util/ContextDataProvider.java | 52 ++++++++-
18 files changed, 190 insertions(+), 260 deletions(-)
diff --git a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/TestLogger.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/TestLogger.java
index b308434cfc..5f1fb02de7 100644
--- a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/TestLogger.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/TestLogger.java
@@ -23,9 +23,10 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.apache.logging.log4j.ContextData;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.ScopedContext;
+import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MessageFactory;
import org.apache.logging.log4j.spi.AbstractLogger;
@@ -80,8 +81,11 @@ public class TestLogger extends AbstractLogger {
sb.append(' ');
}
sb.append(message.getFormattedMessage());
- final Map<String, String> mdc = new HashMap<>(ContextData.size());
- ContextData.addAll(mdc);
+ Map<String, ScopedContext.Renderable> contextMap = ScopedContext.getContextMap();
+ final Map<String, String> mdc = new HashMap<>(ThreadContext.getImmutableContext());
+ if (contextMap != null && !contextMap.isEmpty()) {
+ contextMap.forEach((key, value) -> mdc.put(key, value.render()));
+ }
if (!mdc.isEmpty()) {
sb.append(' ');
sb.append(mdc);
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/ScopedContext.java b/log4j-api/src/main/java/org/apache/logging/log4j/ScopedContext.java
index 67e2ba97fd..4081be5629 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/ScopedContext.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/ScopedContext.java
@@ -16,7 +16,9 @@
*/
package org.apache.logging.log4j;
+import java.util.ArrayDeque;
import java.util.Collections;
+import java.util.Deque;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@@ -25,7 +27,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.function.Supplier;
-import org.apache.logging.log4j.spi.ScopedContextDataProvider;
import org.apache.logging.log4j.status.StatusLogger;
/**
@@ -52,6 +53,48 @@ public class ScopedContext {
public static final Logger LOGGER = StatusLogger.getLogger();
+ private static final ThreadLocal<Deque<Instance>> scopedContext = new ThreadLocal<>();
+
+ /**
+ * Returns an immutable Map containing all the key/value pairs as Renderable objects.
+ * @return An immutable copy of the Map at the current scope.
+ */
+ private static Optional<Instance> getContext() {
+ Deque<Instance> stack = scopedContext.get();
+ if (stack != null) {
+ return Optional.of(stack.getFirst());
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Add the ScopeContext.
+ * @param context The ScopeContext.
+ */
+ private static void addScopedContext(Instance context) {
+ Deque<Instance> stack = scopedContext.get();
+ if (stack == null) {
+ stack = new ArrayDeque<>();
+ scopedContext.set(stack);
+ }
+ stack.addFirst(context);
+ }
+
+ /**
+ * Remove the top ScopeContext.
+ */
+ private static void removeScopedContext() {
+ Deque<Instance> stack = scopedContext.get();
+ if (stack != null) {
+ if (!stack.isEmpty()) {
+ stack.removeFirst();
+ }
+ if (stack.isEmpty()) {
+ scopedContext.remove();
+ }
+ }
+ }
+
/**
* @hidden
* Returns an unmodifiable copy of the current ScopedContext Map. This method should
@@ -59,7 +102,7 @@ public class ScopedContext {
* @return the Map of Renderable objects.
*/
public static Map<String, Renderable> getContextMap() {
- Optional<Instance> context = ScopedContextDataProvider.getContext();
+ Optional<Instance> context = getContext();
if (context.isPresent()
&& context.get().contextMap != null
&& !context.get().contextMap.isEmpty()) {
@@ -74,7 +117,7 @@ public class ScopedContext {
* @return the number of items in the context map.
*/
public static int size() {
- Optional<Instance> context = ScopedContextDataProvider.getContext();
+ Optional<Instance> context = getContext();
return context.map(instance -> instance.contextMap.size()).orElse(0);
}
@@ -85,7 +128,7 @@ public class ScopedContext {
*/
@SuppressWarnings("unchecked")
public static <T> T get(String key) {
- Optional<Instance> context = ScopedContextDataProvider.getContext();
+ Optional<Instance> context = getContext();
if (context.isPresent()) {
Renderable renderable = context.get().contextMap.get(key);
if (renderable != null) {
@@ -101,7 +144,7 @@ public class ScopedContext {
* @return The value of the key in the current ScopedContext.
*/
public static String getString(String key) {
- Optional<Instance> context = ScopedContextDataProvider.getContext();
+ Optional<Instance> context = getContext();
if (context.isPresent()) {
Renderable renderable = context.get().contextMap.get(key);
if (renderable != null) {
@@ -116,7 +159,7 @@ public class ScopedContext {
* @param map The Map to add entries to.
*/
public static void addAll(Map<String, String> map) {
- Optional<Instance> context = ScopedContextDataProvider.getContext();
+ Optional<Instance> context = getContext();
if (context.isPresent()) {
Map<String, Renderable> contextMap = context.get().contextMap;
if (contextMap != null && !contextMap.isEmpty()) {
@@ -136,16 +179,16 @@ public class ScopedContext {
public static Instance where(String key, Object value) {
if (value != null) {
Renderable renderable = value instanceof Renderable ? (Renderable) value : new ObjectRenderable(value);
- Instance parent = current().isPresent() ? current().get() : null;
+ Instance parent = getContext().isPresent() ? getContext().get() : null;
return new Instance(parent, key, renderable);
} else {
- if (current().isPresent()) {
+ if (getContext().isPresent()) {
Map<String, Renderable> map = getContextMap();
map.remove(key);
return new Instance(map);
}
}
- return current().isPresent() ? current().get() : new Instance();
+ return getContext().isPresent() ? getContext().get() : new Instance();
}
/**
@@ -167,8 +210,8 @@ public class ScopedContext {
public static Instance where(Map<String, ?> map) {
if (map != null && !map.isEmpty()) {
Map<String, Renderable> renderableMap = new HashMap<>();
- if (current().isPresent()) {
- renderableMap.putAll(current().get().contextMap);
+ if (getContext().isPresent()) {
+ renderableMap.putAll(getContext().get().contextMap);
}
map.forEach((key, value) -> {
if (value == null || (value instanceof String && ((String) value).isEmpty())) {
@@ -180,7 +223,7 @@ public class ScopedContext {
});
return new Instance(renderableMap);
} else {
- return current().isPresent() ? current().get() : new Instance();
+ return getContext().isPresent() ? getContext().get() : new Instance();
}
}
@@ -194,15 +237,15 @@ public class ScopedContext {
if (obj != null) {
Renderable renderable = obj instanceof Renderable ? (Renderable) obj : new ObjectRenderable(obj);
Map<String, Renderable> map = new HashMap<>();
- if (current().isPresent()) {
- map.putAll(current().get().contextMap);
+ if (getContext().isPresent()) {
+ map.putAll(getContext().get().contextMap);
}
map.put(key, renderable);
new Instance(map).run(op);
} else {
Map<String, Renderable> map = new HashMap<>();
- if (current().isPresent()) {
- map.putAll(current().get().contextMap);
+ if (getContext().isPresent()) {
+ map.putAll(getContext().get().contextMap);
}
map.remove(key);
new Instance(map).run(op);
@@ -220,8 +263,8 @@ public class ScopedContext {
if (obj != null) {
Renderable renderable = obj instanceof Renderable ? (Renderable) obj : new ObjectRenderable(obj);
Map<String, Renderable> map = new HashMap<>();
- if (current().isPresent()) {
- map.putAll(current().get().contextMap);
+ if (getContext().isPresent()) {
+ map.putAll(getContext().get().contextMap);
}
map.put(key, renderable);
if (executorService != null) {
@@ -233,8 +276,8 @@ public class ScopedContext {
}
} else {
Map<String, Renderable> map = new HashMap<>();
- if (current().isPresent()) {
- map.putAll(current().get().contextMap);
+ if (getContext().isPresent()) {
+ map.putAll(getContext().get().contextMap);
}
map.remove(key);
if (executorService != null) {
@@ -255,8 +298,8 @@ public class ScopedContext {
public static void runWhere(Map<String, ?> map, Runnable op) {
if (map != null && !map.isEmpty()) {
Map<String, Renderable> renderableMap = new HashMap<>();
- if (current().isPresent()) {
- renderableMap.putAll(current().get().contextMap);
+ if (getContext().isPresent()) {
+ renderableMap.putAll(getContext().get().contextMap);
}
map.forEach((key, value) -> {
renderableMap.put(key, value instanceof Renderable ? (Renderable) value : new ObjectRenderable(value));
@@ -277,15 +320,15 @@ public class ScopedContext {
if (obj != null) {
Renderable renderable = obj instanceof Renderable ? (Renderable) obj : new ObjectRenderable(obj);
Map<String, Renderable> map = new HashMap<>();
- if (current().isPresent()) {
- map.putAll(current().get().contextMap);
+ if (getContext().isPresent()) {
+ map.putAll(getContext().get().contextMap);
}
map.put(key, renderable);
return new Instance(map).call(op);
} else {
Map<String, Renderable> map = new HashMap<>();
- if (current().isPresent()) {
- map.putAll(current().get().contextMap);
+ if (getContext().isPresent()) {
+ map.putAll(getContext().get().contextMap);
}
map.remove(key);
return new Instance(map).call(op);
@@ -304,8 +347,8 @@ public class ScopedContext {
if (obj != null) {
Renderable renderable = obj instanceof Renderable ? (Renderable) obj : new ObjectRenderable(obj);
Map<String, Renderable> map = new HashMap<>();
- if (current().isPresent()) {
- map.putAll(current().get().contextMap);
+ if (getContext().isPresent()) {
+ map.putAll(getContext().get().contextMap);
}
map.put(key, renderable);
if (executorService != null) {
@@ -318,8 +361,8 @@ public class ScopedContext {
} else {
if (executorService != null) {
Map<String, Renderable> map = new HashMap<>();
- if (current().isPresent()) {
- map.putAll(current().get().contextMap);
+ if (getContext().isPresent()) {
+ map.putAll(getContext().get().contextMap);
}
map.remove(key);
return executorService.submit(new Caller<R>(
@@ -339,8 +382,8 @@ public class ScopedContext {
public static <R> R callWhere(Map<String, ?> map, Callable<R> op) throws Exception {
if (map != null && !map.isEmpty()) {
Map<String, Renderable> renderableMap = new HashMap<>();
- if (current().isPresent()) {
- renderableMap.putAll(current().get().contextMap);
+ if (getContext().isPresent()) {
+ renderableMap.putAll(getContext().get().contextMap);
}
map.forEach((key, value) -> {
renderableMap.put(key, value instanceof Renderable ? (Renderable) value : new ObjectRenderable(value));
@@ -351,14 +394,6 @@ public class ScopedContext {
}
}
- /**
- * Returns an Optional holding the active ScopedContext.Instance
- * @return an Optional containing the active ScopedContext, if there is one.
- */
- private static Optional<Instance> current() {
- return ScopedContextDataProvider.getContext();
- }
-
public static class Instance {
private final Instance parent;
@@ -500,11 +535,11 @@ public class ScopedContext {
if (contextStack != null) {
ThreadContext.setStack(contextStack);
}
- ScopedContextDataProvider.addScopedContext(scopedContext);
+ addScopedContext(scopedContext);
try {
op.run();
} finally {
- ScopedContextDataProvider.removeScopedContext();
+ removeScopedContext();
ThreadContext.clearAll();
}
}
@@ -551,11 +586,11 @@ public class ScopedContext {
if (contextStack != null) {
ThreadContext.setStack(contextStack);
}
- ScopedContextDataProvider.addScopedContext(scopedContext);
+ addScopedContext(scopedContext);
try {
return op.call();
} finally {
- ScopedContextDataProvider.removeScopedContext();
+ removeScopedContext();
ThreadContext.clearAll();
}
}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLogger.java b/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLogger.java
index d914f1c4c9..f5529f4258 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLogger.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLogger.java
@@ -23,9 +23,10 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
-import org.apache.logging.log4j.ContextData;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.ScopedContext;
+import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MessageFactory;
import org.apache.logging.log4j.spi.AbstractLogger;
@@ -295,8 +296,8 @@ public class SimpleLogger extends AbstractLogger {
}
sb.append(msg.getFormattedMessage());
if (showContextMap) {
- final Map<String, String> mdc = new HashMap<>(ContextData.size());
- ContextData.addAll(mdc);
+ final Map<String, String> mdc = new HashMap<>(ThreadContext.getImmutableContext());
+ ScopedContext.getContextMap().forEach((key, value) -> mdc.put(key, value.render()));
if (!mdc.isEmpty()) {
sb.append(SPACE);
sb.append(mdc.toString());
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/ContextDataProvider.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/ContextDataProvider.java
deleted file mode 100644
index d003e9c74f..0000000000
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/ContextDataProvider.java
+++ /dev/null
@@ -1,76 +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 java.util.Map;
-import org.apache.logging.log4j.util.StringMap;
-
-/**
- * Source of context data to be added to each log event.
- */
-public interface ContextDataProvider {
-
- /**
- * Returns the key for a value from the context data.
- * @param key the key to locate.
- * @return the value or null if it is not found.
- */
- default String get(String key) {
- return null;
- }
-
- /**
- * Returns a Map containing context data to be injected into the event or null if no context data is to be added.
- * <p>
- * Thread-safety note: The returned object can safely be passed off to another thread: future changes in the
- * underlying context data will not be reflected in the returned object.
- * </p>
- * @return A Map containing the context data or null.
- */
- Map<String, String> supplyContextData();
-
- /**
- * Returns the number of items in this context.
- * @return the number of items in the context.
- */
- default int size() {
- Map<String, String> contextMap = supplyContextData();
- return contextMap != null ? contextMap.size() : 0;
- }
-
- /**
- * Add all the keys in the current context to the provided Map.
- * @param map the StringMap to add the keys and values to.
- */
- default void addAll(Map<String, String> map) {
- Map<String, String> contextMap = supplyContextData();
- if (contextMap != null) {
- map.putAll(contextMap);
- }
- }
-
- /**
- * Add all the keys in the current context to the provided StringMap.
- * @param map the StringMap to add the keys and values to.
- */
- default void addAll(StringMap map) {
- Map<String, String> contextMap = supplyContextData();
- if (contextMap != null) {
- contextMap.forEach(map::putValue);
- }
- }
-}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/ScopedContextDataProvider.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/ScopedContextDataProvider.java
deleted file mode 100644
index f2a14c19d0..0000000000
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/ScopedContextDataProvider.java
+++ /dev/null
@@ -1,104 +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 aQute.bnd.annotation.Resolution;
-import aQute.bnd.annotation.spi.ServiceProvider;
-import java.util.ArrayDeque;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import org.apache.logging.log4j.ScopedContext;
-
-/**
- * ContextDataProvider for {@code Map<String, String>} data.
- * @since 2.24.0
- */
-@ServiceProvider(value = ContextDataProvider.class, resolution = Resolution.OPTIONAL)
-public class ScopedContextDataProvider implements ContextDataProvider {
-
- private static final ThreadLocal<Deque<ScopedContext.Instance>> scopedContext = new ThreadLocal<>();
-
- /**
- * Returns an immutable Map containing all the key/value pairs as Renderable objects.
- * @return An immutable copy of the Map at the current scope.
- */
- public static Optional<ScopedContext.Instance> getContext() {
- Deque<ScopedContext.Instance> stack = scopedContext.get();
- if (stack != null) {
- return Optional.of(stack.getFirst());
- }
- return Optional.empty();
- }
-
- /**
- * Add the ScopeContext.
- * @param context The ScopeContext.
- */
- public static void addScopedContext(ScopedContext.Instance context) {
- Deque<ScopedContext.Instance> stack = scopedContext.get();
- if (stack == null) {
- stack = new ArrayDeque<>();
- scopedContext.set(stack);
- }
- stack.addFirst(context);
- }
-
- /**
- * Remove the top ScopeContext.
- */
- public static void removeScopedContext() {
- Deque<ScopedContext.Instance> stack = scopedContext.get();
- if (stack != null) {
- if (!stack.isEmpty()) {
- stack.removeFirst();
- }
- if (stack.isEmpty()) {
- scopedContext.remove();
- }
- }
- }
-
- @Override
- public String get(String key) {
- return ScopedContext.getString(key);
- }
-
- @Override
- public Map<String, String> supplyContextData() {
- Map<String, ScopedContext.Renderable> contextMap = ScopedContext.getContextMap();
- if (!contextMap.isEmpty()) {
- Map<String, String> map = new HashMap<>();
- contextMap.forEach((key, value) -> map.put(key, value.render()));
- return map;
- } else {
- return Collections.emptyMap();
- }
- }
-
- @Override
- public int size() {
- return ScopedContext.size();
- }
-
- @Override
- public void addAll(Map<String, String> map) {
- ScopedContext.addAll(map);
- }
-}
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 5bb479f66c..f8b5b11402 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
@@ -19,7 +19,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.ContextData;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.ThreadContext;
@@ -31,6 +30,7 @@ import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.config.ReliabilityStrategy;
+import org.apache.logging.log4j.core.impl.ContextData;
import org.apache.logging.log4j.core.impl.ContextDataFactory;
import org.apache.logging.log4j.core.impl.ContextDataInjectorFactory;
import org.apache.logging.log4j.core.util.Clock;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java
index c965ce974d..ef79ca5b3e 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java
@@ -17,11 +17,11 @@
package org.apache.logging.log4j.core.async;
import com.lmax.disruptor.EventTranslator;
-import org.apache.logging.log4j.ContextData;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.ThreadContext.ContextStack;
import org.apache.logging.log4j.core.ContextDataInjector;
+import org.apache.logging.log4j.core.impl.ContextData;
import org.apache.logging.log4j.core.impl.ContextDataInjectorFactory;
import org.apache.logging.log4j.core.util.Clock;
import org.apache.logging.log4j.core.util.NanoClock;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/DynamicThresholdFilter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/DynamicThresholdFilter.java
index d2de85fe4d..b1f3c8f0d2 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/DynamicThresholdFilter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/DynamicThresholdFilter.java
@@ -19,7 +19,6 @@ package org.apache.logging.log4j.core.filter;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
-import org.apache.logging.log4j.ContextData;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.ThreadContext;
@@ -32,11 +31,12 @@ import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.core.impl.ContextData;
import org.apache.logging.log4j.core.impl.ContextDataFactory;
import org.apache.logging.log4j.core.impl.ContextDataInjectorFactory;
+import org.apache.logging.log4j.core.util.ContextDataProvider;
import org.apache.logging.log4j.core.util.KeyValuePair;
import org.apache.logging.log4j.message.Message;
-import org.apache.logging.log4j.spi.ContextDataProvider;
import org.apache.logging.log4j.util.PerformanceSensitive;
import org.apache.logging.log4j.util.StringMap;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/ThreadContextMapFilter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/ThreadContextMapFilter.java
index 7b27f88450..5116876555 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/ThreadContextMapFilter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/ThreadContextMapFilter.java
@@ -21,7 +21,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import org.apache.logging.log4j.ContextData;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.core.Filter;
@@ -33,6 +32,7 @@ import org.apache.logging.log4j.core.config.plugins.PluginAliases;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.core.impl.ContextData;
import org.apache.logging.log4j.core.util.KeyValuePair;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.util.IndexedReadOnlyStringMap;
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/ContextData.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextData.java
similarity index 96%
rename from log4j-api/src/main/java/org/apache/logging/log4j/ContextData.java
rename to log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextData.java
index 1b9445dcd8..df951a2e9f 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/ContextData.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextData.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.logging.log4j;
+package org.apache.logging.log4j.core.impl;
import java.util.ArrayList;
import java.util.Collection;
@@ -24,7 +24,8 @@ import java.util.Map;
import java.util.ServiceLoader;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicInteger;
-import org.apache.logging.log4j.spi.ContextDataProvider;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.util.ContextDataProvider;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.ServiceLoaderUtil;
import org.apache.logging.log4j.util.StringMap;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java
index bc02b085bb..aff4d5893c 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java
@@ -24,7 +24,6 @@ import java.rmi.MarshalledObject;
import java.util.List;
import java.util.Map;
import java.util.Objects;
-import org.apache.logging.log4j.ContextData;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.ThreadContext;
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 5a916d4003..5b41469aac 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
@@ -17,7 +17,6 @@
package org.apache.logging.log4j.core.impl;
import java.util.List;
-import org.apache.logging.log4j.ContextData;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.ThreadContext;
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/ThreadContextDataProvider.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ScopedContextDataProvider.java
similarity index 60%
rename from log4j-api/src/main/java/org/apache/logging/log4j/spi/ThreadContextDataProvider.java
rename to log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ScopedContextDataProvider.java
index d6e28f00d8..805c0979e7 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/ThreadContextDataProvider.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ScopedContextDataProvider.java
@@ -14,36 +14,47 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.logging.log4j.spi;
+package org.apache.logging.log4j.core.impl;
import aQute.bnd.annotation.Resolution;
import aQute.bnd.annotation.spi.ServiceProvider;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
-import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.ScopedContext;
+import org.apache.logging.log4j.core.util.ContextDataProvider;
/**
- * ContextDataProvider for ThreadContext data.
+ * ContextDataProvider for {@code Map<String, String>} data.
+ * @since 2.24.0
*/
@ServiceProvider(value = ContextDataProvider.class, resolution = Resolution.OPTIONAL)
-public class ThreadContextDataProvider implements ContextDataProvider {
+public class ScopedContextDataProvider implements ContextDataProvider {
@Override
public String get(String key) {
- return ThreadContext.get(key);
+ return ScopedContext.getString(key);
}
@Override
public Map<String, String> supplyContextData() {
- return ThreadContext.getImmutableContext();
+ Map<String, ScopedContext.Renderable> contextMap = ScopedContext.getContextMap();
+ if (!contextMap.isEmpty()) {
+ Map<String, String> map = new HashMap<>();
+ contextMap.forEach((key, value) -> map.put(key, value.render()));
+ return map;
+ } else {
+ return Collections.emptyMap();
+ }
}
@Override
public int size() {
- return ThreadContext.getContext().size();
+ return ScopedContext.size();
}
@Override
public void addAll(Map<String, String> map) {
- map.putAll(ThreadContext.getContext());
+ ScopedContext.addAll(map);
}
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java
index 0362984c5b..06b9bcd084 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java
@@ -21,7 +21,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import org.apache.logging.log4j.ContextData;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.ContextDataInjector;
@@ -236,9 +235,9 @@ public class ThreadContextDataInjector {
private static class ProviderIterator implements Iterator<ContextDataProvider> {
- private final Iterator<org.apache.logging.log4j.spi.ContextDataProvider> iter;
+ private final Iterator<ContextDataProvider> iter;
- public ProviderIterator(Iterator<org.apache.logging.log4j.spi.ContextDataProvider> iter) {
+ public ProviderIterator(Iterator<ContextDataProvider> iter) {
this.iter = iter;
}
@@ -249,7 +248,7 @@ public class ThreadContextDataInjector {
@Override
public ContextDataProvider next() {
- org.apache.logging.log4j.spi.ContextDataProvider next = iter.next();
+ ContextDataProvider next = iter.next();
if (next instanceof ContextDataProvider) {
return (ContextDataProvider) next;
} else if (next != null) {
@@ -261,9 +260,9 @@ public class ThreadContextDataInjector {
private static class ProviderWrapper implements ContextDataProvider {
- private final org.apache.logging.log4j.spi.ContextDataProvider provider;
+ private final ContextDataProvider provider;
- public ProviderWrapper(org.apache.logging.log4j.spi.ContextDataProvider provider) {
+ public ProviderWrapper(ContextDataProvider provider) {
this.provider = provider;
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataProvider.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataProvider.java
index a20216c755..949f8868a4 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataProvider.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataProvider.java
@@ -29,6 +29,11 @@ import org.apache.logging.log4j.util.StringMap;
@ServiceProvider(value = ContextDataProvider.class, resolution = Resolution.OPTIONAL)
public class ThreadContextDataProvider implements ContextDataProvider {
+ @Override
+ public String get(String key) {
+ return ThreadContext.get(key);
+ }
+
@Override
public Map<String, String> supplyContextData() {
return ThreadContext.getImmutableContext();
@@ -38,4 +43,14 @@ public class ThreadContextDataProvider implements ContextDataProvider {
public StringMap supplyStringMap() {
return ThreadContext.getThreadContextMap().getReadOnlyContextData();
}
+
+ @Override
+ public int size() {
+ return ThreadContext.getContext().size();
+ }
+
+ @Override
+ public void addAll(Map<String, String> map) {
+ map.putAll(ThreadContext.getContext());
+ }
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/ContextMapLookup.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/ContextMapLookup.java
index b24f1203a8..9b841bb396 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/ContextMapLookup.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/ContextMapLookup.java
@@ -16,12 +16,12 @@
*/
package org.apache.logging.log4j.core.lookup;
-import org.apache.logging.log4j.ContextData;
import org.apache.logging.log4j.ScopedContext;
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.config.plugins.Plugin;
+import org.apache.logging.log4j.core.impl.ContextData;
import org.apache.logging.log4j.core.impl.ContextDataInjectorFactory;
/**
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/osgi/Activator.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/osgi/Activator.java
index 17bde215ff..5f6f1da67c 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/osgi/Activator.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/osgi/Activator.java
@@ -18,14 +18,14 @@ package org.apache.logging.log4j.core.osgi;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicReference;
-import org.apache.logging.log4j.ContextData;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.plugins.util.PluginRegistry;
+import org.apache.logging.log4j.core.impl.ContextData;
import org.apache.logging.log4j.core.impl.Log4jProvider;
+import org.apache.logging.log4j.core.impl.ThreadContextDataProvider;
import org.apache.logging.log4j.core.util.Constants;
-import org.apache.logging.log4j.spi.ContextDataProvider;
-import org.apache.logging.log4j.spi.ThreadContextDataProvider;
+import org.apache.logging.log4j.core.util.ContextDataProvider;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.PropertiesUtil;
import org.apache.logging.log4j.util.ProviderActivator;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/ContextDataProvider.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/ContextDataProvider.java
index 086ac93981..6eeeeef9b5 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/ContextDataProvider.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/ContextDataProvider.java
@@ -22,11 +22,26 @@ import org.apache.logging.log4j.util.StringMap;
/**
* Source of context data to be added to each log event.
- * @deprecated Use ContextDataProvider from Log4j API from 2.24.0.
*/
-@Deprecated
-public interface ContextDataProvider extends org.apache.logging.log4j.spi.ContextDataProvider {
+public interface ContextDataProvider {
+ /**
+ * Returns the key for a value from the context data.
+ * @param key the key to locate.
+ * @return the value or null if it is not found.
+ */
+ default String get(String key) {
+ return null;
+ }
+
+ /**
+ * Returns a Map containing context data to be injected into the event or null if no context data is to be added.
+ * <p>
+ * Thread-safety note: The returned object can safely be passed off to another thread: future changes in the
+ * underlying context data will not be reflected in the returned object.
+ * </p>
+ * @return A Map containing the context data or null.
+ */
Map<String, String> supplyContextData();
/**
@@ -42,4 +57,35 @@ public interface ContextDataProvider extends org.apache.logging.log4j.spi.Contex
default StringMap supplyStringMap() {
return new JdkMapAdapterStringMap(supplyContextData(), true);
}
+
+ /**
+ * Returns the number of items in this context.
+ * @return the number of items in the context.
+ */
+ default int size() {
+ Map<String, String> contextMap = supplyContextData();
+ return contextMap != null ? contextMap.size() : 0;
+ }
+
+ /**
+ * Add all the keys in the current context to the provided Map.
+ * @param map the StringMap to add the keys and values to.
+ */
+ default void addAll(Map<String, String> map) {
+ Map<String, String> contextMap = supplyContextData();
+ if (contextMap != null) {
+ map.putAll(contextMap);
+ }
+ }
+
+ /**
+ * Add all the keys in the current context to the provided StringMap.
+ * @param map the StringMap to add the keys and values to.
+ */
+ default void addAll(StringMap map) {
+ Map<String, String> contextMap = supplyContextData();
+ if (contextMap != null) {
+ contextMap.forEach(map::putValue);
+ }
+ }
}