Add a Unique Request ID to Every HTTP Request
One of the marks of a well-built application is how easily it can be debugged. And in most real-world systems, the most reliable debugging tool is logs.
In a microservices architecture, a single user action often triggers a cascade of calls across multiple services. Each service runs independently, yet when something goes wrong, you still need to trace the entire user journey across those services.
This is where a request ID becomes invaluable.
Why a Request ID?
A request-id (also called a correlation ID or trace ID) acts as a unique identifier for a specific user request. By attaching this ID to every downstream call — from the frontend all the way through each backend microservice — developers can easily correlate logs from different components and reconstruct the full path of the request.
The request-id can be passed in an HTTP header (recommended) or body, but manually reading and logging it in every class or method quickly becomes tedious and error-prone.
Wouldn’t it be better if the request-id appeared automatically with every log line, just like timestamps or class names?
Automatically Logging the Request ID
In a Java Spring Boot application, this can be done elegantly using Servlet Filters and SLF4J’s Mapped Diagnostic Context (MDC).
The idea is simple:
Intercept every incoming HTTP request using a filter.
Generate a new
request-id(if one doesn’t exist) or reuse the existing one from headers.Inject that ID into the MDC — a thread-local map used by SLF4J to enrich log statements with contextual data.
Clear the MDC once the request completes.
With this setup, every log line automatically includes the request-id, without developers needing to manually pass it around in their code.
Example: Adding Request ID via Filter
Refer GIST
@Component
public class MDCFilter implements Filter {
private static final String REQUEST_ID = “requestId”;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String requestId = httpRequest.getHeader(REQUEST_ID);
if (requestId == null || requestId.isEmpty()) {
requestId = UUID.randomUUID().toString();
}
try {
MDC.put(REQUEST_ID, requestId);
chain.doFilter(request, response);
} finally {
MDC.clear();
}
}
}
Result
Every log statement now automatically includes the request-id, giving you a clean, end-to-end trace of a request across multiple services:
2025-11-03 14:25:12 [3a9d7e1a-82b4-4c23-8c77-f10e3e7a4b93] INFO com.example.OrderService - Order created successfully
Takeaway
By combining Spring Boot filters with SLF4J’s MDC, you can inject contextual information like request-id into your logs automatically. This small enhancement makes debugging distributed systems dramatically easier and keeps your logs clean, consistent, and traceable — without burdening developers with extra boilerplate code.


