We had a requirement where we need to log our message in json for some report generation that we are doing out of our services log
Our current logging is based on slf4j +log4j2. We enquired what is the best and quick option we have
We decided to go with log4j2 json layout reason it have inbuilt support to write json i.e ObjectMessage is serialized as JSON object to the “message” field of the output log. Defaults to false.
Lets get started
Pom.xml changes
Below are the pom change and I am using spring boot 2.2.6.RELEASE
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
Checklist
objectMessageAsJsonObject support is available for Log4J2 version. 2.11.0 onwards
Log4j2.xml
SampleController class
package com.medium.json.controller;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.Calendar;
import java.util.Map;
@RestController
public class SampleController {
private static Logger loggerWithJsonLayout = LogManager.getLogger(SampleController.class.getName());
@PostMapping(path = "/hello", produces ="application/json" , consumes = "application/json")
public ResponseEntity<String> hello(@RequestBody Map<String, Object> requestBody){
loggerWithJsonLayout.info(requestBody);
loggerWithJsonLayout.info(createEmployeePojoMessage());
return ResponseEntity.ok("request submitted");
}
private EmployeePojo createEmployeePojoMessage() {
return new EmployeePojo("hello", 12345);
}
}
Employee pojo
package com.db.json.controller;
import java.util.Date;
public class EmployeePojo {
private String name;
private int employeeId;
public EmployeePojo(String name, int employeeId) {
this.name = name;
this.employeeId = employeeId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getEmployeeId() {
return employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
}
Sample Log
{“thread”:”http-nio-8080-exec-2",”level”:”INFO”,”loggerName”:”com.medium.json.controller.SampleController”,”message”:{“name”:”hello”,”employeeId”:12345,”endOfBatch”:false,”loggerFqcn”:”org.apache.logging.log4j.spi.AbstractLogger”,”instant”:{“epochSecond”:1616253931,”nanoOfSecond”:746000000},”threadId”:20,”threadPriority”:5,”timeMillis”:”2021–03–20T20:55:31.746+0530",”service”:”subscription”}
Reference
https://logging.apache.org/log4j/2.x/manual/layouts.html#JSONLayout