基于SpringBoot+logback+MDC使用拦截器实现日志输出里为每个请求设置唯一请求ID
470 字
2 分钟
基于SpringBoot+logback+MDC使用拦截器实现日志输出里为每个请求设置唯一请求ID
1.MDC
MDC为“Mapped Diagnostic Context”(映射诊断上下文),即将一些运行时的上下文数据通过logback打印出来;此时我们需要借助org.sl4j.MDC类。
MDC类基本原理其实非常简单,其内部持有一个InheritableThreadLocal实例,用于保存context数据,MDC提供了put/get/remove等几个核心接口,用于操作ThreadLocal中的数据;ThreadLocal中的K-V,可以在logback.xml中声明,最终将会打印在日志中。
在使用MDC时需要注意一些问题,这些问题通常也是ThreadLocal引起的,比如我们需要在线程退出之前清除(clear)MDC中的数据;在线程池中使用MDC时,那么需要在子线程退出之前清除数据;可以调用MDC.remove()方法
2.使用
-
SpringBoot默认日志组件就是logback,无需导入jar包
-
logback.xml配置 主要是 %X{requestId}
<?xml version="1.0" encoding="UTF-8"?><configuration><!--日志文件轮询 每天一个日志文件--><appender name="File" class="ch.qos.logback.core.rolling.RollingFileAppender"><Append>true</Append><File>../logs/platform_logs/platformHome-api.log</File><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] [%X{requestId}] - [ %p ] %m%n</pattern></encoder><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>../logs/xxxxxxx.log.%d{-yyyy-MM-dd}</fileNamePattern></rollingPolicy></appender><!--本地控制台输出--><appender name="Console" class="ch.qos.logback.core.ConsoleAppender"><Target>System.out</Target><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] [%X{requestId}] - [ %p ] %m%n</pattern></encoder></appender><root level="INFO"><appender-ref ref="File"/><appender-ref ref="Console"/></root></configuration> -
拦截器
@Slf4jpublic class LogInterceptor implements HandlerInterceptor {private final static String REQUEST_ID = "requestId";private final static String REQUEST_TIME = "requestTime";@Overridepublic boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) {String ipAddress = IPAddressUtils.getIPAddress(httpServletRequest);String url = httpServletRequest.getRequestURL().toString();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String requestTime = sdf.format(new Date());String uuid = UUID.randomUUID().toString().replaceAll("-", "");log.info("请求的url:{} 客户端IP为:{} 设置的请求Id为:{} 请求时间为:{}", url, ipAddress, uuid, requestTime);log.info("put requestId ({}) requestTime ({}) to logger", uuid, requestTime);MDC.put(REQUEST_ID, uuid);MDC.put(REQUEST_TIME, requestTime);return true;}@Overridepublic void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) {String uuid = MDC.get(REQUEST_ID);String requestTime = MDC.get(REQUEST_TIME);MDC.remove(REQUEST_ID);MDC.remove(REQUEST_TIME);log.info("remove requestId ({}) requestTime ({}) from logger", uuid, requestTime);}@Overridepublic void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {}} -
注册拦截器
@Configurationpublic class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(logInterceptor());}@Beanpublic LogInterceptor logInterceptor() {return new LogInterceptor();}}
3.效果

文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
基于SpringBoot+logback+MDC使用拦截器实现日志输出里为每个请求设置唯一请求ID
https://tianch.com.cn/posts/tutorials/ji-yu-springboot-mdc-shi-xian-ri-zhi-shu-chu-li-wei-mei-ge-qing-qiu-she-zhi-wei-yi-qing-qiu-id/相关文章智能推荐
1
基于SpringBoot+logstash+redis实现日志异步集中存储
中间件logstash是一个数据分析软件,主要目的是分析log日志。整一套软件可以当作一个MVC模型,logstash是controller层,Elasticsearch是一个model层,kibana是view层。首先将数据传给logstash
2
SpringBoot统一参数校验
Java2026-01-05
3
SpringBoot+Redis+ELK日志集中存储和查询
中间件http://www.tianch.xyz/archives/%E4%BD%BF%E7%94%A8docker-compose%E5%AE%89%E8%A3%85skywalking%E5%92%8Celasticsearchmd
4
MDC进阶 给异步线程添加唯一id
Java之前写过了MDC的简单用法。
5
基于Springboot2.x+Mybatis Plus+Atomikos实现多数据源事务和DAP层多数据源动态切换
Java2020-05-30
随机文章随机推荐


