基于spring boot 和MDC实现 同一笔记录的日志跟踪实现--1.filter

同一个项目中,一般包含controller/servlet、service、dao等。1笔记录的日志贯穿于controller、service、dao中,在并发情况下,那如何找出该笔日志?

可通过以下三种方式实现:

1、filter:依赖servlet容器

2、Interceptor:依赖spring

3、AOP:spring boot中,不能拦截servlet(我试过的,但可能也行)

以下时filter的实现。

首先,包结构:

基于spring boot 和MDC实现 同一笔记录的日志跟踪实现--1.filter

代码实现:

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{requestId}] %p | %logger{20}.%M:%L - %m%n</pattern>
        </encoder>
    </appender>
    <!-- TRACE < DEBUG < INFO < WARN < ERROR -->
    <root level="INFO">
        <appender-ref ref="console"/>
    </root>
</configuration>

MdcLogEnhancerFilter

package com.ebc.slf4j.mdc.filter;
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.slf4j.MDC;
import org.springframework.stereotype.Component;

import cn.hutool.core.lang.Console;
import cn.hutool.core.util.IdUtil;
@Component
public class MdcLogEnhancerFilter implements Filter {
    @Override
    public void destroy() {
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        MDC.put("requestId", IdUtil.objectId());
        filterChain.doFilter(servletRequest, servletResponse);
        MDC.remove("requestId");//否则内存溢出
        //Console.log("======{}",MDC.get("requestId"));//输出null
    }
}

Application

package com.ebc.slf4j.mdc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
@ServletComponentScan(basePackages="com.ebc.slf4j.mdc.servlet")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

下边是业务类

M2Servlet

package com.ebc.slf4j.mdc.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.ebc.slf4j.mdc.service.WelcomeService;

@WebServlet("/M2Servlet")
@Slf4j
public class M2Servlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        log.info("进入了servlet");
        WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
        WelcomeService welcomeService = (WelcomeService) wac.getBean("welcomeService");
        String reStr = welcomeService.exec("遥远2");
        log.info("service返回:{}",reStr);
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

WelcomeService

package com.ebc.slf4j.mdc.service;

import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Service;

@Service
@Slf4j
public class WelcomeService {
    public String exec(String name) {
        log.info("service接收到:{}",name);
        return "hello "+name;
    }
}

执行:http://localhost:8080/M2Servlet

结果:

2019-01-22 11:22:03.900 [5c468c5bcbb014209e2ea828] INFO | c.e.s.m.s.M2Servlet.doGet:20 - 进入了servlet
2019-01-22 11:22:03.900 [5c468c5bcbb014209e2ea828] INFO | c.e.s.m.s.WelcomeService.exec:11 - service接收到:遥远2
2019-01-22 11:22:03.900 [5c468c5bcbb014209e2ea828] INFO | c.e.s.m.s.M2Servlet.doGet:24 - service返回:hello 遥远2