#335 Allow non-String values in MapResolver.
diff --git a/log4j-layout-json-template/src/main/java/org/apache/logging/log4j/layout/json/template/resolver/MapResolver.java b/log4j-layout-json-template/src/main/java/org/apache/logging/log4j/layout/json/template/resolver/MapResolver.java
index 622d8f3..21d125c 100644
--- a/log4j-layout-json-template/src/main/java/org/apache/logging/log4j/layout/json/template/resolver/MapResolver.java
+++ b/log4j-layout-json-template/src/main/java/org/apache/logging/log4j/layout/json/template/resolver/MapResolver.java
@@ -17,9 +17,10 @@
package org.apache.logging.log4j.layout.json.template.resolver;
import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.lookup.MapLookup;
import org.apache.logging.log4j.layout.json.template.util.JsonWriter;
import org.apache.logging.log4j.message.MapMessage;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.util.IndexedReadOnlyStringMap;
/**
* {@link MapMessage} field resolver.
@@ -27,7 +28,9 @@
* <h3>Configuration</h3>
*
* <pre>
- * config = "key" -> string
+ * config = key , [ stringified ]
+ * key = "key" -> string
+ * stringified = "stringified" -> boolean
* </pre>
*
* <h3>Examples</h3>
@@ -43,20 +46,20 @@
*/
final class MapResolver implements EventResolver {
- private static final MapLookup MAP_LOOKUP = new MapLookup();
-
private final String key;
+ private final boolean stringified;
+
static String getName() {
return "map";
}
MapResolver(final TemplateResolverConfig config) {
- final String key = config.getString("key");
+ this.key = config.getString("key");
+ this.stringified = config.getBoolean("stringified", false);
if (key == null) {
throw new IllegalArgumentException("missing key: " + config);
}
- this.key = key;
}
@Override
@@ -68,8 +71,21 @@
public void resolve(
final LogEvent logEvent,
final JsonWriter jsonWriter) {
- final String resolvedValue = MAP_LOOKUP.lookup(logEvent, key);
- jsonWriter.writeString(resolvedValue);
+ final Message message = logEvent.getMessage();
+ if (!(message instanceof MapMessage)) {
+ jsonWriter.writeNull();
+ } else {
+ @SuppressWarnings("unchecked")
+ MapMessage<?, Object> mapMessage = (MapMessage<?, Object>) message;
+ final IndexedReadOnlyStringMap map = mapMessage.getIndexedReadOnlyStringMap();
+ final Object value = map.getValue(key);
+ if (stringified) {
+ final String stringifiedValue = String.valueOf(value);
+ jsonWriter.writeString(stringifiedValue);
+ } else {
+ jsonWriter.writeValue(value);
+ }
+ }
}
}
diff --git a/log4j-layout-json-template/src/test/java/org/apache/logging/log4j/layout/json/template/JsonTemplateLayoutTest.java b/log4j-layout-json-template/src/test/java/org/apache/logging/log4j/layout/json/template/JsonTemplateLayoutTest.java
index 4419b58..80cd2b9 100644
--- a/log4j-layout-json-template/src/test/java/org/apache/logging/log4j/layout/json/template/JsonTemplateLayoutTest.java
+++ b/log4j-layout-json-template/src/test/java/org/apache/logging/log4j/layout/json/template/JsonTemplateLayoutTest.java
@@ -322,6 +322,47 @@
}
@Test
+ public void test_MapMessage_keyed_access() {
+
+ // Create the event template.
+ final String key = "list";
+ final String eventTemplate = writeJson(Map(
+ "typedValue", Map(
+ "$resolver", "map",
+ "key", key),
+ "stringifiedValue", Map(
+ "$resolver", "map",
+ "key", key,
+ "stringified", true)));
+
+ // Create the layout.
+ final JsonTemplateLayout layout = JsonTemplateLayout
+ .newBuilder()
+ .setConfiguration(CONFIGURATION)
+ .setEventTemplate(eventTemplate)
+ .build();
+
+ // Create the log event with a MapMessage.
+ final List<Integer> value = Arrays.asList(1, 2);
+ final StringMapMessage mapMessage = new StringMapMessage()
+ .with(key, value);
+ final LogEvent logEvent = Log4jLogEvent
+ .newBuilder()
+ .setLoggerName(LOGGER_NAME)
+ .setLevel(Level.INFO)
+ .setMessage(mapMessage)
+ .setTimeMillis(System.currentTimeMillis())
+ .build();
+
+ // Check the serialized event.
+ usingSerializedLogEventAccessor(layout, logEvent, accessor -> {
+ assertThat(accessor.getObject("typedValue")).isEqualTo(value);
+ assertThat(accessor.getString("stringifiedValue")).isEqualTo(String.valueOf(value));
+ });
+
+ }
+
+ @Test
public void test_message_fallbackKey() {
// Create the event template.
diff --git a/src/site/asciidoc/manual/json-template-layout.adoc b/src/site/asciidoc/manual/json-template-layout.adoc
index 9b819d1..97a8898 100644
--- a/src/site/asciidoc/manual/json-template-layout.adoc
+++ b/src/site/asciidoc/manual/json-template-layout.adoc
@@ -593,10 +593,13 @@
a|
[source]
----
-config = "key" -> string
+config = key , [ stringified ]
+key = "key" -> string
+stringified = "stringified" -> boolean
----
-| performs link:lookups.html#MapLookup[Map Lookup] for the given `key`
-| none
+| resolves the given `key` of ``MapMessage``s
+| `stringified` flag translates to `String.valueOf(value)`, hence mind
+ not-`String`-typed values.
a|
Resolve the `userRole` field of the message: