1.maven依赖
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
2.log4j.properties
log4j.rootLogger = info, stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} API_NAME:[%X{API_NAME}] UUID:[%X{UUID}] [ %t:%r ] - [ %p ] %m%n
3.Log4jUtils
public class Log4jUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(Log4jUtils.class);
private static final Map<String, String> TAGS = new HashMap<>();
static {
try {
TAGS.put("API_NAME", "SpringBoot-demo");
} catch (Exception e) {
throw new RuntimeException("init mdc tags error.", e);
}
}
public Log4jUtils() {
}
public static void initGlobalMDC() {
Iterator<Entry<String, String>> iterator = TAGS.entrySet().iterator();
while(iterator.hasNext()) {
Entry<String, String> entry = iterator.next();
MDC.put(entry.getKey(), entry.getValue());
}
}
}
4.Log4jFilter
public class Log4jFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(Log4jFilter.class);
public Log4jFilter() {
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
LOGGER.info("Log4jFilter init.");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
Log4jUtils.initGlobalMDC();
MDC.put("UUID", UUID.randomUUID().toString());
try {
chain.doFilter(request, response);
} finally {
MDC.clear();
}
}
@Override
public void destroy() {
LOGGER.info("Log4jFilter destroy.");
}
}
5.WebFilterConfig
@Configuration
public class WebFilterConfig {
@Bean
public FilterRegistrationBean log4jFilterRegistrationBean() {
FilterRegistrationBean<Log4jFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setName("log4jFilter");
Log4jFilter log4jFilter = new Log4jFilter();
registrationBean.setFilter(log4jFilter);
registrationBean.setOrder(0);
return registrationBean;
}
}
6.测试
@RestController
public class TestController {
private static final Logger LOGGER = LoggerFactory.getLogger(TestController.class);
@RequestMapping("/test")
@ResponseBody
public void test() {
LOGGER.info("test");
}
@RequestMapping("/sub_thread_test")
@ResponseBody
public void subThreadTest() {
LOGGER.info("sub_thread_test");
new Thread(() -> LOGGER.info("sub_thread_test run.")).start();
}
}
日志如下:
2018-12-07 15:21:52 API_NAME:[SpringBoot-demo] UUID:[df3e0d89-b547-48af-a7a7-d5aa1df4cd73] [ http-nio-8080-exec-5:11626 ] - [ INFO ] test
2018-12-07 15:22:20 API_NAME:[SpringBoot-demo] UUID:[483a0d14-9f98-4dbd-a312-1bd25f022401] [ http-nio-8080-exec-8:39609 ] - [ INFO ] sub_thread_test
2018-12-07 15:22:20 API_NAME:[SpringBoot-demo] UUID:[483a0d14-9f98-4dbd-a312-1bd25f022401] [ Thread-13:39625 ] - [ INFO ] sub_thread_test run.
注意:System.setProperty("log4j2.isThreadContextMapInheritable", "true") 别忘了它
源码:https://gitee.com/jsjack_wang/springboot-demo dev-mdc分支