最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用MDC快速查詢應用接口全部執(zhí)行日志

 更新時間:2023年01月08日 17:03:42   作者:程序員拾山  
這篇文章主要為大家介紹了使用MDC快速查詢應用接口全部執(zhí)行日志的方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

對于每一個開發(fā)者來說,查詢接口的執(zhí)行日志都是一個高頻率的操作,每當測試說接口有問題時,我們都需要去服務器或者日志系統(tǒng)上查報錯的原因。

一般情況下,我們會通過對應的關(guān)鍵字或者接口地址去查詢這個接口到底報了什么錯,但是這帶來一個問題,就是我們可能少打日志或者忘打某些關(guān)鍵字的日志,導致查詢記錄比較麻煩。

那么有沒有一種簡單高效的方法,即使我們在日志中不打印任何關(guān)鍵字,系統(tǒng)會自動生成一個關(guān)鍵字,讓我們一次性查詢出這個接口的所有l(wèi)og記錄呢?

MDC

MDC是日志門面框架SLF4J提供的一個類,可以提供在多線程情況下記錄日志的功能,log4j、logback、log4j2都有對這個類的實現(xiàn)。

從本質(zhì)上來說,MDC可以看做一個ThreadLocal,由于其線程安全的特性,可以讓我們輕松安全的保存數(shù)據(jù)。

MDC主要的API有clear()、get()、put()、remove()方法等,簡潔的api讓我們使用上手基本沒有難度。

如何使用

1,修改日志打印格式

以日志框架logback為例,在logback.xml中,找到日志打印規(guī)則的配置,添加**-%X{reqId}** 屬性,其中reqId可以任意指定,你寫其他的屬性也可以,博主這里演示指定為reqId。

<encoder>
  <pattern>-%X{reqId} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %file:%line %msg%n</pattern>
  <charset>UTF-8</charset>
</encoder>

2,添加過濾器MDCFilter

ps.使用攔截器也可以,效果是一樣的。對每個接口 做攔截。

@Component
@AllArgsConstructor
@Order(Ordered.HIGHEST_PRECEDENCE)
@Slf4j
public class MDCFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        try {
            //給每個請求接口生成一個requestId
            String requestId = RandomUtil.randomNumbers(10);
            //這里的reqId就是上面配置的,要保持一致
            MDC.put("reqId", "reqId:" + requestId);
            chain.doFilter(request, response);
        } finally {
            MDC.clear();
        }
    }
    @Override
    public void destroy() {
    }
}

經(jīng)過簡單的兩步就配置好了,下面我們看一下效果。

@PostMapping(value = "/mdcTest")
public ResponseEntity&lt;Object&gt; mdcTest(String id, String name) {
    log.info("測試日志打印,id={},name={}", id, name);
    log.info("測試日志打印1");
    log.info("測試日志打印2");
    log.info("測試日志打印3");
    log.info("測試日志打印4");
    return ResponseEntity.ok().build();
}

每一行日志都有一個關(guān)鍵字reqId:9723829830,這樣我們查詢?nèi)罩緯r只需要查詢關(guān)鍵字9723829830就可以直接查出來這個接口所有的執(zhí)行記錄了。

如果想更方便的話,也可以把這個關(guān)鍵字直接輸出到每一個接口的響應頭或者響應體中。

進階使用

對于普通的web應用我們可以直接攔截每個接口,自動生成一個請求id,那么對于微服務項目,一個接口可能會產(chǎn)生很多服務的調(diào)用,那如何一次性查出來所有系統(tǒng)內(nèi)的日志呢?

對于日志的搜集本文暫不考慮,咱們先說如何做請求id的傳遞。

其實也很簡單,當我們有多個系統(tǒng)間的調(diào)用時,把reqId放到request的header中進行傳遞,然后下游系統(tǒng)獲取這個id就可以了。

比如下方的攔截器:

public class LogInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //如果有上層調(diào)用就從header中取出上層的ID
        String traceId = request.getHeader("reqId");
        if (traceId == null) {
            //如果沒有,就生成一個默認的
            traceId = RandomUtil.randomNumbers(10);
        }
        MDC.put("reqId", traceId);
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception {
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        //調(diào)用結(jié)束后刪除
        MDC.remove("reqId");
    }
}

MDC存在的一些問題

我們在上文說過,MDC的本質(zhì)是ThreadLocal,它會把數(shù)據(jù)都綁定到當前線程上。但是當我們使用多線程的時候,就會帶來一個數(shù)據(jù)丟失的問題。

所以,我們需要進行線程間的數(shù)據(jù)傳遞,保證MDC數(shù)據(jù)不丟失。

以線程池傳遞數(shù)據(jù)為例,ThreadPoolTaskExecutor提供了一個taskDecorator裝飾器,通過這個屬性,我們就可以實現(xiàn)屬性的傳遞。

首先,定義一個MDCContextDecorator,

