Add json object to log4j2 when is JSONLayout
This doesn't seem possible to do with the built-in JsonLayout. No matter what I try it just does a toString on the field rather than serializing it correctly.
One solution is to use the PatternLayout and format it like JSON.
log4j.appender.frontEndAudit.layout=org.apache.log4j.PatternLayoutlog4j.appender.frontEndAudit.layout.ConversionPattern={"timestamp": "%d{MM/dd/yyyy HH:mm:ss:SSSS}", "class": "%C", "file": "%F", "level" : "%5p", "line_number" : "%L", "logger_name": "frontEndAuditLog", "mdc": "ipAddress": "%X{ipAddress}", "requestId":"%X{requestId}", "sessionId":"%X{sessionId}"}, "message": %m, "method": "%M", "source_host":"%X{sourceHost}", "thread_name": "%t" }%n
This was for log4j1 but same concept would work for log4j2
It turns out LogstashLayout is a custom layout that does the trick.
- Write
"message": "${json:message:json}"
inLogstashJsonEventLayoutV1.json
file. - You have to log a Java object which implements the
MultiformatMessage
and return the JSON string ingetFromattedMessage
method. getMessageFormats()
method also must returnJSON
.
log4j-layout-template-json is available with version 2.14.0 and works flawlessly using MapMessage.Just add below gradle dependencies if using gradle
compile 'org.apache.logging.log4j:log4j-api:2.14.0'compile 'org.apache.logging.log4j:log4j-core:2.14.0'compile 'org.apache.logging.log4j:log4j-layout-template-json:2.14.0'compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.10.0'compile 'com.fasterxml.jackson.dataformat:jackson-databind:2.10.0'
log4j2.yaml looks like
Configuration: name: Default Appenders: Console: name: LogToConsole target: SYSTEM_OUT JsonTemplateLayout: eventTemplateUri: "classpath:LogstashJsonEventLayoutV1.json" Loggers: AsyncRoot: level: info additivity: false AppenderRef: - ref: LogToConsole
Then extend MapMessage for the object(MyMapMessage) you want to log and use
private static final org.apache.logging.log4j.Logger LOGGER = LogManager.getLogger(YourClass.class);LOGGER.error(myMapMessage.getData());