转换词

http://logback.qos.ch/manual/layouts.html#conversionWord

MDC

用来在日志中映射诊断上下文信息

在 xml 中配置

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> 
  <layout>
    <Pattern>%X{client} %X{number} - %m%n</Pattern>
  </layout> 
</appender>

%X{key} : 表示在 MDC.put(key, value) 输出 key 的值

使用方式

手工处理

MDC.put("client", "客户client");
MDC.put("number", "客户1");
log.info("hello -> ");

// clean
MDC.remove("client");
MDC.remove("number");

默认的 Filter

MDC 自带有一个 MDCInsertingServletFilter , 确保它在所有 Filter 之前使用即可

在 Spring Boot 中典型的用法

@Bean
public FilterRegistrationBean<MDCInsertingServletFilter> mdcFilterBean() {
  FilterRegistrationBean<MDCInsertingServletFilter> registration = new FilterRegistrationBean<>();
  registration.setFilter(new MDCInsertingServletFilter());
  registration.addUrlPatterns("/*");
  registration.setName("mdcFilter");
  registration.setOrder(1);
  return registration;

}

可用的 MDC 变量

"req.remoteHost"
"req.userAgent"
"req.requestURI"
"req.queryString"
"req.requestURL"
"req.method"
"req.xForwardedFor"

例如在 xml 中这样子配置

%X{req.remoteHost} %X{req.requestURI}%n%d - %m%n

在线程池中使用

在提交到线程池前, 调用 MDC.getCopyOfContextMap() , 然后当线程执行时, 第一个执行的逻辑应该是 MDC.setContextMapValues()

在 Spring Boot 中典型用法

MdcTaskDecorator.java

import org.slf4j.MDC;
import org.springframework.core.task.TaskDecorator;

import java.util.Map;

public class MdcTaskDecorator implements TaskDecorator {
    @Override
    public Runnable decorate(Runnable runnable) {
        final Map<String, String> contextMap = MDC.getCopyOfContextMap();
        return () -> {
            try {
                if (contextMap != null) {
                    MDC.setContextMap(contextMap);
                }
                runnable.run();
            } finally {
                MDC.clear();
            }
        };
    }
}
@Bean
public ThreadPoolTaskExecutor executor() {
  ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  executor.setTaskDecorator(new MdcTaskDecorator());
  executor.setWaitForTasksToCompleteOnShutdown(true);
  executor.initialize();
  return executor;
}

资料