Backend Development 8 min read

Structured Logging in Spring Boot 3.4: JSON, ECS, and Custom Formats

Spring Boot 3.4 adds built‑in support for structured logging with ready‑made JSON formats such as Elastic Common Schema, lets you configure console or file outputs, enrich logs via MDC or the fluent API, and enables custom formatters—including a JsonWriter‑based example—for fully tailored, machine‑readable log entries.

Java Tech Enthusiast
Java Tech Enthusiast
Java Tech Enthusiast
Structured Logging in Spring Boot 3.4: JSON, ECS, and Custom Formats

Log recording is a core part of application troubleshooting and system observability. Structured logging outputs logs in a predefined, machine‑readable format (commonly JSON), enabling powerful search, filtering, and analysis.

Spring Boot 3.4 provides out‑of‑the‑box support for structured logging. It includes built‑in formats such as Elastic Common Schema (ECS) and Logstash, and can be extended for custom needs.

Enable Structured Logging on the Console

Add the following property to application.properties to output console logs in ECS format:

logging.structured.format.console=ecs

When the application starts, logs appear as JSON, e.g.:

{"@timestamp":"2024-07-30T08:41:10.561295200Z","log.level":"INFO","process.pid":67455,"process.thread.name":"main","service.name":"structured-logging-demo","log.logger":"com.example.structured_logging_demo.StructuredLoggingDemoApplication","message":"Started StructuredLoggingDemoApplication in 0.329 seconds (process running for 0.486)","ecs.version":"8.11"}

Write Structured Logs to a File

Configure file output by adding to application.properties :

logging.structured.format.file=ecs
logging.file.name=log.json

The console shows human‑readable logs, while log.json contains the structured JSON entries.

Adding Extra Fields

Use MDC to attach additional data (e.g., userId) to each log event:

@Component
class MyLogger implements CommandLineRunner {
private static final Logger LOGGER = LoggerFactory.getLogger(MyLogger.class);
@Override
public void run(String... args) {
MDC.put("userId", "1");
LOGGER.info("Hello structured logging!");
MDC.remove("userId");
}
}

The resulting JSON includes the extra field:

{..., "message":"Hello structured logging!", "userId":"1", ...}

Alternatively, use the fluent API without MDC:

@Component
class MyLogger implements CommandLineRunner {
private static final Logger LOGGER = LoggerFactory.getLogger(MyLogger.class);
@Override
public void run(String... args) {
LOGGER.atInfo().setMessage("Hello structured logging!")
.addKeyValue("userId", "1")
.log();
}
}

Custom Log Formatter

Create a class implementing StructuredLogFormatter<ILoggingEvent> and register it in application.properties :

class MyStructuredLoggingFormatter implements StructuredLogFormatter<ILoggingEvent> {
@Override
public String format(ILoggingEvent event) {
return "time=" + event.getTimeStamp() + " level=" + event.getLevel() + " message=" + event.getMessage() + "\n";
}
}
logging.structured.format.console=com.example.structured_logging_demo.MyStructuredLoggingFormatter

Running the app now prints logs like:

time=1722330118045 level=INFO message=Hello structured logging!

For JSON output, Spring Boot 3.4 introduces JsonWriter :

class MyStructuredLoggingFormatter implements StructuredLogFormatter<ILoggingEvent> {
private final JsonWriter<ILoggingEvent> writer = JsonWriter.<ILoggingEvent>of(members -> {
members.add("time", e -> e.getInstant());
members.add("level", e -> e.getLevel());
members.add("thread", e -> e.getThreadName());
members.add("message", e -> e.getFormattedMessage());
members.add("application").usingMembers(app -> {
app.add("name", "StructuredLoggingDemo");
app.add("version", "1.0.0-SNAPSHOT");
});
members.add("node").usingMembers(node -> {
node.add("hostname", "node-1");
node.add("ip", "10.0.0.7");
});
}).withNewLineAtEnd();
@Override
public String format(ILoggingEvent event) {
return writer.writeToString(event);
}
}
logging.structured.format.console=com.example.structured_logging_demo.MyStructuredLoggingFormatter

The generated log looks like:

{"time":"2024-07-30T09:14:49.377308361Z","level":"INFO","thread":"main","message":"Hello structured logging!","application":{"name":"StructuredLoggingDemo","version":"1.0.0-SNAPSHOT"},"node":{"hostname":"node-1","ip":"10.0.0.7"}}

Note: Spring Boot 3.0/3.1 lifecycle has ended; upgrade to the latest version.

JavaJSONloggingSpring BootECSstructured logging
Java Tech Enthusiast
Written by

Java Tech Enthusiast

Sharing computer programming language knowledge, focusing on Java fundamentals, data structures, related tools, Spring Cloud, IntelliJ IDEA... Book giveaways, red‑packet rewards and other perks await!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.