视线追踪,迟健男,机械工业出版社
178元
(需用券)
去购买 >

追踪日志
通过什么方式,可以在logger的输出结果上自动附加一个标识?
日常开发中,为了能够快速定位问题,通常需要在日志中记录请求url,请求方法,用户ID,请求ID等等等等。硬编码的形式log.info("requestUrl:{}, userId: {}......", requestUrl, userId);显然是无法满足要求的,这样实现工作量大,易出错,改动也极其不便。
解决方案
使用MDC只需要几行代码就能轻松应对上述需求。实现一个Filter,使用MDC.put(key, val)写入需要打印的参数。
import org.slf4j.MDC;
public class MDCFilter extends OncePerRequestFilter implements Filter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws
IOException,
ServletException {
try {
MDC.put("requestMethod", request.getMethod().toUpperCase());
MDC.put("requestUri", request.getRequestURI());
MDC.put("uuid", UUID.randomUUID().toString().replace("-", ""));
MDC.put("ip", request.getRemoteAddr());
User requestUser = (User) request.getAttribute(Constants.REQUEST_USER);
if (requestUser != null) {
MDC.put("uid", String.valueOf(requestUser.getId()));
}
} catch (Exception e) {
logger.error("init MDC error.", e);
}
try {
filterChain.doFilter(request, response);
} finally {
MDC.clear();
}
}
}
注册Filter
@Bean
public FilterRegistrationBean mdcFilter() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
registrationBean.setName("mdcFilter");
MDCFilter mdcFilter = new MDCFilter();
registrationBean.setFilter(mdcFilter);
registrationBean.addUrlPatterns("/*");
registrationBean.setOrder(100);
return registrationBean;
}
日志pattern配置,使用%X{} 取值。%X{requestMethod} %X{requestUri} %X{uuid} %X{uid}
${log.path}/log.log
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %X{requestMethod} %X{requestUri} %X{uuid} %X{uid} %logger{50} - %msg%n
UTF-8
${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log
10MB
15
打印效果
2020-05-23 01:59:27.028 INFO POST /api/login 5a7fa16b42e44f1395678f77fbbcad92 17552
最后附上文档 MDC文档
java 11官方入门(第8版)教材
79.84元
包邮
(需用券)
去购买 >

本文介绍了一种使用MDC简化日志记录的方法。通过实现Filter并利用MDC.put方法,可以自动在日志中附加请求方法、URL等关键信息,大幅减少硬编码的工作量并提高灵活性。
1449

被折叠的 条评论
为什么被折叠?



