package com.vlkan.log4j2.logstash.layout.resolver;

import java.io.IOException;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.NullNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MultiformatMessage;

public class MessageJSONResolver implements TemplateResolver {

    private static final MessageJSONResolver INSTANCE = new MessageJSONResolver();
    private static final ObjectMapper MAPPER = new ObjectMapper();
    private static final String[] FORMATS = { "JSON" };

    private MessageJSONResolver() {
        // Do nothing.
    }

    public static MessageJSONResolver getInstance() {
        return INSTANCE;
    }

    @Override
    public String getName() {
        return "messageJson";
    }

    private JsonNode readTree(String message) {
        try {
            return MAPPER.readTree(message);
        } catch (IOException e) {
            ObjectNode node = MAPPER.createObjectNode();
            node.put("message", new TextNode(message));
            return node;
        }
    }

    @Override
    public JsonNode resolve(TemplateResolverContext context, LogEvent logEvent, String key) {
        Message msg = logEvent.getMessage();
        try {
            String message = ((MultiformatMessage) msg).getFormattedMessage(FORMATS);
            boolean messageExcluded = StringUtils.isEmpty(message) && context.isEmptyPropertyExclusionEnabled();
            return messageExcluded
                    ? NullNode.getInstance()
                    : readTree(message);
        } catch (ClassCastException e) {
            String message = msg.getFormattedMessage();
            boolean messageExcluded = StringUtils.isEmpty(message) && context.isEmptyPropertyExclusionEnabled();
            if (messageExcluded) {
                return NullNode.getInstance();
            }
            ObjectNode node = MAPPER.createObjectNode();
            node.put("message", new TextNode(message));
            return node;
        }
    }

}

@@ -1085,16 +1085,37 @@
  message
+, ObjectMapper mapper
 ) %7B%0A    
@@ -1143,22 +1143,22 @@
  return 
-MAPPER
+mapper
 .readTre
@@ -1225,38 +1225,38 @@
 jectNode node = 
-MAPPER
+mapper
 .createObjectNod
@@ -1269,34 +1269,34 @@
            node.
-pu
+se
 t(%22message%22, new
@@ -1834,32 +1834,59 @@
 readTree(message
+, context.getObjectMapper()
 );%0A        %7D cat
@@ -2208,22 +2208,41 @@
  node = 
-MAPPER
+context.getObjectMapper()
 .createO
@@ -2271,18 +2271,18 @@
    node.
-pu
+se
 t(%22messa

Use ObjectMapper from TemplateResolverContext in MessageJSONResolver