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 ba5e77835dfdba885277fa4f3dc099f93736eb21
Author: Ralph Goers <[email protected]>
AuthorDate: Fri Mar 29 07:49:49 2024 -0700

    ResourceLogger uses ScopedContext
---
 .../org/apache/logging/log4j/test/TestLogger.java  | 10 +++++--
 .../apache/logging/log4j/ResourceLoggerTest.java   |  4 +--
 .../org/apache/logging/log4j/ResourceLogger.java   | 35 +++++++++++++++++-----
 .../org/apache/logging/log4j/ScopedContext.java    | 10 +++----
 .../apache/logging/log4j/ResourceLoggerTest.java   | 30 ++++++++++---------
 src/site/asciidoc/manual/resource-logger.adoc      |  7 ++---
 6 files changed, 60 insertions(+), 36 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 ff9c6f01c0..d90258e5a2 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
@@ -20,10 +20,12 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 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;
@@ -80,14 +82,18 @@ public class TestLogger extends AbstractLogger {
             sb.append(' ');
         }
         sb.append(message.getFormattedMessage());
-        final Map<String, String> mdc = ThreadContext.getImmutableContext();
+        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);
             sb.append(' ');
         }
         if (message instanceof ParameterizedMapMessage) {
-            sb.append(" Resource data: ");
+            sb.append(" Map data: ");
             sb.append(((ParameterizedMapMessage) 
message).getData().toString());
             sb.append(' ');
         }
diff --git 
a/log4j-api-test/src/test/java/org/apache/logging/log4j/ResourceLoggerTest.java 
b/log4j-api-test/src/test/java/org/apache/logging/log4j/ResourceLoggerTest.java
index f706b0a7dd..c9a8ae691e 100644
--- 
a/log4j-api-test/src/test/java/org/apache/logging/log4j/ResourceLoggerTest.java
+++ 
b/log4j-api-test/src/test/java/org/apache/logging/log4j/ResourceLoggerTest.java
@@ -78,7 +78,7 @@ public class ResourceLoggerTest {
         events.clear();
     }
 
