原文鏈接:https://blog.csdn.net/xxssyyyyssxx/article/details/81135383
在log-pattern中增加 %X{METHOD-INVOKE-KEY}
在入口方法或者攔截器中增加
MDC.put("METHOD-INVOKE-KEY", logId);
和
MDC.remove("METHOD-INVOKE-KEY");
就可以實(shí)現(xiàn)方法調(diào)用鏈的日志使用同一個logId來標(biāo)識,方便在日志中查找方法調(diào)用鏈。
package interceptor;
import org.slf4j.MDC;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;
/**
* 日志處理攔截器
*
* @author duxuefu
* @since 2020-04-14
*/
public class LogInterceptor extends HandlerInterceptorAdapter {
public final static String METHOD_INVOKE_KEY = "METHOD-INVOKE-KEY";
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
Object o) throws Exception {
MDC.put(METHOD_INVOKE_KEY, UUID.randomUUID().toString());
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
MDC.remove(METHOD_INVOKE_KEY);
super.afterCompletion(request, response, handler, ex);
}
}
切面方法
package aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import java.util.UUID;
/**
* 類日志切面
*
* @author duxuefu
* @since 2020-11-18
*/
@Aspect
@Component
public class LogAspect {
public final static String METHOD_INVOKE_KEY = "METHOD-INVOKE-KEY";
/**
* Pointcut 切入點(diǎn)
* 匹配cn.controller包下面的所有方法
*/
@Pointcut("execution(public * com..*Controller.*(..))")
public void webLog() {
}
/**
* 方法執(zhí)行前
*/
@Before(value = "webLog()")
public void before(JoinPoint joinPoint) {
MDC.put(METHOD_INVOKE_KEY, UUID.randomUUID().toString());
}
/**
* 方法執(zhí)行結(jié)束,不管是拋出異常或者正常退出都會執(zhí)行
*/
@After(value = "webLog()")
public void after(JoinPoint joinPoint) {
MDC.remove(METHOD_INVOKE_KEY);
}
}
logback-spring.xml 中的配置,主要關(guān)注%X{METHOD-INVOKE-KEY}部分
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度%msg:日志消息,%n是換行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %X{METHOD-INVOKE-KEY} %-5level %logger{50}[%line] - %msg%n</pattern>
</encoder>
package handler;
import interceptor.LogInterceptor;
import org.slf4j.MDC;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
/**
* 返回對象處理
*
* @author duxuefu
* @since 2020-04-14
*/
@RestControllerAdvice
public class ResponseHandler implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
return true;
}
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, org.springframework.http.server.ServerHttpRequest serverHttpRequest, org.springframework.http.server.ServerHttpResponse serverHttpResponse) {
// TODO BasicResult是業(yè)務(wù)實(shí)現(xiàn)中的基礎(chǔ)返回對象,可以自己實(shí)現(xiàn),統(tǒng)一返回業(yè)務(wù)標(biāo)識:sn
if (o instanceof BasicResult) {
((BasicResult) o).setSn(MDC.get(LogInterceptor.METHOD_INVOKE_KEY));
}
return o;
}
}
詳細(xì)方法參考:
原文鏈接:https://blog.csdn.net/xxssyyyyssxx/article/details/81135383