SpringBoot查詢?nèi)罩荆禾砑尤罩靖檌d

1.起源:

(1)業(yè)務(wù)需求:

代碼的功能是寫一個api接口,完成與mysql的crud操作。
后臺使用SpringBoot+JdbcTemplate實現(xiàn)伊诵,并在controller層添加了一些請求丈冬、響應(yīng)、異常處理的日志币厕;

(2)問題產(chǎn)生:

由于該api接口是多方調(diào)用的列另,當(dāng)高并發(fā)場景調(diào)用這個api時,從controller層一路下來旦装,日志的記錄將會非骋逞茫混亂,所有業(yè)務(wù)日志都摻雜在一起阴绢。比如像下面這樣:

(3)一種解決方法:

當(dāng)產(chǎn)生異常日志時店乐,特別是高并發(fā)的情況下,作為服務(wù)端呻袭,你并不知道某條error日志報的錯對應(yīng)的是哪條請求眨八,除非將請求信息打印在日志中,但是仔細想想左电,這就需要所有需要添加日志的類都帶著請求信息廉侧,顯然這太難做到了页响,同時日志文件也將不堪重負。

2.更好的解決方案

有沒有想到過日志跟蹤呢段誊?如果不管是誰調(diào)用接口闰蚕,在其每次調(diào)用的時候,代碼都自動加上一個唯一的id該多好连舍,不管這次請求是到了service層没陡、dao層、甚至bean層索赏,只要是調(diào)用controller里面的接口盼玄,所有這條請求的日志流都加上了這個唯一的id,這樣再查找日志的時候参滴,將會很方便强岸。

而怎么才能在不影響已經(jīng)寫好業(yè)務(wù)邏輯的情況下,對日志流做統(tǒng)一處理呢砾赔?當(dāng)然是要想到AOP了~蝌箍!

具體操作如下:

(1)先配上aop的maven依賴(已經(jīng)有aop就不用再加了),這里要注意spring-aop的版本對應(yīng)上spring-core的版本:
     <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>4.3.10.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.13</version>
    </dependency>
(2)再添加AOP處理類~暴心!這里只針對controller層妓盲。(不太了解aop配置的需要補習(xí)一下基本的配置方法)
package com.tools.pincollect.common;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.UUID;
 
@Aspect
@Configuration
public class SpringAOP {
 
    private static final Logger logger = LoggerFactory.getLogger(SpringAOP.class);
 
    /**
     * 定義切點Pointcut
     * 第一個*號:表示返回類型, *號表示所有的類型
     * 第二個*號:表示類名专普,*號表示所有的類
     * 第三個*號:表示方法名悯衬,*號表示所有的方法
     * 后面括弧里面表示方法的參數(shù),兩個句點表示任何參數(shù)
     */
    @Pointcut("execution(*  com.tools.pincollect.controller.*.*(..))")
    public void executionService() {}
 
    /**
     * 方法調(diào)用之前調(diào)用
     * @param joinPoint
     */
    @Before(value = "executionService()")
    public void doBefore(JoinPoint joinPoint){
        String requestId = String.valueOf(UUID.randomUUID());
        MDC.put("requestId",requestId);
        logger.info("=====>@Before:請求參數(shù)為:{}",Arrays.toString(joinPoint.getArgs()));
    }
 
    /**
     * 方法之后調(diào)用
     * @param joinPoint
     * @param returnValue 方法返回值
     */
    @AfterReturning(pointcut = "executionService()",returning="returnValue")
    public void  doAfterReturning(JoinPoint joinPoint,Object returnValue){
        logger.info("=====>@AfterReturning:響應(yīng)參數(shù)為:{}",returnValue);
        // 處理完請求檀夹,返回內(nèi)容
        MDC.clear();
    }
}
(3)在項目resources目錄下的logback-spring.xml中修改日志pattern(不了解的話筋粗,這里需要補充下日志配置的知識),添加[%X{requestId}]炸渡,requestId就是在切面類中的MCD.put()方法中的key娜亿,如下圖所示:
   <pattern>
        [ %-5level] [%date{yyyy-MM-dd HH:mm:ss}] [%X{requestId}] %logger{96} [%line] - %msg%n
    </pattern>
添加了跟蹤id后的日志.png

有了跟蹤id,查找與定位日志是不是方便多了呢蚌堵?

3.究其原理

依賴的是log4j 和 logback 提供的一種方便在多線程條件下記錄日志的功能MDC(Mapped Diagnostic Context买决,映射調(diào)試上下文)。

MDC 可以看成是一個與當(dāng)前線程綁定的哈希表吼畏,可以往其中添加鍵值對督赤。MDC 中包含的內(nèi)容可以被同一線程中執(zhí)行的代碼所訪問。當(dāng)前線程的子線程會繼承其父線程中的 MDC 的內(nèi)容泻蚊。當(dāng)需要記錄日志時躲舌,只需要從 MDC 中獲取所需的信息即可。MDC 的內(nèi)容則由程序在適當(dāng)?shù)臅r候保存進去性雄。對于一個 Web 應(yīng)用來說孽糖,通常是在請求被處理的最開始保存這些數(shù)據(jù)枯冈。
具體內(nèi)容請參考:
https://blog.csdn.net/sunzhenhua0608/article/details/29175283

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市办悟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌滩褥,老刑警劉巖病蛉,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瑰煎,居然都是意外死亡铺然,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門酒甸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來魄健,“玉大人,你說我怎么就攤上這事插勤」潦荩” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵农尖,是天一觀的道長析恋。 經(jīng)常有香客問我,道長盛卡,這世上最難降的妖魔是什么助隧? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮滑沧,結(jié)果婚禮上并村,老公的妹妹穿的比我還像新娘。我一直安慰自己滓技,他們只是感情好哩牍,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著殖属,像睡著了一般姐叁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上洗显,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天外潜,我揣著相機與錄音,去河邊找鬼挠唆。 笑死处窥,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的玄组。 我是一名探鬼主播滔驾,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼谒麦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了哆致?” 一聲冷哼從身側(cè)響起绕德,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎摊阀,沒想到半個月后耻蛇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡胞此,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年臣咖,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漱牵。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡夺蛇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酣胀,到底是詐尸還是另有隱情刁赦,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布灵临,位于F島的核電站截型,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏儒溉。R本人自食惡果不足惜宦焦,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望顿涣。 院中可真熱鬧波闹,春花似錦、人聲如沸涛碑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒲障。三九已至歹篓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間揉阎,已是汗流浹背庄撮。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留毙籽,地道東北人洞斯。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像坑赡,于是被迫代替她去往敵國和親烙如。 傳聞我的和親對象是個殘疾皇子么抗,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容