亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring項(xiàng)目如何實(shí)現(xiàn)帶請(qǐng)求鏈路id的日志記錄

 更新時(shí)間:2024年12月19日 08:49:12   作者:名一  
我們?cè)谧鲰?xiàng)目的時(shí)候通常需要通過(guò)請(qǐng)求日志來(lái)排查定位線(xiàn)上問(wèn)題,如果日志比較多而我們又需要查找整個(gè)請(qǐng)求的全部日志的時(shí)候會(huì)比較困難,下面我們就來(lái)看看如何用java aop實(shí)現(xiàn)請(qǐng)求id的日志記錄吧

我們?cè)谧鰆ava項(xiàng)目的時(shí)候通常需要通過(guò)請(qǐng)求日志來(lái)排查定位線(xiàn)上問(wèn)題,在日志比較多而我們又需要查找整個(gè)請(qǐng)求的全部日志的時(shí)候會(huì)比較困難。所以,就需要在日志記錄的時(shí)候講同一個(gè)請(qǐng)求的關(guān)鍵日志用同一個(gè)唯一標(biāo)識(shí)串聯(lián)起來(lái)。這樣查找的時(shí)候就會(huì)比較好查找。下面來(lái)用java aop實(shí)現(xiàn)請(qǐng)求id的日志記錄。(該支持子線(xiàn)程繼承主線(xiàn)程請(qǐng)求id)

一:首先我們需要一個(gè)日志請(qǐng)求鏈路id切面類(lèi)

注意:如果不考慮多線(xiàn)程則(第二步和第三步可以不要)

package com.iMagine.iMagine_pro.aop;

import com.iMagine.iMagine_common.utils.UUIDUtil;
import com.iMagine.iMagine_pro.utils.TokenUtil;
import lombok.extern.slf4j.Slf4j;
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;


/**
 * @author 名一
 * @ClassName TraceIdAspect
 * @description: 日志請(qǐng)求鏈路id切面處理
 * @datetime 2024年 12月 16日 14:28
 * @version: 1.0
 */
@Slf4j
@Aspect
@Component
public class TraceIdAspect {
    
    /** 鏈路追蹤id */
    public final static String TRACE_ID = "TRACE_ID";
    /** 用戶(hù) */
    public final static String USER = "USER";
    
    /**
     * 鏈路id切點(diǎn)定義
     */
    @Pointcut("execution(* com.iMagine.iMagine_pro.controller.*.*(..))")
    public void TraceIdCut() {

    }

    /**
     * 鏈路id添加
     */
    @Before("TraceIdCut()")
    public void cutProcessBefore() {
        MDC.put(TRACE_ID, UUIDUtil.getUUID());
        //以下代碼為記錄用戶(hù)信息,方便更直觀(guān)的識(shí)別日志操作人信息。若不需要可以將下面部分刪除
        String nickname = TokenUtil.getNicknameByToken();
        if (null == nickname){
            nickname = "游客訪(fǎng)問(wèn)";
        }
        MDC.put(USER, nickname);
    }

    /**
     * 鏈路id清除
     */
    @After("TraceIdCut()")
    public void cutProcessAfter() {
        MDC.clear();
    }
}
package com.iMagine.iMagine_common.utils;

import java.util.UUID;

/**
 * @author 名一
 * @ClassName UUIDUtil
 * @description: UUID工具類(lèi)
 * @datetime 2024年 04月 23日 11:49
 * @version: 1.0
 */
public class UUIDUtil {

    /**
     * 獲取UUID
     *
     * @return
     */
    public static String getUUID() {
        //生產(chǎn)uuid并去掉uuid的短橫線(xiàn)
        return UUID.randomUUID().toString().replace("-", "");
    }
}

二:創(chuàng)建一個(gè)處理多線(xiàn)程鏈路追蹤的工具類(lèi)

package com.iMagine.iMagine_common.utils;

import com.iMagine.iMagine_common.constant.SysConstant;
import org.slf4j.MDC;

import java.util.Map;

/**
 * @author 名一
 * @ClassName ThreadMdcUtil
 * @description: 多線(xiàn)程鏈路追蹤工具類(lèi)
 * @datetime 2024年 12月 16日 14:57
 * @version: 1.0
 */
public class ThreadMdcUtil {

    // 獲取唯一性標(biāo)識(shí)
    public static String generateTraceId() {
        return UUIDUtil.getUUID();
    }

    public static void setTraceIdIfAbsent() {
        if (MDC.get(SysConstant.TRACE_ID) == null) {
            MDC.put(SysConstant.TRACE_ID, generateTraceId());
        }
    }

    /**
     * 用于父線(xiàn)程向線(xiàn)程池中提交任務(wù)時(shí),將自身MDC中的數(shù)據(jù)復(fù)制給子線(xiàn)程
     *
     * @param runnable  要執(zhí)行的線(xiàn)程
     * @param context   父線(xiàn)程的mdc
     * @return          鏈路id傳遞后的任務(wù)
     */
    public static Runnable wrap(final Runnable runnable, final Map<String, String> context) {
        return () -> {
            if (context == null) {
                MDC.clear();
            } else {
                MDC.setContextMap(context);
            }
            setTraceIdIfAbsent();
            try {
                runnable.run();
            } finally {
                MDC.clear();
            }
        };
    }
}