public class MDCContextDecorator implements TaskDecorator {
    @Override
    public Runnable decorate(Runnable runnable) {
        Map&lt;String,String&gt; previous = MDC.getCopyOfContextMap();
        return () -&gt; {
            try {
                if (previous != null) {
                    MDC.setContextMap(previous);
                }
                runnable.run();
            } finally {
                MDC.clear();
            }
        };
    }
}

然后設置線程池的taskDecorator屬性,

public ThreadPoolTaskExecutor executor() {
  ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  executor.setCorePoolSize(5);
  executor.setMaxPoolSize(20);
  //...其他屬性
  //設置線程屬性的自動傳遞
  executor.setTaskDecorator(new MDCContextDecorator());
  return executor;
}

最后

MDC的使用其實很簡單,對于我們查詢?nèi)罩疽埠苡袔椭瑧靡菜闶欠浅V泛了。有興趣的同學也可以去看一下它的內(nèi)部實現(xiàn),代碼也并不復雜。

以上就是使用MDC快速查詢應用接口全部執(zhí)行日志的詳細內(nèi)容,更多關(guān)于MDC查詢接口執(zhí)行日志的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java截取圖片示例

    java截取圖片示例

    這篇文章主要介紹了java截取圖片示例,把代碼中的圖片路徑改成自己的圖片,運行就可以看到效果了,需要的朋友可以參考下
    2014-03-03
  • MyBatis中關(guān)于SQL的寫法總結(jié)

    MyBatis中關(guān)于SQL的寫法總結(jié)

    這篇文章主要介紹了MyBatis中關(guān)于SQL的寫法總結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • IDEA運行SpringBoot項目的超詳細步驟截圖

    IDEA運行SpringBoot項目的超詳細步驟截圖

    在當前的開發(fā)中Spring Boot開發(fā)框架已經(jīng)成為主流,下面這篇文章主要給大家介紹了關(guān)于IDEA運行SpringBoot項目的超詳細步驟截圖,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2022-11-11
  • 分享令人目瞪口呆的?Java?代碼技巧

    分享令人目瞪口呆的?Java?代碼技巧

    這篇文章主要介紹了令人目瞪口呆的?Java?代碼技巧,本文從寫?Java?程序的小方面一直寫到大方面,來闡述了如何才能寫好?Java?程序,并告訴讀者們?nèi)绾尾拍芴岣咦陨淼木幋a水平,需要的朋友可以參考下
    2022-05-05
  • SpringBoot下使用自定義監(jiān)聽事件的流程分析

    SpringBoot下使用自定義監(jiān)聽事件的流程分析

    事件機制是Spring的一個功能,目前我們使用了SpringBoot框架,所以記錄下事件機制在SpringBoot框架下的使用,同時實現(xiàn)異步處理,這篇文章主要介紹了SpringBoot下使用自定義監(jiān)聽事件,需要的朋友可以參考下
    2023-08-08
  • Java實現(xiàn)隊列的三種方法集合

    Java實現(xiàn)隊列的三種方法集合

    這篇文章主要介紹了Java實現(xiàn)隊列的三種方法集合,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Java線程池隊列PriorityBlockingQueue原理分析

    Java線程池隊列PriorityBlockingQueue原理分析

    這篇文章主要介紹了Java線程池隊列PriorityBlockingQueue原理分析,PriorityBlockingQueue隊列是?JDK1.5?的時候出來的一個阻塞隊列,但是該隊列入隊的時候是不會阻塞的,永遠會加到隊尾,需要的朋友可以參考下
    2023-12-12
  • SSM框架流程及原理分析

    SSM框架流程及原理分析

    本文給大家分享小編一些心得體會,主要是學習SSM框架之后的收獲吧,重點給大家介紹SSM框架流程以及原理分析,通過圖文實例相結(jié)合給大家介紹的非常詳細,需要的朋友參考下吧
    2021-06-06
  • 解讀Jvm的內(nèi)存結(jié)構(gòu)與GC及jvm參數(shù)調(diào)優(yōu)

    解讀Jvm的內(nèi)存結(jié)構(gòu)與GC及jvm參數(shù)調(diào)優(yōu)

    這篇文章主要介紹了解讀Jvm的內(nèi)存結(jié)構(gòu)與GC及jvm參數(shù)調(diào)優(yōu)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • Spring Boot 項目啟動失敗的解決方案

    Spring Boot 項目啟動失敗的解決方案

    這篇文章主要介紹了Spring Boot 項目啟動失敗的解決方案,幫助大家更好的理解和學習使用Spring Boot,感興趣的朋友可以了解下
    2021-03-03

最新評論

涟源市| 北海市| 常山县| 宁陕县| 吉水县| 乃东县| 大方县| 公安县| 太和县| 旬邑县| 股票| 资兴市| 波密县| 班玛县| 谢通门县| 乐东| 赤水市| 麦盖提县| 理塘县| 鹤山市| 北碚区| 海林市| 高要市| 旌德县| 武安市| 读书| 浦北县| 保靖县| 静乐县| 新竹市| 浑源县| 电白县| 林西县| 中山市| 日照市| 通辽市| 广饶县| 古丈县| 大姚县| 吉隆县| 衡水市|