在web环境下进行日志记录,时刻需要跟踪用户,特别是多线程下进行日志记录可能会导致一些问题 LogBack 有个 MDC(Mapped Diagnostic Context,映射调试上下文) 是 log4j 和 logback 提供的一种方便在多线程条件下记录日志的功能。
MDC : https://logback.qos.ch/manual/mdc.html#autoMDC http://www.cnblogs.com/dumuqiao/p/3654702.html?utm_source=tuicool&utm_medium=referral
在一个用户的使用过程中,可能有多个不同的线程来进行处理。典型的例子是 Web 应用服务器。当用户访问某个页面时,应用服务器可能会创建一个新的线程来处理该请求,也可能从线程池中复用已有的线程。在一个用户的会话存续期间,可能有多个线程处理过该用户的请求。这使得比较难以区分不同用户所对应的日志。当需要追踪某个用户在系统中的相关日志记录时,就会变得很麻烦。
MDC内部就是使用 ThreadLocal
当然这里要介绍的是 Log4j2 的 ThreadContext,功能和MDC差不多,但是Log4j2的性能更好.
官方性能测试报告 : http://logging.apache.org/log4j/2.x/performance.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 import com.aidijing.common.LogUtils;import com.aidijing.common.RequestUtils;import org.apache.logging.log4j.ThreadContext;import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import java.io.IOException;public class RequestLoggingFilter implements Filter { private static final String REQUEST_MESSAGE = "requestMessage" ; private static final String USER_ID = "userId" ; private static final String USER_NAME = "userName" ; @Override public void doFilter ( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException { final BodyReaderWrapper wrapper = new BodyReaderWrapper( ( HttpServletRequest ) request ); final String username = "用户名A" ; ThreadContext.put( USER_ID, wrapper.getRequestedSessionId() ); ThreadContext.put( USER_NAME, username ); LogUtils.getLogger().info( RequestUtils.getRequestMessage( wrapper, USER_ID, username ) ); chain.doFilter( wrapper, response ); ThreadContext.clearAll(); } @Override public void init ( FilterConfig filterConfig ) throws ServletException { } @Override public void destroy () { } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <Configuration monitorInterval ="3600" shutdownHook ="disable" > <Appenders > <Console name ="Console" target ="SYSTEM_OUT" follow ="true" > <PatternLayout pattern ="[%X{userId}] [%X{userName}] %d{yyyy-MM-dd HH:mm:ss SSS} [%p] [%t] %c.%M(%L) | %m%n" /> </Console > </Appenders > <Loggers > <logger name ="com.aidijing" level ="debug" /> <logger name ="org.mybatis" level ="info" /> <logger name ="org.springframework" level ="info" /> <logger name ="com.alibaba.druid" level ="info" /> <Root level ="debug" > <AppenderRef ref ="Console" /> </Root > </Loggers > </Configuration >
效果如下: