spring 添加拦截器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
@Component public class MDCFilter extends OncePerRequestFilter {
private static final String TRACEID = "traceId";
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { try { MDC.put(TRACEID, UUID.getUUIDString()); filterChain.doFilter(request, response); } finally { MDC.remove(TRACEID); } }
}
|
把filter生效
以前是使用的拦截器,但是方法如果报错后,清除mdc不执行,因为postHandler方法在方法异常时不执行。
日志格式中添加traceId
logback.xml
1
| <property name="log.pattern" value="%d{HH:mm:ss.SSS} -[%X{traceId}]- [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
统一返回格式中添加traceId
1 2 3 4 5
| public static final String TRACE_ID = "traceId"; public AjaxResult(int code, String msg) { super.put(TRACE_ID, MDC.get(TRACE_ID)); }
|
子线程传递工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import org.slf4j.MDC; import org.springframework.util.CollectionUtils;
import java.util.Map;
public class MDCUtil {
public static Runnable wrap(final Runnable runnable, final Map<String, String> context) { return () -> { if (CollectionUtils.isEmpty(context)) { MDC.clear(); } else { MDC.setContextMap(context); } try { runnable.run(); } finally { MDC.clear(); } }; }
}
|
子线程调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Test implements Runnable { private Integer i;
public Integer getI() { return i; }
public void setI(Integer i) { this.i = i; }
@Override public void run() { log.info("------------------------" + i); log.info("asdfafafafdasfsafdaf"); } }
Test test = new Test(); test.setI(22); Runnable runnable = MDCUtil.wrap(test, MDC.getCopyOfContextMap()); Thread thread = new Thread(runnable); thread.start();
|
线程池同上。
其他非http请求时使用traceId
1 2 3 4 5 6 7 8
| if (StringUtils.isEmpty(MDC.get("traceId"))) { MDC.put("traceId", UUID.getUUIDString()); } try { } finally { MDC.remove("traceId"); }
|