国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

高效日志打印技巧,簡(jiǎn)潔又清晰

開(kāi)發(fā) 前端
不同的業(yè)務(wù)場(chǎng)景有不同的日志需求,一般情況下為了排查問(wèn)題方便,需要唯一標(biāo)識(shí)把一系列請(qǐng)求串聯(lián)起來(lái),使用 UserLog 注解+Aop ,自動(dòng)將這部分默認(rèn)參數(shù)放到日志中,可以簡(jiǎn)化業(yè)務(wù)日志打印,極大地提高了生產(chǎn)力。
為了更方便地排查問(wèn)題,電商交易系統(tǒng)的日志中需要記錄用戶(hù)id和訂單id等字段。然而,每次打印日志都需要手動(dòng)設(shè)置用戶(hù)id,這一過(guò)程非常繁瑣,需要想個(gè)辦法優(yōu)化下。
log.warn("user:{}, orderId:{} 訂單提單成功",userId, orderId);
log.warn("user:{}, orderId:{} 訂單支付成功",userId, orderId);
log.warn("user:{}, orderId:{} 訂單收到履約請(qǐng)求",userId, orderId);
log.warn("user:{}, orderId:{} 訂單履約成功",userId, orderId);

1、目標(biāo)

打印日志時(shí),自動(dòng)填充用戶(hù)id和訂單Id等通參,無(wú)需手動(dòng)指定

2、實(shí)現(xiàn)思路

  • 日志模板中聲明占位符 userId,orderId
  • 在業(yè)務(wù)入口將userId放入到線程ThreadLocal本地變量中。
  • 使用SpringAop + 注解 自動(dòng)將第二步的用戶(hù)信息放到線程上下文

3、配置日志變量,讀取上下文變量

%X{}可以自定義占位符,例如本例中 使用 userId:%X{userId} orderId:%X{orderId},定義了userId和orderId兩個(gè)占位符。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info">

    <Appenders>
        <Console name="consoleAppender" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{DEFAULT} [%t] %-5p - userId:%X{userId} orderId:%X{orderId} %m%n%ex" charset="UTF-8"/>
        </Console>
    </Appenders>
    <Loggers>
        <!-- Root Logger -->
        <AsyncRoot level="info" includeLocation="true">
            <appender-ref ref="consoleAppender"/>
        </AsyncRoot>
    </Loggers>
</Configuration>

4、基于MDC 將訂單和用戶(hù)信息放到線程的上下文Map

為了給每個(gè)請(qǐng)求添加唯一標(biāo)識(shí),用戶(hù)可將上下文信息放入MDC(Mapped Diagnostic Context)。

slfj 提供了MDC 類(lèi),可以將變量設(shè)置在線程上下文中,日志框架會(huì)自動(dòng)將線程上下文中的變量放置到日志占位符中。Slf4j 作為java日志標(biāo)準(zhǔn),log4j和logback都實(shí)現(xiàn)了slfj 日志標(biāo)準(zhǔn)。

MDC是基于每個(gè)線程進(jìn)行管理的,允許每個(gè)服務(wù)器線程具有不同的MDC標(biāo)記。MDC類(lèi)中的put()和get()操作僅影響當(dāng)前線程的MDC。其他線程中的MDC不會(huì)受到影響,所以可以理解MDC是基于ThreadLocal的Map。

例如下面這種方式,打印日志的效果是這樣的。

MDC.put("userId", userId);
MDC.put("orderId", orderId);
log.warn("訂單履約完成");

當(dāng)使用log.warn("訂單履約完成") 方式打印日志時(shí),代碼中會(huì)自動(dòng)包含userId和 訂單Id。

2024-08-17 21:35:38,284 [main] WARN  - userId:32894934895 orderId:8497587947594859232 訂單履約完成

接下來(lái),聲明一個(gè)注解加切面,自動(dòng)將用戶(hù)和訂單信息放到日志占位符中。

5、注解 + SpringAop,自動(dòng)將UserId放到MDC

