在SpringBoot应用程序中为传入请求添加唯一的请求ID
只需3个简单的步骤,即可为每个传入请求添加UUID,从而轻松跟踪请求、调试和监控审计。
图片来源:Shreyak SinghonUnsplash
要向Spring靴子应用程序中的每个传入请求添加UUID,您可以实现一个过滤器,该过滤器拦截每个请求并分配UUID。这个UUID可以在请求的整个生命周期中使用,包括在日志中。
实施步骤:
- 创建过滤器: 实现
javax.servlet.Filter
拦截传入请求并添加UUID。 - 将UUID添加到
MDC
: 使用SLF 4J中的Mapped Diagnostic Context (MDC)
来存储UUID,以便它可以自动包含在日志消息中。 - 记录UUID: 修改日志记录模式以在每个日志条目中包含UUID。
代码实现:
- 创建过滤器类:
import org.slf4j.MDC;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
import java.util.UUID;
@WebFilter("/*") // Apply the filter to all incoming requests
public class UUIDFilter implements Filter {
private static final String UUID_KEY = "requestUUID";
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Initialization logic, if required
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// Generate a UUID for the request
String uuid = UUID.randomUUID().toString();
// Add the UUID to MDC so it can be used in logging
MDC.put(UUID_KEY, uuid);
try {
// Proceed with the rest of the filter chain
chain.doFilter(request, response);
} finally {
// Clean up MDC to avoid memory leaks
MDC.remove(UUID_KEY);
}
}
@Override
public void destroy() {
// Cleanup logic, if required
}
}
2.更新日志记录配置:
确保日志记录配置在日志格式中包含UUID。例如,如果您使用带有XML配置的Logback,您可以像这样更新它:
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%X{requestUUID}] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
此配置将在每个日志条目中包含UUID,从而更容易跟踪特定请求的日志。
3.在应用程序中使用日志记录:
当您在应用程序中登录时,UUID将自动包含在日志消息中:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class MyController {
private static final Logger logger = LoggerFactory.getLogger(MyController.class);
@GetMapping("/test")
public String test() {
logger.info("Test endpoint was called");
return "Request processed";
}
}
这种方法确保每个请求都被分配一个唯一的UUID,然后将其包含在与该请求相关的所有日志中,以帮助跟踪和调试。