MDC与Log4j无法正常工作

时间:2015-09-26 12:31:57

标签: java log4j spring-boot mdc

您好我想在日志模式中显示登录的用户ID,主机名,IP地址等。我正在使用log4j。我正在使用MDC。在我的主控制器中,我能够看到具有指定模式的日志但在其他文件日志中我无法看到模式,是否就像我在某个会话中设置了MDC并将上下文值再次放在其他控制器中? 请建议。

log4j.properties

log4j.rootLogger=INFO,CONSOLE,R
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=C:/Logs/Test.log
log4j.appender.R.ImmediateFlush=true
log4j.appender.R.Append=true
log4j.appender.R.MaxFileSize=10MB
log4j.appender.R.MaxBackupIndex=10
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d %X{ipAddress} %X{hostName} %X{Asif}- %c - %p - %m%n

---------------------------------
MainController.java
try {
        MDC.put("Asif", "Asif");
        MDC.put("ipAddress", request.getRemoteAddr());
        MDC.put("hostName", request.getServerName());
        logger.info("Context Info : " +    MDC.get("userId")+MDC.get("ipAddress")+MDC.get("hostName"));

    } finally {
        MDC.remove("ipAddress");
        MDC.remove("hostName");
        MDC.remove("Asif");
        MDC.clear();
    }

我也有其他不同的控制器。现在主控制器内部的记录器语句在日志模式中显示上下文信息,但在其他控制器中的其他日志消息中,它不显示上下文信息。

我的问题。 1.我是否需要在所有控制器中添加上下文信息? 2.有更好的方法吗? 我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

MDC属性将是“每个线程”。如果两个控制器不共享同一个线程,那么它们将没有MDC属性 - 这就是您所描述的情况。

请尝试以下操作。

创建过滤器:

public class MDCFilter implements Filter {
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        try {
            MDC.put("Asif", "Asif");
            MDC.put("ipAddress", request.getRemoteAddr());
            MDC.put("hostName", request.getServerName());
            chain.doFilter(request, response);
        } finally {
            MDC.remove("ipAddress");
            MDC.remove("hostName");
            MDC.remove("Asif");
            MDC.clear();
        }
    }
}

然后将其映射到所有servlet(web.xml)

<filter>
    <filter-name>MDCFilter</filter-name>
    <filter-class>{your package}MDCFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>MDCFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

通过执行上述操作,每个控制器/ servlet /端点都将具有您想要的MDC属性。

祝你好运!