通過(guò)注解的方式,在方法執(zhí)行之前自動(dòng)將UserId注入到MDC中。其中的難點(diǎn)在于如何獲取到UserId。

我的思路是,方法的入?yún)⒅锌隙ò薝serId。可以在注解中聲明UserId的獲取路徑,在切面中獲取到UserId,并將其注入到MDC中。

5.1 定義注解

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserLog {

   String userId() default "";
   
   String orderId() default "";
}

使用時(shí),要求輸入userId屬性的路徑。例如UserOrder中包含userId和orderId屬性,則像如下方式聲明。

@UserLog(userId = "userId", orderId = "orderId")
public void orderPerform(UserOrder order) {
   log.warn("訂單履約完成");
}

@Data
public static class UserOrder {
   String userId;
   String orderId;
}

5.2 定義切面

聲明注解的Aop切面,在方法執(zhí)行前,將UserId從入?yún)⒅腥〕鰜?lái),放到MDC中。全部代碼如下

@Aspect
@Component
public class UserLogAspect {

   @Pointcut("@annotation(UserLog) && execution(public * *(..))")
   public void pointcut() {
   }

   @Around(value = "pointcut()")
   public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
      //無(wú)參方法不處理
      Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
      Object[] args = joinPoint.getArgs();

      //獲取注解
      UserLog userLogAnnotation = method.getAnnotation(UserLog.class);
      if (userLogAnnotation != null && args != null && args.length > 0) {
         //使用工具類(lèi)獲取userId。
         String userId = String.valueOf(PropertyUtils.getProperty(args[0], userLogAnnotation.userId()));
         String orderId = String.valueOf(PropertyUtils.getProperty(args[0], userLogAnnotation.orderId()));
         // 放到MDC中
         MDC.put("userId", userId);
         MDC.put("orderId", orderId);
      }

      try {
         Object response = joinPoint.proceed();
         return response;
      } catch (Exception e) {
         throw e;
      } finally {
         //清理MDC
         MDC.clear();
      }

   }
}

5.3 關(guān)鍵代碼解讀

5.3.1 獲取UserLog注解

UserLog userLogAnnotation = method.getAnnotation(UserLog.class);

5.3.2 使用PropertyUtils.getProperty 獲取userId

PropertyUtils.getProperty(args[0], userLogAnnotation.userId())

要注意 PropertyUtils 是commons-beanutils提供的工具類(lèi),可以指定屬性的路徑,自動(dòng)提取屬性值。如果存在多層關(guān)系,可以使用 . 級(jí)聯(lián)取屬性值。

例如 info.userId,則從對(duì)象的info屬性中取userId屬性。

<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.4</version>
</dependency>

5.3.3 使用MDC設(shè)置變量和清除變量。

MDC.put("userId", userId);
MDC.clear();

6、驗(yàn)證使用效果

6.1 聲明業(yè)務(wù)Service

@Service
public class OrderService {
   public static final Logger log = LoggerFactory.getLogger(OrderService.class);
   
   @UserLog(userId = "userId", orderId = "orderId")
   public void orderPerform(UserOrder order) {
      log.warn("訂單履約完成");
   }

   @Data
   public static class UserOrder {
      String userId;
      String orderId;
   }
}

6.2 測(cè)試日志打印

@Test
public void testUserLog() {
   OrderService.UserOrder order = new OrderService.UserOrder();
   order.setUserId("32894934895");
   order.setOrderId("8497587947594859232");
   orderService.orderPerform(order);
}

6.3 日志效果

圖片圖片

7、總結(jié)

不同的業(yè)務(wù)場(chǎng)景有不同的日志需求,一般情況下為了排查問(wèn)題方便,需要唯一標(biāo)識(shí)把一系列請(qǐng)求串聯(lián)起來(lái),使用 UserLog 注解+Aop ,自動(dòng)將這部分默認(rèn)參數(shù)放到日志中,可以簡(jiǎn)化業(yè)務(wù)日志打印,極大地提高了生產(chǎn)力。

