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 Generate a Git SSH Key on Your Mac and Add it to GitHub
31 Aug 2025
Why Are My React Components Re-rendering Too Much?
26 Jul 2025
How to Use Custom Hooks in React
01 Jun 2025