Logging and Correlation ID Patterns in Java – Trace Requests Across Microservices

Illustration for Logging and Correlation ID Patterns in Java – Trace Requests Across Microservices
By Last updated:

Introduction

In modern Java microservice architectures, a single user request can traverse multiple services. Without proper logging and traceability, debugging and observability become nightmares.

This is where Logging and Correlation ID Patterns come in. These patterns ensure that every request is traceable end-to-end, even across service boundaries.

In this guide, you’ll learn how to implement these patterns in Spring Boot, how to propagate correlation IDs across services, and how to make logs developer- and ops-friendly.


🧠 What Are Logging and Correlation ID Patterns?

Logging Pattern

Ensures that all operations (success or failure) are logged with sufficient context—like user ID, request path, service name, and timestamp.

Correlation ID Pattern

Assigns a unique ID to each request that’s propagated across services and included in all log entries.


UML-Style Request Trace

[Client] 
   | (HTTP Header: X-Correlation-ID)
   v
[API Gateway] --> [Service A] --> [Service B] --> [Database]
        |              |              |
     [Logs]         [Logs]         [Logs]
       (with X-Correlation-ID)

👥 Core Participants

  • Correlation ID Generator: Assigns ID to new requests.
  • Logging Context (MDC): Stores correlation ID per thread.
  • Log Appender: Outputs formatted logs (e.g., JSON).
  • Log Aggregator: Collects logs (ELK, Loki, etc.)
  • Tracer (optional): Used with Zipkin, Sleuth, or OpenTelemetry.

🌍 Real-World Use Cases

  • Trace user actions across microservices.
  • Debug failed transactions that span services.
  • Identify latency bottlenecks.
  • Ensure audit trails for compliance.

🧰 Java Implementation (Spring Boot + MDC + Sleuth)

1. Add Dependencies

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>

2. Configure Logging Format

application.yml

spring:
  sleuth:
    propagation-keys: X-Correlation-ID
    sampler:
      probability: 1.0

3. Add Filter to Inject Correlation ID

@Component
public class CorrelationIdFilter extends OncePerRequestFilter {

    private static final String CORRELATION_ID_HEADER = "X-Correlation-ID";

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        String correlationId = request.getHeader(CORRELATION_ID_HEADER);
        if (correlationId == null) {
            correlationId = UUID.randomUUID().toString();
        }

        MDC.put(CORRELATION_ID_HEADER, correlationId);
        response.setHeader(CORRELATION_ID_HEADER, correlationId);

        try {
            filterChain.doFilter(request, response);
        } finally {
            MDC.remove(CORRELATION_ID_HEADER);
        }
    }
}

✅ Pros and Cons

Pros Cons
Full traceability across services Slight performance overhead
Improves debuggability and audit trails Misuse can expose sensitive data in logs
Works with distributed tracing tools Requires disciplined logging practices

❌ Anti-Patterns and Misuse

  • Not passing correlation ID downstream.
  • Logging user PII or secrets.
  • Overusing logs (e.g., logging entire objects).
  • No standardization in log format.

🔁 Comparison with Similar Patterns

Pattern Purpose
Correlation ID Trace request across services
Trace ID (Zipkin) Used for distributed tracing
MDC Logging Adds context to each log entry
Structured Logging Format logs for searchability (JSON)

💻 Log Format Example

{
  "timestamp": "2025-08-06T11:00:00",
  "level": "INFO",
  "service": "order-service",
  "correlationId": "c3f9d2fa-7891-4fd9-bd87-19eafe6f1a00",
  "message": "Order placed successfully",
  "userId": "42"
}

🔧 Refactoring Legacy Code

Before

log.info("Order created");

After

log.info("Order created with correlationId {}", MDC.get("X-Correlation-ID"));

Or use MDC configuration to include it automatically in log pattern:

logging.pattern.level=%5p [${X-Correlation-ID:-}] 

🌟 Best Practices

  • Always include correlation ID in all log entries.
  • Use MDC to inject logging context.
  • Use JSON logs with unique service name and trace ID.
  • Never log passwords or secrets.
  • Use centralized logging (e.g., ELK, Loki, Datadog).

🧠 Real-World Analogy

Think of a courier tracking number (correlation ID). No matter how many hands your package goes through, the tracking number stays the same. It helps you trace every step—from pickup to delivery.


☕ Java Feature Relevance

  • MDC (Mapped Diagnostic Context): Adds correlation ID to logs.
  • Servlet Filters: Modify request/response at the entry point.
  • Lambdas: Use with MDC-aware logging in async tasks.

🔚 Conclusion & Key Takeaways

Logging and Correlation ID Patterns bring clarity, traceability, and accountability to your Java microservices. In distributed environments, they're no longer optional—they're essential.

✅ Summary

  • Use correlation ID to trace requests end-to-end.
  • Implement with MDC and servlet filters in Spring Boot.
  • Include correlation ID in every log line.
  • Use structured logs and centralized log aggregation.

❓ FAQ – Logging and Correlation ID Patterns

1. What is a correlation ID?

A unique ID assigned to a request to trace it across services.

2. What’s the difference between trace ID and correlation ID?

Trace ID is part of distributed tracing (Zipkin). Correlation ID is application-specific and often manually propagated.

3. How do I generate a correlation ID?

Use UUID.randomUUID() if not passed from upstream.

4. Is MDC thread-safe?

Yes, MDC uses thread-local storage, but be careful with async operations.

5. Can I use correlation ID in async code?

Yes, but you must manually propagate MDC context using wrappers.

6. Is Spring Cloud Sleuth enough for this?

Yes, it handles correlation and trace IDs automatically.

7. Should I log correlation ID manually?

You can use log patterns or interceptors to auto-inject it.

8. How do I visualize correlation ID logs?

Use Kibana, Grafana Loki, or any centralized logging system.

9. Can I use correlation ID in non-HTTP systems?

Yes—gRPC, messaging queues, etc. can carry it in metadata/headers.

10. What’s a good default header for correlation ID?

X-Correlation-ID is the de facto standard.