【问题标题】:MDC is not working Properly with Log4jMDC 无法与 Log4j 一起正常工作
【发布时间】:2015-09-26 12:31:56
【问题描述】:

您好,我想在日志模式中显示登录的用户 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.有没有更好的方法? 3.我错过了什么吗?

【问题讨论】:

    标签: java log4j spring-boot mdc


    【解决方案1】:

    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/endpoint 都将具有您想要的 MDC 属性。

    祝你好运!

    【讨论】:

    • 非常感谢卡里洛。
    • 你有相同的 Java 配置而不是 Spring MVC 中的 web.xml 吗?
    • @WebFilter(urlPatterns = {"/*"}, description = "MDC Filter") 添加到过滤器类并扫描。
    • 我们为什么要在 finally 中删除参数??
    • @DaveRanjan 我们删除了标头,因为 MDC 值不会自行删除,您必须手动完成,并且您不希望线程包含陈旧的 MDC 值
    猜你喜欢
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-14
    • 2020-08-19
    • 2013-02-06
    • 2019-02-02
    • 2021-10-15
    相关资源
    最近更新 更多