'%X {value}'在log4J打印中不起作用

时间:2019-05-28 11:07:52

标签: spring-boot log4j mdc

在执行此代码之后,我使用MDC来为我的Spring-Boot应用程序中的每个请求提供唯一的ID:

Slf4jMDCFilterConfiguration.java

@Data
@Configuration
public class Slf4jMDCFilterConfiguration {

    public static final String DEFAULT_RESPONSE_TOKEN_HEADER = "Response_Token";
    public static final String DEFAULT_MDC_UUID_TOKEN_KEY = "Slf4jMDCFilter.UUID";
    public static final String DEFAULT_MDC_CLIENT_IP_KEY = "Slf4jMDCFilter.ClientIP";

    private String responseHeader = DEFAULT_RESPONSE_TOKEN_HEADER;
    private String mdcTokenKey = DEFAULT_MDC_UUID_TOKEN_KEY;
    private String mdcClientIpKey = DEFAULT_MDC_CLIENT_IP_KEY;
    private String requestHeader = null;

    @Bean
    public FilterRegistrationBean servletRegistrationBean() {
        final FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        final Slf4jMDCFilter log4jMDCFilterFilter = new Slf4jMDCFilter(responseHeader, mdcTokenKey, mdcClientIpKey, requestHeader);
        registrationBean.setFilter(log4jMDCFilterFilter);
        registrationBean.setOrder(2);
        return registrationBean;
    }
}

Slf4jMDCFilter.java

@Data
@EqualsAndHashCode(callSuper = false)
@Component
public class Slf4jMDCFilter extends OncePerRequestFilter {

    private final Logger log = Logger.getLogger(getClass());

    private final String responseHeader;
    private final String mdcTokenKey;
    private final String mdcClientIpKey;
    private final String requestHeader;

    public Slf4jMDCFilter() {
        responseHeader = Slf4jMDCFilterConfiguration.DEFAULT_RESPONSE_TOKEN_HEADER;
        mdcTokenKey = Slf4jMDCFilterConfiguration.DEFAULT_MDC_UUID_TOKEN_KEY;
        mdcClientIpKey = Slf4jMDCFilterConfiguration.DEFAULT_MDC_CLIENT_IP_KEY;
        requestHeader = null;
    }

    public Slf4jMDCFilter(final String responseHeader, final String mdcTokenKey, final String mdcClientIPKey, final String requestHeader) {
        this.responseHeader = responseHeader;
        this.mdcTokenKey = mdcTokenKey;
        this.mdcClientIpKey = mdcClientIPKey;
        this.requestHeader = requestHeader;
    }

    @Override
    protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain)
            throws java.io.IOException, ServletException {
        try {
            final String token = extractToken(request);
            final String clientIP = extractClientIP(request);
            MDC.put(mdcClientIpKey, clientIP);
            MDC.put(mdcTokenKey, token);
            if (!StringUtils.isEmpty(responseHeader)) {
                response.addHeader(responseHeader, token);
            }
            chain.doFilter(request, response);
        } finally {            
            MDC.remove(mdcTokenKey);
            MDC.remove(mdcClientIpKey);
        }
    }

    private String extractToken(final HttpServletRequest request) {
        final String token;
        if (!StringUtils.isEmpty(requestHeader) && !StringUtils.isEmpty(request.getHeader(requestHeader))) {
            token = request.getHeader(requestHeader);
        } else {
            token = UUID.randomUUID().toString().toUpperCase().replace("-", "");
        }
        return token;
    }

    private String extractClientIP(final HttpServletRequest request) {
        final String clientIP;
        if (request.getHeader("X-Forwarded-For") != null) {
            clientIP = request.getHeader("X-Forwarded-For").split(",")[0];
        } else {
            clientIP = request.getRemoteAddr();
        }
        return clientIP;
    }

    @Override
    protected boolean isAsyncDispatch(final HttpServletRequest request) {
        return false;
    }

    @Override
    protected boolean shouldNotFilterErrorDispatch() {
        return false;
    }
}

log4j.properties

# Define the properties for file appender
log4j.appender.FILE.layout.conversionPattern=%X{Slf4jMDCFilter.UUID}|[%d{ISO8601}][%p][%t] %C{1} %x - %m%n
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.File=logs/AmericanWell-FRE.log
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.MaxFileSize=20MB
log4j.appender.FILE.MaxBackupIndex=20
log4j.appender.FILE.append=true

log4j.rootCategory=ALL, rollingFile

#CONSOLE Settings
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.conversionPattern=%X{Slf4jMDCFilter.UUID}|[%d{ISO8601}][%p][%t] %C{1} %x - %m%n

我的问题是,当我尝试使用%X{Slf4jMDCFilter.UUID}时,在日志文件和控制台中我得到的是空字符串。

这是我的日志的示例输出-正在生成令牌,但未打印该值:

|[2019-05-28 14:09:38,919][INFO][http-nio-8080-exec-1] Slf4jMDCFilter  - 0******************************************************************************* token = null
|[2019-05-28 14:09:38,921][INFO][http-nio-8080-exec-1] Slf4jMDCFilter  - 1******************************************************************************* token = 2A905F87CB84484B8EC05D6432D39303
|[2019-05-28 14:09:38,921][INFO][http-nio-8080-exec-1] Slf4jMDCFilter  - 2******************************************************************************* token = 2A905F87CB84484B8EC05D6432D39303
|[2019-05-28 14:09:38,997][INFO][http-nio-8080-exec-1] Slf4jMDCFilter  - 3******************************************************************************* token = 2A905F87CB84484B8EC05D6432D39303
|[2019-05-28 14:09:38,998][INFO][http-nio-8080-exec-1] Slf4jMDCFilter  - 4******************************************************************************* token = 2A905F87CB84484B8EC05D6432D39303
|[2019-05-28 14:09:38,998][INFO][http-nio-8080-exec-1] Slf4jMDCFilter  - 5******************************************************************************* token = null
|[2019-05-28 14:09:38,998][INFO][http-nio-8080-exec-1] Slf4jMDCFilter  - 6******************************************************************************* token = null
|[2019-05-28 14:09:38,999][INFO][http-nio-8080-exec-1] Slf4jMDCFilter  - 7******************************************************************************* token = null

我尝试了几种打印方法,但是没有任何效果。

我在这里缺少一些配置吗?

1 个答案:

答案 0 :(得分:0)

我也遇到了这个。问题是该项目中有多个MDC。

我正在使用org.slf4j.MDC编写上下文。使用%X{varname}的模式已设置为使用org.apache.log4j.MDC。 我将代码更改为使用org.apache.log4j.MDC,一切都很好。

相关问题