🪵 Spring Boot: Structured Logging Without Writing a Single Encoder
Your log aggregator wants JSON. Your application prints a friendly sentence with a timestamp, a thread name and a few dashes.
For years the fix was a hand-rolled Logback encoder, or an extra dependency, or a regex in the log pipeline that everyone was afraid to touch.
Since Spring Boot 3.4, there is a shorter route.
The discovery: It’s one property
Spring Boot 3.4 introduced built-in structured logging. It supports three JSON formats out of the box: Elastic Common Schema (ecs), Graylog Extended Log Format (gelf) and Logstash (logstash).
spring:
application:
name: orderslogging:
structured:
format:
console: ecs# file: ecs # same idea for file output
That’s it. Console output is now one JSON object per line instead of the classic pattern. With ecs, the service.name field defaults to spring.application.name, so setting the application name is worth the extra line.
Adding your own fields
The JSON includes every key-value pair in the MDC. You can also attach values per log statement with SLF4J’s fluent API:
The reference documentation states that these key-value pairs end up in the logged JSON object. Your log search can now filter by orderId instead of grepping a sentence.
If the default field names don’t match what your ingestion system expects, the logging.structured.json.* properties let you include, exclude, rename and add members. For long stack traces, logging.structured.json.stacktrace.* lets you cap their length or print the root cause first.
The important nuance: Custom log configuration
If you ship your own logback-spring.xml, the property alone won’t do anything for you. The documentation says to update your configuration to respect CONSOLE_LOG_STRUCTURED_FORMAT and FILE_LOG_STRUCTURED_FORMAT, replacing your encoder with Spring Boot’s StructuredLogEncoder:
Also remember that this is a Spring Boot 3.4+ feature. On an older version, the property simply isn’t there.
The takeaway ☕
If your logs end up in a platform that prefers JSON, try logging.structured.format.console before reaching for a custom encoder. Pick the format your platform already understands, set the application name, and move your “context” out of the message string and into key-value pairs.
Your future self, squinting at a dashboard at 2 a.m., will appreciate fields over sentences.