Tips & tricks: Spring Boot – propagate correlation ID in the REST API

As I mentioned in the previous post, the correlation ID is very important, especially when you have many requests in this same time. Below is class which automatically propagate correlation ID between requests and responses in Spring Boot application:

package pl.dmarciniak.blog.example.restcorrelationid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class RestLogger implements Filter {

    private final static String CORRELATION_ID_KEY = "correlation-id";

    private final Logger log = LoggerFactory.getLogger(RestLogger.class);

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        if (servletRequest instanceof HttpServletRequest && servletResponse instanceof HttpServletResponse) {
            var req = (HttpServletRequest) servletRequest;
            var resp = (HttpServletResponse) servletResponse;
            var cid = req.getHeader(CORRELATION_ID_KEY);

            log.info("[cid: {}] REQ {} {}?{}", cid, req.getMethod(), req.getRequestURL(), req.getQueryString());
            resp.addHeader(CORRELATION_ID_KEY, cid);
            chain.doFilter(req, resp);
            log.info("[cid: {}] RESP status: {}", cid, resp.getStatus());
        } else {
            chain.doFilter(servletRequest, servletResponse);
        }
    }
}

The output will be something like this:

2019-10-18 21:14:28.336  INFO 29366 --- [nio-8080-exec-1] p.d.b.e.r.RestLogger              : [cid: 2ac8d2837d91] REQ GET http://127.0.0.1:8080/api1/test?query=123
2019-10-18 21:14:28.395  INFO 29366 --- [nio-8080-exec-1] p.d.b.e.r.RestLogger              : [cid: 2ac8d2837d91] RESP status: 200

As you see, I used Filter to do that. Additionally I logged some information but you can change this logic. In this example I used Java 11 but convert to older version shouldn’t be a problem.