三:在往線(xiàn)程池放任務(wù)的時(shí)候做請(qǐng)求鏈路id傳遞

/**
 * 線(xiàn)程池添加 [ai server 相關(guān)操作(psot)]任務(wù)
 *
 * @param task 添加的任務(wù)
 */
public static void addSendPostThreadToThreadPool(SendPostThread task) {
    log.info("addSendPostThreadToThreadPool pool:{}, task:{}", pool, task);
    try {
        pool.execute(ThreadMdcUtil.wrap(task, MDC.getCopyOfContextMap()));
    } catch (Exception e) {
        log.error("addSendPostThreadToThreadPool error pool:{}, task:{}, e:", pool, task, e);
    }
}

四:在日志配置里將鏈路追蹤id加入日志輸出格式的配置里

<!-- 日志輸出格式 (其中%X{TRACE_ID}是mdc里邊鏈路請(qǐng)求id的key,user-%X{USER}是用戶(hù)信息的key)-->
<property name="ENCODER_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %X{TRACE_ID} user-%X{USER} %-5level %logger{32}-[%line] - %msg%n"/>

到此spring 項(xiàng)目實(shí)現(xiàn)帶請(qǐng)求鏈路id的日志記錄就完成了

到此這篇關(guān)于Spring項(xiàng)目如何實(shí)現(xiàn)帶請(qǐng)求鏈路id的日志記錄的文章就介紹到這了,更多相關(guān)Spring請(qǐng)求id日志記錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Swagger注解-@ApiModel和@ApiModelProperty的用法

    Swagger注解-@ApiModel和@ApiModelProperty的用法

    這篇文章主要介紹了Swagger注解-@ApiModel和@ApiModelProperty的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • java?讀寫(xiě)鎖的使用及它的優(yōu)點(diǎn)

    java?讀寫(xiě)鎖的使用及它的優(yōu)點(diǎn)

    這篇文章主要介紹了java?讀寫(xiě)鎖的使用及它的優(yōu)點(diǎn),讀寫(xiě)鎖的特點(diǎn)就是是讀讀不互斥、讀寫(xiě)互斥、寫(xiě)寫(xiě)互斥,下面具體使用分享需要的小伙伴可以參考一下
    2022-05-05
  • 詳解 Java Maximum redirects (100) exceeded

    詳解 Java Maximum redirects (100) exceeded

    這篇文章主要介紹了詳解 Java Maximum redirects (100) exceeded的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • 詳解如何給SpringBoot部署的jar包瘦身

    詳解如何給SpringBoot部署的jar包瘦身

    這篇文章主要介紹了如何給SpringBoot部署的jar包瘦身,如今迭代發(fā)布是常有的事情,每次都上傳一個(gè)如此龐大的文件,會(huì)浪費(fèi)很多時(shí)間,接下來(lái)小編就以一個(gè)小項(xiàng)目為例,來(lái)演示如何給jar包瘦身,需要的朋友可以參考下
    2023-07-07
  • 從HelloWorld和文檔注釋開(kāi)始入門(mén)Java編程

    從HelloWorld和文檔注釋開(kāi)始入門(mén)Java編程

    這篇文章主要介紹了從HelloWorld和文檔注釋開(kāi)始入門(mén)Java編程,涉及到Javadoc工具的使用,需要的朋友可以參考下
    2015-10-10
  • Java模板動(dòng)態(tài)生成word文件的方法步驟

    Java模板動(dòng)態(tài)生成word文件的方法步驟

    最近項(xiàng)目中需要根據(jù)模板生成word文檔,模板文件也是word文檔。本文使用使用freemarker模板生成word文件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 使用?EasyCode生成springboot+mybatis基礎(chǔ)程序的實(shí)現(xiàn)示例

    使用?EasyCode生成springboot+mybatis基礎(chǔ)程序的實(shí)現(xiàn)示例

    本文主要介紹了使用?EasyCode生成springboot+mybatis基礎(chǔ)程序的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • RocketMQ實(shí)現(xiàn)隨緣分BUG小功能示例詳解

    RocketMQ實(shí)現(xiàn)隨緣分BUG小功能示例詳解

    這篇文章主要為大家介紹了RocketMQ實(shí)現(xiàn)隨緣分BUG小功能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • SpringBoot整合UEditor的示例代碼

    SpringBoot整合UEditor的示例代碼

    本篇文章主要介紹了SpringBoot整合UEditor的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • 深入理解Java 對(duì)象和類(lèi)

    深入理解Java 對(duì)象和類(lèi)

    下面小編就為大家?guī)?lái)一篇深入理解Java 對(duì)象和類(lèi)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-05-05

最新評(píng)論