Master Structured Logging in Spring Boot 3.4 with ECS and Custom Formats
This guide explains why structured logging is essential for observability, shows how Spring Boot 3.4 adds out‑of‑the‑box support for Elastic Common Schema and Logstash formats, and provides step‑by‑step configurations and code examples for console output, file logging, custom fields, and custom formatters.
Logging is a cornerstone of troubleshooting and observability, alongside metrics and tracing. Structured logging writes logs in a well‑defined, machine‑readable format—most commonly JSON—so they can be ingested by log management systems for powerful search and analysis.
Spring Boot 3.4 introduces built‑in support for structured logging, offering two ready‑made formats: Elastic Common Schema (ECS) and Logstash . Developers can also extend the system with custom formats.
1. Quick Start
Because the 3.4 release is still a milestone (3.4.0‑M3), you need to use the milestone repository to fetch the parent pom:
<code><parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.0-M3</version>
<relativePath/>
</parent></code>Configure the logger to use the ECS format for console output:
<code>logging:
structured:
format:
console: ecs</code>The console will now emit JSON‑formatted logs.
2. Writing to a File
To keep human‑readable logs on the console while writing structured JSON logs to a file, add the following configuration and disable the default console ECS formatter:
<code>logging:
file:
name: json.log
structured:
format:
file: ecs</code>This creates json.log in the project root with the same JSON structure as the console output.
3. Adding Custom Fields
Using MDC (Mapped Diagnostic Context) you can inject additional data, such as a user ID, into each log event:
<code>@Component
public class PackCustomLogger implements CommandLineRunner {
private static final Logger LOGGER = LoggerFactory.getLogger(PackCustomLogger.class);
@Override
public void run(String... args) {
MDC.put("userId", "666");
LOGGER.info("Hello structured logging, custom field!");
MDC.remove("userId");
}
}</code>The resulting JSON contains a userId field.
Alternatively, the fluent API can add fields without MDC:
<code>LOGGER.atInfo()
.setMessage("Hello structured logging, by fluent!")
.addKeyValue("userId", "888")
.log();</code>4. Enriching Logs with Service Metadata
ECS defines standard fields for service name, version, environment, and node name. Set them in application.yml :
<code>logging:
structured:
ecs:
service:
name: my-app
version: 1.0.0
node-name: app-node-01</code>The generated JSON now includes service.name , service.version , and service.node.name , which can be filtered in Elasticsearch/Kibana.
5. Custom StructuredLogFormatter
To define a completely custom JSON structure, implement the StructuredLogFormatter interface:
<code>public class PackStructuredLoggingFormatter implements StructuredLogFormatter<ILoggingEvent> {
private final JsonWriter<ILoggingEvent> writer = JsonWriter.<ILoggingEvent>of(members -> {
members.add("time", e -> DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
.format(e.getInstant().atZone(ZoneId.systemDefault()).toLocalDateTime()));
members.add("level", ILoggingEvent::getLevel);
members.add("thread", ILoggingEvent::getThreadName);
members.add("message", ILoggingEvent::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", "pack-node-1");
node.add("ip", "127.0.0.1");
});
}).withNewLineAtEnd();
@Override
public String format(ILoggingEvent event) {
return writer.writeToString(event);
}
}</code>Reference the formatter in the configuration:
<code>logging:
structured:
format:
console: com.pack.PackStructuredLoggingFormatter</code>The console now prints JSON that includes the custom application and node objects.
Conclusion
Spring Boot’s built‑in structured logging makes it straightforward to emit JSON logs compatible with Elasticsearch, enabling powerful filtering and visualization through Kibana.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.