利用Slf4j的MDC跟蹤方法調(diào)用鏈

原文鏈接: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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容