另外大家可以自行擴(kuò)展能力,例如自動(dòng)打印出入?yún)⑷罩荆詣?dòng)上報(bào)監(jiān)控打點(diǎn)等等。

責(zé)任編輯:武曉燕 來(lái)源: 一安未來(lái)
相關(guān)推薦

2024-01-30 08:54:05

JavaScript技巧代碼

2019-07-31 10:24:16

JavaScript瀏覽器口袋妖怪

2023-07-30 17:10:32

TypeScript開(kāi)發(fā)

2019-07-24 15:29:55

JavaScript開(kāi)發(fā) 技巧

2018-06-08 09:50:07

程序員開(kāi)發(fā)技巧Java

2025-02-27 10:20:49

2010-09-06 09:06:22

CSS

2012-12-25 09:45:08

PythonWeb

2021-01-19 13:10:29

ZshLinuxUbuntu

2021-03-16 09:48:51

FaustPython數(shù)據(jù)流

2024-11-04 09:47:59

2018-10-19 12:37:47

GitHub代碼開(kāi)發(fā)者

2025-10-31 00:30:00

.NET內(nèi)存優(yōu)化

2012-01-09 17:03:39

臺(tái)式機(jī)評(píng)測(cè)

2024-11-11 17:00:27

字典壓縮Python代碼

2024-12-19 09:05:13

