在SpringBoot項目中添加logback的MDC


在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:
 
           
  1.  
    @Component
  2.  
    public class LogInterceptor implements HandlerInterceptor {
  3.  
     
  4.  
    private final static String REQUEST_ID = "requestId";
  5.  
    private static final Logger LOGGER = LoggerFactory.getLogger(LogInterceptor.class);
  6.  
     
  7.  
    @Override
  8.  
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
  9.  
    String xForwardedForHeader = httpServletRequest.getHeader( "X-Forwarded-For");
  10.  
    String remoteIp = httpServletRequest.getRemoteAddr();
  11.  
    String uuid = UUID.randomUUID().toString();
  12.  
    LOGGER.info( "put requestId ({}) to logger", uuid);
  13.  
    LOGGER.info( "request id:{}, client ip:{}, X-Forwarded-For:{}", uuid, remoteIp, xForwardedForHeader);
  14.  
    MDC.put(REQUEST_ID, uuid);
  15.  
    return true;
  16.  
    }
  17.  
     
  18.  
    @Override
  19.  
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
  20.  
    String uuid = MDC.get(REQUEST_ID);
  21.  
    LOGGER.info( "remove requestId ({}) from logger", uuid);
  22.  
    MDC.remove(REQUEST_ID);
  23.  
    }
  24.  
     
  25.  
    @Override
  26.  
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
  27.  
     
  28.  
    }
  29.  
    }
關鍵代碼在於:MDC.put(REQUEST_ID, uuid);
 
           
2. 注冊一下這個Interceptor,寫一個WebMvcConfigurer類:
 
           
  1.  
    @Configuration
  2.  
    public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
  3.  
    @Autowired
  4.  
    private LogInterceptor logInterceptor;
  5.  
     
  6.  
    @Override
  7.  
    public void addInterceptors(InterceptorRegistry registry) {
  8.  
    registry.addInterceptor(logInterceptor);
  9.  
    super.addInterceptors(registry);
  10.  
    }
  11.  
    }
3. 放一個logback.xml到src/main/resources/目錄中,用於配置logback的參數,如沒有,請新建一個
  1.  
    <configuration scan="true" scanPeriod="30 seconds" debug="true">
  2.  
     
  3.  
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
  4.  
    <target>System.out</target>
  5.  
    <encoder>
  6.  
    <pattern>[%date{ISO8601}] [%-5level] - [%thread] [%X{requestId}] [%logger] [%X{akkaSource}] - %msg %rootException %n
  7.  
    </pattern>
  8.  
     
  9.  
    </encoder>
  10.  
    </appender>
  11.  
     
  12.  
     
  13.  
     
  14.  
    <root level="INFO">
  15.  
    <appender-ref ref="STDOUT"/>
  16.  
    </root>
  17.  
     
  18.  
    </configuration>
注意這個<pattern/>中配置了輸出 requestId
4. 最后看下效果,下面加粗的即為requestId
[2017-12-14 16:08:45,677] [INFO ] - [http-nio-8080-exec-1] [a08f86cd-6743-48ce-816a-f5ee61b802b8] 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM