在Spring Boot中,我们可以通过使用MDC Filter来轻松地将MDC集成到我们的应用程序中。本文将介绍如何使用Spring Boot MDC Filter来实现请求跟踪和日志记录。
什么是MDC?
MDC是一种日志记录技术,它允许我们将上下文信息存储在线程局部变量中,并在整个线程执行期间共享这些信息。这些上下文信息可以是任何东西,例如请求ID、用户ID、会话ID等等。MDC允许我们在跨多个线程和组件的日志记录中,轻松地将所有相关日志记录关联起来。
MDC(Mapped Diagnostic Context,映射调试上下文)是 log4j 、logback及log4j2 提供的一种方便在多线程条件下记录日志的功能。MDC 可以看成是一个与当前线程绑定的哈希表,可以往其中添加键值对。MDC 中包含的内容可以被同一线程中执行的代码所访问。
当前线程的子线程会继承其父线程中的 MDC 的内容。当需要记录日志时,只需要从 MDC 中获取所需的信息即可。MDC 的内容则由程序在适当的时候保存进去。对于一个 Web 应用来说,通常是在请求被处理的最开始保存这些数据。
如何使用MDC?
org.slf4j.MDC的API:
clear() :移除所有MDC
get (String key) :获取当前线程MDC中指定key的值
getContext() :获取当前线程MDC的MDC
put(String key, Object o) :往当前线程的MDC中存入指定的键值对
remove(String key) :删除当前线程MDC中指定的键值对
1 添加过滤器
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;
@Slf4j
public class LogFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
MDC.put("U", UUID.randomUUID().toString().replace("-", ""));
log.info("enter {} Coffee: {}", "a", "a");
try {
filterChain.doFilter(request, response);
} finally {
MDC.remove("U");
log.info("remove {} Coffee: {}", "a", "a");
}
}
}
@Configuration
public class Config {
@Bean
public FilterRegistrationBean logFilter() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new LogFilter());
filterRegistrationBean.setOrder(Integer.MIN_VALUE);
return filterRegistrationBean;
}
}
2 logback配置变量输出 [%X{U}]
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{U}] [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="com.example" level="DEBUG"/>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
3 输出效果
image.png