Structured Logging in Spring Boot 3.4 for Improved Logs
Comparison of structured logging with traditional logging, its uses, and advancements in Spring Framework 6.2 and Spring Boot 3.4.
Join the DZone community and get the full member experience.
Join For FreeStructured logging has become essential in modern applications to simplify the analysis of logs and improve observability. Spring Boot 3.4 extends the logging capabilities of Spring Framework 6.2. This can be easily configured log formats using application.yml or application.properties.
Before jumping into the details of the improvements, below is a brief on how structured logging has evolved, with comparisons between traditional logging and structured logging in Spring Framework 6.2 and Spring Boot 3.4.
Traditional Logging
Traditional logging relies on string concatenation or placeholders in log messages. This approach was simple but lacked the ability to structure data in a way that log aggregation tools could parse easily.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TraditionalLogging {
private static final Logger logger = LoggerFactory.getLogger(TraditionalLogging.class);
public static void main(String[] args) {
String userId = "12345";
String action = "login";
logger.info("User action: userId={}, action={}", userId, action);
}
}
Logged as below:
2025-01-10 10:00:00 INFO TraditionalLogging: User action: userId=12345, action=login
The above logging is hard to parse for automated systems, and manual effort is required to extract and analyze the fields, e.g., userId, and action.
Structured Logging
With structured logging, the logs are in machine-readable format (e.g., JSON), making it easier to process and analyze. With Spring Framework 6.2 and Spring Boot 3.4, we can use structured logging schemas like Elastic Common Schema (ECS) and Graylog Extended Log Format (GELF). This means structured logging generates logs as key-value pairs or JSON objects with minimal setup.
Add the below configuration to application.yml to ensure the logs are generated in ECS format.
logging:
ecs:
enabled: true
level:
root: INFO
Below is an example of logging structured information using SLF4J. Spring handles converting the log messages into a JSON format automatically.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class StructuredLoggingExample {
private static final Logger logger = LoggerFactory.getLogger(StructuredLoggingExample.class);
public static void main(String[] args) {
logger.info("User logged in", Map.of("userId", "12345", "action", "login"));
}
}
Output in ECS format (JSON):
{
"@timestamp": "2025-01-10T10:00:00Z",
"log.level": "INFO",
"message": "User logged in",
"userId": "12345",
"action": "login",
"logger": "StructuredLoggingExample",
"ecs.version": "1.2.0"
}
Advantages of Structured Logging
- Tools like Kibana, Grafana, and Splunk can directly ingest structured logs for alerts.
- Simplified debugging with the ability to search for specific log entries (e.g., filter by userId)
- Structured logging aligns with modern logging standards like ECS, which makes it easier to integrate with distributed systems.
Machine-Readability
Let's look at an example of how structured logging helps with machine readability.
Step 1: Structured logs are ingested into tools like:
- Elastic Search: Parses JSON logs and indexes fields for search.
- Grafana Loki: Stores structured logs for querying.
- Splunk: Processes and visualizes log data.
Step 2: Field-based indexing
Each field in a log entry (e.g., userId, action) is indexed separately. This allows tools to perform operations like:
- Filtering: Shows logs where userId = 12345
- Aggregating: Count login actions(action = login).
Finally, tools like Kibana or Grafana can create dashboards or alerts based on the log fields.
Log entries:
[
{"@timestamp": "2025-01-10T12:00:00Z", "action": "login", "userId": "123"},
{"@timestamp": "2025-01-10T12:01:00Z", "action": "logout", "userId": "123"},
{"@timestamp": "2025-01-10T12:02:00Z", "action": "login", "userId": "456"}
]
Filters in Kibana/Elasticsearch:
{
"query": {
"term": {
"userId": "12345"
}
}
}
Result: All logs where userId = 12345.
Aggregating logs:
{
"aggs": {
"login_count": {
"terms": {
"field": "action.keyword"
}
}
}
}
Output:
{
"aggregations": {
"login_count": {
"buckets": [
{"key": "login", "doc_count": 2},
{"key": "logout", "doc_count": 1}
]
}
}
}
Conclusion
Structured logging enables developers to create machine-readable logs that are easy to index, analyze, and manage with advanced observability tools. With the latest updates in Spring Framework 6.2 and Spring Boot 3.4, and with built-in support for widely used formats like ECS and GELF, adopting structured logging has become easier and more effective. Beyond improving readability, these improvements enhanced debugging, monitoring, and system analytics, making it an essential practice for building scalable distributed environments.
Opinions expressed by DZone contributors are their own.
Comments