Python鏈?zhǔn)秸{(diào)用

2011-05-06 09:07:19

惠普打印機(jī)

2025-11-04 09:31:44

2024-12-04 15:10:21

2024-03-28 14:29:46

JavaScript編程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

欧美日韩破处视频| 亚洲三级av| 中文字幕一区二区在线观看 | 亚洲日本中文字幕| 伊人75在线| 一区二区三区在线免费播放 | 国产视频九色蝌蚪| 韩国视频理论视频久久| 亚洲精品永久免费视频| 日韩精品一区二| 黄色成人在线观看| 91精品国产全国免费观看| 一区二区三区中文字幕| 欧美人妖视频| 国产欧美日产一区| 国产小视频在线| 国产做受69高潮| 动漫一区二区在线| 狠狠色狠色综合曰曰| 尤物tv在线精品| 久久久久久免费精品| 国产精品嫩模av在线| 国内三级在线观看| 亚洲精品久久久久久久久久久| 亚洲欧洲高清| 91九色国产在线| 国产精品vvv| 国产精品视频免费一区二区三区| 高清国产一区二区| 国产日韩在线| 亚洲第一区中文99精品| 激情五月激情综合网| 久久久久高清| 国产精品主播在线观看| 久久99精品国产一区二区三区| 九九久久精品视频| а√最新版天堂中文在线| 欧美极品美女视频| 午夜激情在线观看| 99国产精品视频免费观看一公开| 日本一区二区三区www| 色视频在线观看福利| 最新国产精品拍自在线播放 | 亚洲啊v在线观看| 亚洲国产欧美不卡在线观看 | 欧美成ee人免费视频| 美女免费视频一区| 大陆极品少妇内射aaaaa| 亚洲人成网站精品片在线观看| 天堂中文在线视频| 日韩av在线直播| 国产精品传媒| 国产日韩亚洲精品| 国内外成人在线| 亚洲另类第一页| 欧美在线你懂得| 国产三级电影在线播放| 欧美精品久久久久| 亚洲国产高清一区| 男人天堂1024| 欧洲在线/亚洲| 一区二区三区| 波多野结衣久草一区| 成人永久免费视频| 在线观看av中文| 在线观看日韩www视频免费| 色999国产精品| 永久免费精品视频网站| 一区二区三区在线视频观看| 欧美xxx黑人xxx水蜜桃| 91成人在线观看国产| 日本vs亚洲vs韩国一区三区| 好男人看片在线观看免费观看国语| 精品蜜桃在线看| 欧美美女视频| 色综合久久久久无码专区| 欧美日韩免费观看中文| 国产成年精品| 欧美一区少妇| 婷婷综合在线观看| 精品国产乱码一区二区三区| 欧美日韩亚洲一区二区三区四区| 亚洲人午夜精品天堂一二香蕉| 18aaaa精品欧美大片h| 国产精品亚洲欧美导航| 丁香六月久久综合狠狠色| av资源种子在线观看| 欧美精品久久久久久久免费观看| 日韩av二区在线播放| 在线观看国产福利视频| 欧美人与性动交| 精品一区二区三区香蕉蜜桃| 久久手机免费观看| 欧美亚洲成人精品| jiyouzz国产精品久久| 女人天堂av在线播放| 亚洲一区二区三区在线视频 | 日本久久一区二区| 免费看污污视频| 亚洲综合免费观看高清完整版在线 | 91精品啪在线观看国产60岁| 天堂av一区二区三区在线播放| 亚洲欧美日韩另类| 91亚洲国产| 不卡的av中文字幕| 日韩专区中文字幕| 精品中文av资源站在线观看| 69av在线| 亚洲综合在线小说| 亚洲黄色在线视频| 都市激情亚洲| 九色91popny| 久久91亚洲精品中文字幕| 粉嫩av一区二区三区粉嫩| 久草在线新免费首页资源站| 精品产品国产在线不卡| 精品欧美国产一区二区三区| 蜜桃精品wwwmitaows| 猫咪成人官网| 欧美性受xxxx白人性爽| 中文字幕一区二区三区精华液| 日本高清精品| 欧美自拍小视频| 欧美高清激情视频| 国产午夜精品在线观看| 久久这里只精品| 精品久久国产精品| 国内精品视频| 毛片在线播放视频| 亚洲欧洲国产伦综合| 国产精品系列在线播放| 在线观看网站免费入口在线观看国内 | 国产在线视频一区| 欧美日韩免费看| 久久精品久久久| 青青国产在线| 国产欧美一区二区视频| 欧美日本一道本在线视频| 久久亚洲精品伦理| a级片在线免费| 特级黄色录像片| 在线电影中文日韩| 91蜜桃传媒精品久久久一区二区| 一区二区三区欧洲区| 免费黄视频网站| 福利视频一区二区三区| 欧美一区二区视频免费观看| 久久电影网电视剧免费观看| 日韩成人亚洲| 国产97在线视频| 午夜久久久久久久久| 久久精品欧美一区| 黄色免费网站在线观看| 一区在线电影| 萌白酱国产一区二区| 亚洲欧美一区二区久久| 国产精品久久久久久久久久10秀| 欧美激情午夜| 日韩在线观看a| 欧美一区二区三区艳史| 色噜噜狠狠一区二区三区果冻| 日韩不卡一区二区| 自拍偷拍亚洲图片| 男女激情片在线观看| 免费看污久久久| 日韩有码在线电影| 精品久久久久人成| 精品一区二区三区视频| 成人在线视频中文字幕| 精品美女视频在线观看免费软件| 免费看啪啪网站| 亚洲91精品在线| 欧美日韩国产影片| 99久久精品一区二区| 成人免费看片39| 日本天码aⅴ片在线电影网站| 久久9精品区-无套内射无码| 91精品久久久久久久久久久久久久 | 日韩久久综合| bl视频在线免费观看| 日本成人免费| 欧美亚洲另类在线一区二区三区| 欧美成人性生活| 欧美综合一区二区| a美女胸又www黄视频久久| 91成人国产| 日韩三级成人| jzzjzzjzz亚洲成熟少妇| 国产偷人视频免费| 久久99精品久久久久久三级| 欧美噜噜久久久xxx| 91精品国产综合久久精品| 中文字幕av一区二区三区| 九色porny视频在线观看| 97中文在线| 亚洲精品自拍视频| 婷婷久久综合九色综合伊人色| 成a人片国产精品| 先锋a资源在线看亚洲| 要久久爱电视剧全集完整观看|