Is your Java application drowning in cluttered, hard-to-read logs? Wading through unstructured logging data wastes valuable development time and buries important insights.
Imagine missing a critical bug because the relevant log entry was buried in a wall of unformatted text. Poor logging practices don't just slow you downβthey can mask serious issues that impact your application's stability.
There's a clearer path forward. This post will show you how to leverage JSON* formatting for your Java logs, bringing structure and clarity to your logging system while making application maintenance a breeze.
Prerequisite
Before diving into the implementation of the code to print JSON version of a Java object, you will need to add these mandatory dependencies in your pom.xml
:
<!--region SLF4J -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.16</version>
</dependency>
<!--endregion -->
<!--region Logback -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.16</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.5.16</version>
</dependency>
<!--endregion -->
The dependency above have been cut for brevity βοΈ. You can find the full pom.xml
content here on my GitHub.
How to Display Your Java Logs in JSON
Let take a case where you want to display the data of your existing POJO* :
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder
public class Person {
private String name;
private String email;
private String address;
private String phone;
private String dateOfBirth;
}
In a package named utils, you can add this configuration to transform a java object into JSON:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class JsonLogger {
private JsonLogger() {
throw new IllegalStateException("Utility class");
}
public static void info(String message, Object pojo) {
log.info("\n\n--- {} ---\n{} \n", message, pojoToJson(pojo));
}
private static String pojoToJson(Object pojo) {
try {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(pojo);
} catch (JsonProcessingException exception) {
throw new RuntimeException(exception);
}
}
}
Next in the src/main/resources
folder, add the following configuration in the file logback.xml
(you need to create it) to improve the logs formatting of your:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<Pattern>%d β %highlight(%-5level) [%thread] %cyan(%logger{15}): %msg%n</Pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
Finally, let write some code to test what we have configured:
import com.example.domain.Person;
import com.example.utils.JsonLogger;
import com.github.javafaker.Faker;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class App {
public static void main(String[] args) {
int count = 0;
List<Person> persons = new ArrayList<>();
while (count < 4) {
Faker faker = new Faker(Locale.CANADA);
Person person = Person.builder()
.name(faker.name().fullName())
.email(faker.internet().emailAddress().toLowerCase())
.phone(faker.phoneNumber().cellPhone())
.address(faker.address().fullAddress())
.dateOfBirth(new SimpleDateFormat("yyyy-MM-dd")
.format(faker.date().birthday()))
.build();
persons.add(person);
count++;
}
JsonLogger.info("Persons", persons);
}
}
πΏ Here is what your logs will look like!
The output:
2025-01-21 05:39:05,657 β INFO [main] c.e.u.JsonLogger:
--- Persons ---
[ {
"name" : "Forrest Heidenreich",
"email" : "rosalind.mckenzie@hotmail.com",
"address" : "Suite 252 978 Pollich Fields, Jonathonmouth, NB V6P6K2",
"phone" : "(090) 729-6520",
"dateOfBirth" : "1977-06-22"
}, {
"name" : "Daniela Crona",
"email" : "christinia.krajcik@yahoo.ca",
"address" : "Apt. 142 723 Delana Field, Hilllport, NB N1S 6P3",
"phone" : "(048) 038-1776",
"dateOfBirth" : "2002-12-02"
}, {
"name" : "Jamila Robel",
"email" : "marvin.strosin@gmail.com",
"address" : "Suite 182 7407 Beahan Pike, Gusikowskiland, PE A2P 4R2",
"phone" : "1-072-731-2887",
"dateOfBirth" : "2002-08-17"
}, {
"name" : "Mr. Lucio Crist",
"email" : "donald.ruecker@hotmail.com",
"address" : "848 Rob Extension, East Guillermoborough, BC X4E5P4",
"phone" : "1-798-437-6219",
"dateOfBirth" : "1997-12-19"
} ]
Best Practices for JSON Logging
Use Structured Logging: Ensure your log messages are clear and structured. Include context about the event, such as timestamps, user IDs, or transaction IDs, to provide more valuable insights.
Configure ObjectMapper Correctly: Customize the ObjectMapper
settings according to your requirements. For example, use modules like JavaTimeModule
to handle Java 8 date/time types effectively.
Log Levels: Use appropriate log levels (info, warn, error) to categorize logs effectively. This will help you differentiate between normal logs and critical issues.
Avoid Logging Sensitive Information: Ensure that no sensitive data (like passwords or personal information) is logged in any format. Following best practices for security helps in protecting your data.
Test Your Log Output: Regularly test the output of your logging mechanism to ensure logs are generated as expected. This can help catch issues early in the development process.
Consider Log Management Tools: Utilize log management tools or services that can ingest JSON logs directly. These tools can provide better indexing, searching, and visualization options.
π. Similar posts
How to Effectively Use the React useId Hook in Your Apps
16 Feb 2025
The Simple Method for Lifting State Up in React Effectively
16 Feb 2025
How to Master Dynamic Key Generation in React for Your Apps
12 Feb 2025