LOG4J MDC 使用

MDC简介

MDC[http://logback.qos.ch/manual/mdc.html]是为每个线程建立一个独立的存储空间,开发人员可以根据需要把信息存入其中。MDC使用Map机制来存储信息,信息以key/value对的形式存储在Map中。

使用Servlet Filter在接收到请求时,生成UUID填充MDC。在log4j的配置中就可以使用%X{key}打印MDC中的内容,从而识别出同一次请求中的log。

以下是一个简单的MDCFilter实现示例,在MDC中填充了UUID、主机IP和主机名。UUID用于标记同一次请求中的log,主机IP和主机名方便异常发生时到相应机器上检查log。

log4j 1.x中MDCFilter实现

//MDC填充的KEY

public static final String REQUEST_UUID = "REQUEST_UUID";

public static final String HOST_IP = "HOST_IP";

public static final String HOST_NAME = "HOST_NAME";

public static final String APPKEY = "APPKEY";

private String appkey = null;

 

@Override

public void init(FilterConfig filterConfig) throws ServletException {

    appkey = filterConfig.getInitParameter("appkey");//appkey可以在filter  init-param中配置

    if(appkey == null) {

        appkey = "";

    }

} 

@Override

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

    try {

        insertIntoMDC(request);//填充MDC

        chain.doFilter(request, response);

    } finally {

        clearMDC();//请求结束,注意清除MDC中的内容,否则会造成内存泄露问题

    }

}

// 默认实现中填充了UUID,主机IP和主机地址

protected void insertIntoMDC(ServletRequest request) {

    MDC.put(MDCFilter.REQUEST_UUID, UUID.randomUUID().toString());

    MDC.put(MDCFilter.HOST_IP, getHostIP());

    MDC.put(MDCFilter.HOST_NAME, getHostName());

    MDC.put(MDCFilter.APPKEY, appkey);

}

protected void clearMDC() {

    MDC.remove(MDCFilter.REQUEST_UUID);

    MDC.remove(MDCFilter.HOST_IP);

    MDC.remove(MDCFilter.HOST_NAME);

    MDC.remove(MDCFilter.APPKEY);

}

log4j2.0中MDCFilter实现

在log4j 2.0 中,使用ThreadContext代替了MDC和

NDC[http://logging.apache.org/log4j/2.x/manual/thread-context.html]。

log4j 2.x 中,类似MDCFilter的实现:

ThreadContextFilter

public static final String REQUEST_UUID = "REQUEST_UUID";

public static final String HOST_IP = "HOST_IP";

public static final String HOST_NAME = "HOST_NAME";

public static final String APPKEY = "APPKEY";

private String appkey = null;

 

 

@Override

public void init(FilterConfig filterConfig) throws ServletException {

    appkey = filterConfig.getInitParameter("appkey");//appkey可以在filter  init-param中配置

    if(appkey == null) {

        appkey = "";

    }

}

@Override

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

    try {

        insertIntoMDC(request);

        chain.doFilter(request, response);

    } finally {

        clearMDC();

    }

}

     

protected void insertIntoMDC(ServletRequest request) {

    ThreadContext.put(ThreadContextFilter.REQUEST_UUID, UUID.randomUUID().toString());

    ThreadContext.put(ThreadContextFilter.HOST_IP, getHostIP());

    ThreadContext.put(ThreadContextFilter.HOST_NAME, getHostName());        

    ThreadContext.put(ThreadContextFilter.APPKEY, appkey);

}

protected void clearMDC() {

    ThreadContext.remove(ThreadContextFilter.REQUEST_UUID);

    ThreadContext.remove(ThreadContextFilter.HOST_IP);

    ThreadContext.remove(ThreadContextFilter.HOST_NAME);

    ThreadContext.remove(ThreadContextFilter.APPKEY);

}

log4j配置中,使用MDC

在log4j配置中,使用mdc:(log4j 1.x 与 2.x中都可以使用此配置)

log4j配置



%X{REQUEST_UUID} %X{HOST_IP} %X{HOST_NAME} %X{APPKEY} 

猜你喜欢

转载自my.oschina.net/u/2277088/blog/1621289