Log4j 2 JSON pattern layout + Logging JSON payload Log4j 2 JSON pattern layout + Logging JSON payload json json

Log4j 2 JSON pattern layout + Logging JSON payload


To be able to log JSON unescaped, you should use Log4j2 logger instead of Slf4j. This feature is available starting from Log4j 2.11.

Log4j logger is able to log ObjectMessage, which will be converted to a nested JSON.ObjectMessage constructor accepts Map, so JSONObject have to be converted to map (e.g. with help of Jackson ObjectMapper).

In the layout configuration add objectMessageAsJsonObject="true":

<JSONLayout complete="false" compact="true" eventEol="true" objectMessageAsJsonObject="true" />

Full working example:

import com.fasterxml.jackson.core.type.TypeReference;import com.fasterxml.jackson.databind.ObjectMapper;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import org.apache.logging.log4j.message.ObjectMessage;import org.json.JSONObject;import java.io.IOException;import java.util.HashMap;import java.util.Map;public class test {    public static void main(String[] args) throws IOException {        HashMap<Object, Object> map = new HashMap<>();        map.put("foo", "bar");        JSONObject jsonObject = new JSONObject(map);        Map<String, Object> newMap = new ObjectMapper().readValue(jsonObject.toString(), new TypeReference<Map<String, Object>>() {});        Logger log4jLogger = LogManager.getLogger("mainLogger");        log4jLogger.info(new ObjectMessage(newMap));    }}

This will produce:

{"thread":"main","level":"INFO","loggerName":"mainLogger","message":{"foo":"bar"},"endOfBatch":false,"loggerFqcn":"org.apache.logging.log4j.spi.AbstractLogger","instant":{"epochSecond":1548434758,"nanoOfSecond":572000000},"threadId":1,"threadPriority":5}