Spring Boot Logs in OpenShift
Learn how Spring Boot logging works in OpenShift. Understand Logback configuration, stdout logging, JSON logging, correlation IDs, MDC, distributed tracing, centralized logging, and enterprise logging best practices.
Introduction
Logs are one of the most valuable tools for understanding how an application behaves in production.
When a Spring Boot application runs on OpenShift, developers need answers to questions such as:
- Why did a payment fail?
- Which user triggered the request?
- Which microservice returned an error?
- How long did the request take?
- Which database query failed?
Unlike traditional servers, OpenShift Pods are ephemeral.
This means:
- Pods can restart anytime.
- Pods can be recreated during deployments.
- Local log files disappear when Pods are deleted.
For this reason, Spring Boot applications running on OpenShift should write logs to stdout, allowing OpenShift to automatically collect and centralize them.
Learning Objectives
By the end of this article, you will understand:
- Spring Boot logging architecture
- Logback configuration
- stdout logging
- JSON logging
- Correlation IDs
- MDC (Mapped Diagnostic Context)
- Centralized logging
- Best logging practices
- Enterprise troubleshooting
Spring Boot Logging Architecture
flowchart LR
A[Spring Boot Application]
B[Logback]
C[stdout]
D[OpenShift Container Runtime]
E[Vector / Fluentd]
F[Loki / Elasticsearch]
G[Grafana / Kibana]
A --> B
B --> C
C --> D
D --> E
E --> F
F --> G
Logging Flow
sequenceDiagram
participant Client
participant SpringBoot
participant Logback
participant OpenShift
participant Loki
Client->>SpringBoot: REST Request
SpringBoot->>Logback: Generate Log
Logback->>OpenShift: stdout
OpenShift->>Loki: Forward Logs
Why stdout?
Containers should never write logs to local files.
❌ Bad
/var/log/payment.log
If the Pod is deleted, the log file disappears.
✅ Good
log.info("Payment Created Successfully");
OpenShift automatically captures stdout.
Spring Boot Default Logger
Spring Boot uses Logback by default.
Dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
No additional logging dependency is required.
Create Logger
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Service
public class PaymentService {
private static final Logger log =
LoggerFactory.getLogger(PaymentService.class);
}
Logging Levels
| Level | Usage |
|---|---|
| TRACE | Detailed execution |
| DEBUG | Development |
| INFO | Business events |
| WARN | Recoverable problems |
| ERROR | Application failures |
Logging Example
log.trace("Method Entered");
log.debug("Payment Object {}", payment);
log.info("Payment Created Successfully");
log.warn("Retrying Payment Request");
log.error("Database Connection Failed");
Logging Configuration
application.properties
logging.level.root=INFO
logging.level.com.codewithvenu=DEBUG
Logback Configuration
Create
src/main/resources/logback-spring.xml
Example
<configuration>
<include resource=
"org/springframework/boot/logging/logback/base.xml"/>
</configuration>
Logging Architecture
flowchart LR
A[Application]
B[SLF4J]
C[Logback]
D[stdout]
A --> B
B --> C
C --> D
JSON Logging
Instead of
Payment Successful
Use structured JSON.
{
"transactionId":"TX10001",
"customerId":"C101",
"amount":500,
"status":"SUCCESS"
}
JSON logs are easier to search and analyze.
Structured Logging Flow
flowchart LR
A[Spring Boot]
B[JSON Log]
C[Vector]
D[Loki]
E[Grafana]
A --> B
B --> C
C --> D
D --> E
Correlation ID
A Correlation ID tracks a request across multiple microservices.
Example
Correlation-ID
REQ-100001
Microservices Request Flow
flowchart LR
A[Client]
B[API Gateway]
C[Payment Service]
D[Fraud Service]
E[Notification Service]
A --> B
B --> C
C --> D
C --> E
The same Correlation ID travels across every service.
MDC (Mapped Diagnostic Context)
Store request-specific information.
MDC.put("correlationId", correlationId);
log.info("Payment Processing");
MDC.clear();
Log Pattern
logging.pattern.console=
%d %-5level [%X{correlationId}] %msg%n
Example Output
INFO
[REQ-100001]
Payment Created
Spring Filter
Generate Correlation ID.
String correlationId =
UUID.randomUUID().toString();
MDC.put("correlationId", correlationId);
Every request receives a unique identifier.
Business Logging
Good Example
log.info(
"Payment {} created for customer {}",
paymentId,
customerId
);
Bad Logging
log.info(password);
log.info(jwtToken);
log.info(apiKey);
Never log sensitive information.
Exception Logging
try {
paymentService.process();
}
catch(Exception ex){
log.error(
"Payment Processing Failed",
ex
);
}
Centralized Logging
flowchart TD
A[Payment Service]
B[Customer Service]
C[Notification Service]
D[Vector]
E[Loki]
F[Grafana]
A --> D
B --> D
C --> D
D --> E
E --> F
Banking Example
flowchart LR
A[Customer]
B[Payment API]
C[Oracle Database]
D[Kafka]
E[Notification]
A --> B
B --> C
B --> D
D --> E
Every service logs the same Correlation ID.
Search Logs
View logs
oc logs payment-service
Follow logs
oc logs -f payment-service
Previous logs
oc logs payment-service --previous
Useful Commands
View Pods
oc get pods
Describe Pod
oc describe pod payment-service
Container Logs
oc logs payment-service
Follow Logs
oc logs -f payment-service
Enterprise Logging Architecture
flowchart LR
A[Spring Boot Pods]
B[OpenShift]
C[Vector Collectors]
D[Loki]
E[Grafana]
F[Operations Team]
A --> B
B --> C
C --> D
D --> E
E --> F
Common Problems
No Logs
Possible causes:
- Application crashed
- Logging disabled
- Wrong log level
Too Many DEBUG Logs
Use
logging.level.root=INFO
Production environments should avoid DEBUG unless troubleshooting.
Missing Correlation ID
Verify:
- Filter registration
- MDC configuration
Sensitive Information Logged
Immediately:
- Remove logging
- Rotate exposed credentials
- Review security policies
Production Best Practices
- Log to stdout only.
- Use structured JSON logging.
- Generate Correlation IDs.
- Use MDC for request context.
- Log business events.
- Never log passwords or tokens.
- Use INFO in production.
- Centralize logs using Loki or Elasticsearch.
- Monitor log volume.
- Archive logs based on retention policies.
Common Mistakes
❌ Writing logs to local files.
❌ Logging secrets.
❌ Using DEBUG level in production.
❌ Ignoring Correlation IDs.
❌ Creating inconsistent log formats.
❌ Printing stack traces unnecessarily.
Advantages
- Centralized troubleshooting
- Faster debugging
- Better observability
- Easier root cause analysis
- Distributed request tracing
- Secure logging
- Enterprise compliance
- Cloud-native logging
Summary
Spring Boot applications running on OpenShift should use stdout logging, structured JSON logs, and correlation IDs to enable effective monitoring and troubleshooting.
Key takeaways:
- Use Logback as the logging framework.
- Write logs to stdout instead of local files.
- Configure INFO as the default production log level.
- Include Correlation IDs using MDC for distributed tracing.
- Forward logs to centralized platforms such as Loki or Elasticsearch.
- Avoid logging sensitive information and adopt structured logging for enterprise observability.
Interview Questions
- Why should Spring Boot applications log to stdout in OpenShift?
- What is Logback?
- What is the purpose of SLF4J?
- What is MDC?
- Why are Correlation IDs important in microservices?
- What is structured JSON logging?
- Why should sensitive information never be logged?
- How do you view logs from an OpenShift Pod?
- What is the difference between INFO and DEBUG logging?
- What are the best practices for Spring Boot logging in production?