MDC+Filter/Interceptor实现用户信息日志追踪:3步解决链路跟踪难题
本文将通过Filter(过滤器)和Interceptor(拦截器)结合日志框架的MDC机制,详细讲解如何自动注入用户信息并实现全链路日志跟踪。
免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
前言
在分布式系统或复杂业务架构中,日志是排查问题、追踪流程的关键工具。然而系统默认的日志输出往往缺少用户维度信息,导致问题发生时难以快速定位具体用户的操作链路。下面将详细介绍如何利用Filter或Interceptor与日志框架的MDC协作,实现用户信息的自动注入与全链路跟踪。
原理解析
要实现用户信息追踪,首先需要理解三个核心技术组件的作用与协作逻辑:MDC、Filter和Interceptor。
MDC:日志上下文的存储容器
MDC是SLF4J及Logback、Log4j2等日志框架提供的上下文工具,本质上是通过ThreadLocal实现的线程级键值对存储容器。其核心功能包括:
在请求处理线程中保存临时上下文信息(如用户ID、用户名、请求ID等);日志输出时自动从MDC提取配置的键值,无需在每处日志打印代码中手动传入用户信息;线程结束后自动清理上下文,避免内存泄漏(需手动确保清理逻辑)。
MDC核心API(以SLF4J为例):
// 向MDC存入键值对(如用户ID)
MDC.put("userId", "user_123456");
// 从MDC获取值
String userId = MDC.get("userId");
// 清空当前线程的MDC上下文(关键,必须执行)
MDC.clear();
Filter与Interceptor:请求链路的拦截器
图片