-    private static class MapSupplier implements Supplier<Map<String, String>> {
+    private static class MapSupplier implements Supplier<Map<String, ?>> {
 
         private final Connection connection;
 
@@ -87,7 +87,7 @@ public class ResourceLoggerTest {
         }
 
         @Override
-        public Map<String, String> get() {
+        public Map<String, ?> get() {
             Map<String, String> map = new HashMap<>();
             map.put("Name", connection.name);
             map.put("Type", connection.type);
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/ResourceLogger.java 
b/log4j-api/src/main/java/org/apache/logging/log4j/ResourceLogger.java
index bac943751c..6df94e9334 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/ResourceLogger.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/ResourceLogger.java
@@ -20,7 +20,7 @@ import java.util.Collections;
 import java.util.Map;
 import java.util.function.Supplier;
 import org.apache.logging.log4j.message.Message;
-import org.apache.logging.log4j.message.ParameterizedMapMessageFactory;
+import org.apache.logging.log4j.message.MessageFactory;
 import org.apache.logging.log4j.spi.AbstractLogger;
 import org.apache.logging.log4j.spi.ExtendedLogger;
 import org.apache.logging.log4j.status.StatusLogger;
@@ -40,6 +40,7 @@ import org.apache.logging.log4j.util.Strings;
 public final class ResourceLogger extends AbstractLogger {
     private static final long serialVersionUID = -5837924138744974513L;
     private final ExtendedLogger logger;
+    private final Supplier<Map<String, ?>> supplier;
 
     public static ResourceLoggerBuilder newBuilder() {
         return new ResourceLoggerBuilder();
@@ -49,9 +50,11 @@ public final class ResourceLogger extends AbstractLogger {
      * Pass our MessageFactory with its Supplier to AbstractLogger. This will 
be used to create
      * the Messages prior to them being passed to the "real" Logger.
      */
-    private ResourceLogger(final ExtendedLogger logger, final 
Supplier<Map<String, String>> supplier) {
-        super(logger.getName(), new ParameterizedMapMessageFactory(supplier));
+    private ResourceLogger(
+            final ExtendedLogger logger, final Supplier<Map<String, ?>> 
supplier, MessageFactory messageFactory) {
+        super(logger.getName(), messageFactory);
         this.logger = logger;
+        this.supplier = supplier;
     }
 
     @Override
@@ -197,7 +200,11 @@ public final class ResourceLogger extends AbstractLogger {
 
     @Override
     public void logMessage(String fqcn, Level level, Marker marker, Message 
message, Throwable t) {
-        logger.logMessage(fqcn, level, marker, message, t);
+        if (supplier != null) {
+            ScopedContext.runWhere(supplier.get(), () -> 
logger.logMessage(fqcn, level, marker, message, t));
+        } else {
+            logger.logMessage(fqcn, level, marker, message, t);
+        }
     }
 
     /**
@@ -207,7 +214,8 @@ public final class ResourceLogger extends AbstractLogger {
         private static final Logger LOGGER = StatusLogger.getLogger();
         private ExtendedLogger logger;
         private String name;
-        private Supplier<Map<String, String>> supplier;
+        private Supplier<Map<String, ?>> supplier;
+        private MessageFactory messageFactory;
 
         /**
          * Create the builder.
@@ -252,11 +260,22 @@ public final class ResourceLogger extends AbstractLogger {
          * @param supplier the method that provides the Map of resource data 
to include in logs.
          * @return the ResourceLoggerBuilder.
          */
-        public ResourceLoggerBuilder withSupplier(Supplier<Map<String, 
String>> supplier) {
+        public ResourceLoggerBuilder withSupplier(Supplier<Map<String, ?>> 
supplier) {
             this.supplier = supplier;
             return this;
         }
 
+        /**
+         * Adds a MessageFactory.
+         * @param messageFactory the MessageFactory to use to build messages. 
If a MessageFactory
+         * is not specified the default MessageFactory will be used.
+         * @return the ResourceLoggerBuilder.
+         */
+        public ResourceLoggerBuilder withMessageFactory(MessageFactory 
messageFactory) {
+            this.messageFactory = messageFactory;
+            return this;
+        }
+
         /**
          * Construct the ResourceLogger.
          * @return the ResourceLogger.
@@ -269,8 +288,8 @@ public final class ResourceLogger extends AbstractLogger {
                 }
                 this.logger = (ExtendedLogger) LogManager.getLogger(name);
             }
-            Supplier<Map<String, String>> mapSupplier = this.supplier != null 
? this.supplier : Collections::emptyMap;
-            return new ResourceLogger(logger, mapSupplier);
+            Supplier<Map<String, ?>> mapSupplier = this.supplier != null ? 
this.supplier : Collections::emptyMap;
+            return new ResourceLogger(logger, mapSupplier, messageFactory);
         }
     }
 }
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 0806f820c5..b105e3be1d 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
@@ -124,7 +124,7 @@ public class ScopedContext {
      * @param map the Map.
      * @return the ScopedContext Instance constructed.
      */
-    public static Instance where(Map<String, Object> map) {
+    public static Instance where(Map<String, ?> map) {
         if (map != null && !map.isEmpty()) {
             Map<String, Renderable> renderableMap = new HashMap<>();
             if (current().isPresent()) {
@@ -212,11 +212,11 @@ public class ScopedContext {
      * @param map the Map.
      * @param op the Runnable to call.
      */
-    public static void runWhere(Map<String, Object> map, Runnable op) {
+    public static void runWhere(Map<String, ?> map, Runnable op) {
         if (map != null && !map.isEmpty()) {
             Map<String, Renderable> renderableMap = new HashMap<>();
             if (current().isPresent()) {
-                map.putAll(current().get().contextMap);
+                renderableMap.putAll(current().get().contextMap);
             }
             map.forEach((key, value) -> {
                 renderableMap.put(key, value instanceof Renderable ? 
(Renderable) value : new ObjectRenderable(value));
@@ -296,11 +296,11 @@ public class ScopedContext {
      * @param map the Map.
      * @param op the Runnable to call.
      */
-    public static <R> R callWhere(Map<String, Object> map, Callable<R> op) 
throws Exception {
+    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()) {
-                map.putAll(current().get().contextMap);
+                renderableMap.putAll(current().get().contextMap);
             }
             map.forEach((key, value) -> {
                 renderableMap.put(key, value instanceof Renderable ? 
(Renderable) value : new ObjectRenderable(value));
diff --git 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/ResourceLoggerTest.java
 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/ResourceLoggerTest.java
index b62784b4c7..a66f4459ac 100644
--- 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/ResourceLoggerTest.java
+++ 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/ResourceLoggerTest.java
@@ -18,9 +18,10 @@ package org.apache.logging.log4j.message;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.aMapWithSize;
+import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.hasSize;
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 import java.util.HashMap;
 import java.util.List;
@@ -33,6 +34,7 @@ import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.test.appender.ListAppender;
 import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
 import org.apache.logging.log4j.core.test.junit.Named;
+import org.apache.logging.log4j.util.ReadOnlyStringMap;
 import org.junit.jupiter.api.Test;
 
 /**
@@ -59,14 +61,14 @@ public class ResourceLoggerTest {
         logger.debug("Hello, {}", "World");
         List<LogEvent> events = app.getEvents();
         assertThat(events, hasSize(1));
-        Message message = events.get(0).getMessage();
-        assertTrue(message instanceof ParameterizedMapMessage);
-        Map<String, String> data = ((ParameterizedMapMessage) 
message).getData();
-        assertThat(data, aMapWithSize(3));
+        ReadOnlyStringMap map = events.get(0).getContextData();
+        assertNotNull(map);
+        Map<String, String> data = map.toMap();
+        assertThat(data.size(), equalTo(3));
         assertEquals("Test", data.get("Name"));
         assertEquals("dummy", data.get("Type"));
         assertEquals("1", data.get("Count"));
-        assertEquals("Hello, World", message.getFormattedMessage());
+        assertEquals("Hello, World", 
events.get(0).getMessage().getFormattedMessage());
         assertEquals(this.getClass().getName(), events.get(0).getLoggerName());
         assertEquals(this.getClass().getName(), 
events.get(0).getSource().getClassName());
         app.clear();
@@ -74,9 +76,9 @@ public class ResourceLoggerTest {
         logger.debug("Used the connection");
         events = app.getEvents();
         assertThat(events, hasSize(1));
-        message = events.get(0).getMessage();
-        assertTrue(message instanceof ParameterizedMapMessage);
-        data = ((ParameterizedMapMessage) message).getData();
+        map = events.get(0).getContextData();
+        assertNotNull(map);
+        data = map.toMap();
         assertThat(data, aMapWithSize(3));
         assertEquals("2", data.get("Count"));
         app.clear();
@@ -87,20 +89,20 @@ public class ResourceLoggerTest {
         logger.debug("Connection: {}", "NewConnection");
         events = app.getEvents();
         assertThat(events, hasSize(1));
-        message = events.get(0).getMessage();
-        assertTrue(message instanceof ParameterizedMapMessage);
-        data = ((ParameterizedMapMessage) message).getData();
+        map = events.get(0).getContextData();
+        assertNotNull(map);
+        data = map.toMap();
         assertThat(data, aMapWithSize(3));
         assertEquals("NewConnection", data.get("Name"));
         assertEquals("fiber", data.get("Type"));
         assertEquals("1", data.get("Count"));
-        assertEquals("Connection: NewConnection", 
message.getFormattedMessage());
+        assertEquals("Connection: NewConnection", 
events.get(0).getMessage().getFormattedMessage());
         assertEquals(this.getClass().getName(), events.get(0).getLoggerName());
         assertEquals(this.getClass().getName(), 
events.get(0).getSource().getClassName());
         app.clear();
     }
 
-    private static class MapSupplier implements Supplier<Map<String, String>> {
+    private static class MapSupplier implements Supplier<Map<String, ?>> {
 
         private final Connection connection;
 
diff --git a/src/site/asciidoc/manual/resource-logger.adoc 
b/src/site/asciidoc/manual/resource-logger.adoc
index 615e6f6e92..289b69a344 100644
--- a/src/site/asciidoc/manual/resource-logger.adoc
+++ b/src/site/asciidoc/manual/resource-logger.adoc
@@ -78,7 +78,7 @@ inside the Resource Logger.
 With the PatternLayout configured with a pattern of
 
 ----
-%K %m%n
+%X %m%n
 ----
 
 and a loginId of testUser and a role of Admin, after a successful login would 
result in a log message of
@@ -87,7 +87,4 @@ and a loginId of testUser and a role of Admin, after a 
successful login would re
 {LoginId=testUser, Role=Admin, Count=1} Login succeeded
 ----
 
-ResourceLoggers always create ParameterizedMapMessages for every log event.  A 
ParameterizedMapMessage is similar to a ParameterizedMessage but with a Map 
attached. Since ParameterizedMapMessage is a MapMessage all the tooling 
available
-in Layouts, Filters, and Lookups may be used.
-
-The supplier configured on the ResourceLogger is called when generating every 
log event. This allows values, such as counters, to be updated and the log 
event will contain the actual value at the time the event was logged.
+Every logging call is wrapped in a ScopedContext and populated by the supplier 
configured on the ResourceLogger, which is called when generating every log 
event. This allows values, such as counters, to be updated and the log event 
will contain the actual value at the time the event was logged.

Reply via email to