在SpringBoot项目中添加logback的MDC

先看下MDC是什么

Mapped Diagnostic Context,用于打LOG时跟踪一个“会话“、一个”事务“。举例,有一个web controller,在同一时间可能收到来自多个客户端的请求,如果一个请求发生了错误,我们要跟踪这个请求从controller开始一步步都执行到了哪些代码、有哪些log的输出。这时我们可以看log文件,但是log文件是多个请求同时记录的,基本无法分辨哪行是哪个请求产生的,虽然我们可以看线程,但线程可能被复用,也是很难分辨出,这时MDC就派上用场了。

我们可以加一个web filter,在请求进来时,把”标识“放到MDC context中,比如:put( ip, 8.8.8.8), put(username, 'yang'),在filter结束时把context再清掉,即可在整个请求处理过程中,都可以打印出ip, username这些数据,就可以方便的用于日志跟踪。

在SpringBoot中怎么用

1. 写一个LogInterceptor,用于统一处理MDC:
@Component
public class LogInterceptor implements HandlerInterceptor {

    private final static String REQUEST_ID = "requestId";
    private static final Logger LOGGER = LoggerFactory.getLogger(LogInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        String xForwardedForHeader = httpServletRequest.getHeader("X-Forwarded-For");
        String remoteIp = httpServletRequest.getRemoteAddr();
        String uuid = UUID.randomUUID().toString();
        LOGGER.info("put requestId ({}) to logger", uuid);
        LOGGER.info("request id:{}, client ip:{}, X-Forwarded-For:{}", uuid, remoteIp, xForwardedForHeader);
        MDC.put(REQUEST_ID, uuid);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        String uuid = MDC.get(REQUEST_ID);
        LOGGER.info("remove requestId ({}) from logger", uuid);
        MDC.remove(REQUEST_ID);
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}
关键代码在于:MDC.put(REQUEST_ID, uuid);
2. 注册一下这个Interceptor,写一个WebMvcConfigurer类:
@Configuration
public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
    @Autowired
    private LogInterceptor logInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(logInterceptor);
        super.addInterceptors(registry);
    }
}

3. 放一个logback.xml到src/main/resources/目录中,用于配置logback的参数,如没有,请新建一个
<configuration scan="true" scanPeriod="30 seconds" debug="true">

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <target>System.out</target>
        <encoder>
            <pattern>[%date{ISO8601}] [%-5level] - [%thread] [%X{requestId}] [%logger] [%X{akkaSource}] - %msg %rootException %n
            </pattern>

        </encoder>
    </appender>



    <root level="INFO">
        <appender-ref ref="STDOUT"/>
    </root>

</configuration>
注意这个<pattern/>中配置了输出 requestId
4. 最后看下效果,下面加粗的即为requestId
[2017-12-14 16:08:45,677] [INFO ] - [http-nio-8080-exec-1] [a08f86cd-6743-48ce-816a-f5ee61b802b8] 


  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值