Filter和Interceptor都用于拦截HTTP请求,在处理前后执行自定义逻辑(如权限校验、参数预处理),这是注入MDC上下文的最佳切入点。
实践方案
方案1:基于Filter+MDC实现
自定义MDC过滤器
/**
* 基于Filter的MDC用户信息注入过滤器
*/
public class MdcUserFilter extends OncePerRequestFilter {
// 定义MDC中用户信息的键(需与日志配置一致)
private static final String MDC_USER_ID = "userId";
private static final String MDC_USER_NAME = "userName";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
// 1.从请求头提取用户信息(实际项目需替换为Token解析、Session获取等逻辑)
String userId = request.getHeader("X-User-Id");
String userName = request.getHeader("X-User-Name");
// 2.注入MDC(若用户未登录,可存入默认值如"unknown")
MDC.put(MDC_USER_ID, userId != null ? userId : "unknown");
MDC.put(MDC_USER_NAME, userName != null ? userName : "unknown");
// 3.继续执行请求链路(进入Controller层)
filterChain.doFilter(request, response);
} finally {
// 4.关键:请求结束后清理MDC,避免线程复用导致上下文污染(线程池场景必做)
MDC.clear();
}
}
}
步骤2:注册Filter到Spring容器
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean mdcUserFilterRegistration() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new MdcUserFilter());
// 拦截所有请求
registrationBean.addUrlPatterns("/*");
// 设置过滤器优先级(值越小优先级越高,确保先于其他业务过滤器执行)
registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return registrationBean;
}
}
方案2:基于Interceptor+MDC实现
步骤1:自定义MDC拦截器
/**
* 基于Interceptor的MDC用户信息注入拦截器
*/
public class MdcUserInterceptor implements HandlerInterceptor {
private static final String MDC_USER_ID = "userId";
private static final String MDC_USER_NAME = "userName";
/**
* 请求处理前执行:注入MDC
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 1.提取用户信息(逻辑与Filter一致,可复用工具类)
String userId = request.getHeader("X-User-Id");
String userName = request.getHeader("X-User-Name");
// 2.注入MDC
MDC.put(MDC_USER_ID, userId != null ? userId : "unknown");
MDC.put(MDC_USER_NAME, userName != null ? userName : "unknown");
// 返回true:继续执行后续链路(如Controller)
returntrue;
}
/**
* 请求完成后执行(无论是否抛异常):清理MDC
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 关键:清理MDC,避免线程池上下文污染
MDC.clear();
}
}
步骤2:注册Interceptor到SpringMVC
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MdcUserInterceptor())
// 拦截所有请求
.addPathPatterns("/**")
// 排除无需拦截的路径(如登录接口、静态资源等)
.excludePathPatterns("/api/login", "/static/**", "/error");
}
}
配置日志输出MDC信息
线程池场景下的MDC传递
手动传递MDC上下文
public class AsyncMdcDemo {
// 初始化线程池
private static final ExecutorService executorService = Executors.newFixedThreadPool(5);
public void doAsyncTask() {
// 1.获取当前线程的MDC上下文(包含用户信息)
Map mdcContext = MDC.getCopyOfContextMap();
// 2.提交异步任务到线程池
executorService.submit(() -> {
try {
// 3.子线程中注入MDC上下文
if (mdcContext != null) {
MDC.setContextMap(mdcContext);
}
// 4.异步业务逻辑(日志会自动包含用户信息)
log.info("执行异步任务:处理用户订单");
} finally {
// 5.子线程结束后清理MDC
MDC.clear();
}
});
}
}
封装线程池(避免重复代码)
// Spring异步任务装饰器:自动传递MDC
public class MdcTaskDecorator implements TaskDecorator {
@Override
public Runnable decorate(Runnable runnable) {
// 获取当前线程MDC上下文
Map
总结
通过Filter/Interceptor与MDC机制实现用户信息追踪,核心在于拦截请求→注入上下文→日志输出→清理上下文的闭环流程。其价值主要体现在:
无侵入式:无需在业务代码中手动传递用户信息到日志,降低开发成本;可追溯性:日志自动关联用户维度,快速定位单个用户的操作链路;灵活性:支持全局或局部拦截,适配不同业务场景。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
微星 2026 款泰坦 18 Max 游戏本国行上市:7 热管 2 风扇,整机双烤 260W
微星泰坦 18 Max 2026款国行发布:极致双烤260W性能,散热系统全面解析 对于追求极致性能的游戏玩家和专业创作者而言,顶级游戏本市场迎来了一个重磅选项。近日,微星正式在国内推出了其旗舰级新品——2026款泰坦 18 Max(Raider 18 Max HX)游戏笔记本电脑,旨在重新定义高性
旗舰配置 25000Pa 吸力 + 95℃ 自清洁:石头 A30 CE 洗地机 1278 元免费用 15 天
京东百亿补贴开启:石头 A30 CE 系列洗地机享“买贵双倍赔”与“15天免费试用” 如果您正在关注高品质清洁电器,那么现在有一个不容错过的限时机会。石头科技旗下的 A30 CE 系列智能洗地机现已加入“京东百亿补贴”专场。本次促销不仅带来极具竞争力的价格,更提供了两大核心保障:一是“买贵双倍赔”的
比官方预告时间更早:消息称“超级小爱”PC 客户端正推送给小米笔记本 Pro 14
比官方预告时间更早:消息称“超级小爱”PC 客户端正推送给小米笔记本 Pro 14 四月份伊始,小米在AI落地应用方面便带来了令人惊喜的新进展。据知名数码博主@懒酱的日记本透露,备受期待的“超级小爱”PC客户端已开始向小米笔记本 Pro 14用户推送。此次推送的时间点,较官方之前公布的四月中旬计划明
红魔姜超“冒险爆料”:Pad 新品不是四月就是五月发布,一定不让大家失望
红魔姜超透露:全新游戏平板将于四月或五月发布,承诺带来惊艳体验 游戏硬件领域即将迎来重磅更新。努比亚红魔游戏手机的产品线负责人姜超,近日通过社交媒体进行了一次颇具悬念的“前瞻剧透”,成功引发了广大游戏玩家和科技爱好者的高度关注。他明确指出,红魔全新一代游戏平板的发布日期已锁定在四月或五月,并使用了“
未来人类 X98W 移动“工作站”笔记本电脑上线官网,4 月内发售
未来人类X98W移动工作站正式发布:重新定义移动端专业性能的新标杆 在专业移动计算领域,总有一些产品能够打破常规认知。近日,未来人类(TerransForce)正式在其官网上线了全新的X98W高性能移动工作站,并宣布将于本月内全面发售。这款设备的问世,无疑为那些在移动办公环境中仍需要桌面级别强悍性能
- 日榜
- 周榜
- 月榜
相关攻略
2015-03-10 11:25
2015-03-10 11:05
2021-08-04 13:30
2015-03-10 11:22
2015-03-10 12:39
2022-05-16 18:57
2025-05-23 13:43
2025-05-23 14:01
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程

