中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

我發現很多程序(xu)員都不會打日志。。。

你是小(xiao)阿(a)巴,剛入職的(de)低級程(cheng)序(xu)員,正在開發(fa)一個批量導(dao)入數據的(de)程(cheng)序(xu)。

沒想到,程(cheng)序剛(gang)上線(xian),產品經理就(jiu)跑(pao)過來說:小阿巴,用戶反饋你的程(cheng)序有 Bug,剛(gang)導入沒多久就(jiu)報錯中斷了!

你趕緊打開服務器,看著比你發量(liang)都少(shao)的報錯信息:

你一(yi)臉懵逼:只有這(zhe)點兒信息,我(wo)咋知道(dao)哪里出了問題啊?!

你只能(neng)硬著頭皮讓產品經理找用戶(hu)要數據(ju),然后一條(tiao)條(tiao)測(ce)試,看(kan)看(kan)是(shi)哪條(tiao)數據(ju)出(chu)了問題……

原(yuan)本大好的摸魚時光(guang),就這樣無了(le)。

這時,你的導師魚皮走了過來(lai),問道:小阿巴(ba),你是持矢了么(me)?臉色這么(me)難看?

你無奈地說:皮哥,剛才線上出(chu)了個 bug,我花了 8 個小時才定位到問題……

魚皮皺(zhou)了(le)皺(zhou)眉(mei):這么久?你沒打日(ri)志嗎(ma)?

你很是疑惑:誰(shui)是日志?為什么要打它(ta)?

魚皮嘆了口(kou)氣(qi):唉,難怪你(ni)(ni)要(yao)花(hua)這么久…… 來,我(wo)教你(ni)(ni)打日志!

?? 本文對應視頻版:

 

什么是(shi)日(ri)志(zhi)?

魚皮打開(kai)電腦(nao),給你看了一段代碼:

@Slf4j
public class UserService {
   public void batchImport(List<UserDTOuserList) {
       log.info("開始批量導入用戶,總數:{}", userList.size());
       
       int successCount 0;
       int failCount 0;
       
       for (UserDTO userDTO : userList) {
           try {
               log.info("正在導入用戶:{}", userDTO.getUsername());
               validateUser(userDTO);
               saveUser(userDTO);
               successCount++;
               log.info("用戶 {} 導入成功", userDTO.getUsername());
          } catch (Exception e) {
               failCount++;
               log.error("用戶 {} 導入失敗,原因:{}", userDTO.getUsername(), e.getMessage(), e);
          }
      }
       
       log.info("批量導入完成,成功:{},失敗:{}", successCount, failCount);
  }
}

你看著代碼里的 log.infolog.error,疑(yi)惑地問:這些 log 是干什么(me)的?

魚皮:這就(jiu)是打日志(zhi)。日志(zhi)用來(lai)記(ji)錄程序運行時的狀態(tai)和信息,這樣(yang)當系統出(chu)現問題(ti)時,我(wo)們(men)可以(yi)通過日志(zhi)快速(su)定位問題(ti)。

你(ni)若有所思:哦(e)?還可(ke)以這(zhe)樣!如(ru)果當初(chu)我的代碼里有這(zhe)些(xie)日(ri)志(zhi),一眼就(jiu)定位到(dao)問題(ti)了…… 那我應(ying)該怎么打日(ri)志(zhi)?用什么技術(shu)呢?

 

怎么(me)打日志?

魚皮:每種編程語言都有很(hen)多日志(zhi)(zhi)框架和(he)工具(ju)庫,比如 Java 可以(yi)選(xuan)用(yong)(yong) Log4j 2、Logback 等(deng)等(deng)。咱們公司用(yong)(yong)的(de)是(shi) Spring Boot,它默(mo)認(ren)集(ji)成了(le) Logback 日志(zhi)(zhi)框架,你直接用(yong)(yong)就(jiu)行,不(bu)用(yong)(yong)再引入額外的(de)庫了(le)~

日志框(kuang)架的使用非(fei)常簡單,先獲取到 Logger 日志對象(xiang)。

1)方法(fa) 1:通過 LoggerFactory 手動獲取 Logger 日志對(dui)象(xiang):

public class MyService {
   private static final Logger logger LoggerFactory.getLogger(MyService.class);
}

2)方法 2:使用 this.getClass 獲(huo)取當前類(lei)的類(lei)型,來創建 Logger 對象:

public class MyService {
   private final Logger logger LoggerFactory.getLogger(this.getClass());
}

然后調用 logger.xxx(比如 logger.info)就能(neng)輸出(chu)日(ri)志了(le)。

public class MyService {
   private final Logger logger LoggerFactory.getLogger(this.getClass());
?
   public void doSomething() {
       logger.info("執行了一些操作");
  }
}

效果如(ru)圖:

 

小阿巴(ba):啊,每個需要打(da)日志的類都要加上這行代碼么?

魚皮:還有更簡單的方式,使用 Lombok 工具庫提供的 @Slf4j 注解(jie),可以(yi)自動(dong)(dong)為當前類生成日志對象,不用手動(dong)(dong)定義啦。

@Slf4j
public class MyService {
   public void doSomething() {
       log.info("執行了一些操作");
  }
}

上面的代碼等同(tong)于 “自動(dong)為當前類生成(cheng)日志對象”:

private static final org.slf4j.Logger log 
   org.slf4j.LoggerFactory.getLogger(MyService.class);

 

你(ni)咧嘴一笑:這(zhe)個好(hao),爽爽爽!

等等,不對,我直接用 Java 自帶的 System.out.println 不也能輸出信息么?何必多(duo)此一(yi)舉?

System.out.println("開始導入用戶" user.getUsername());

 

魚皮搖了(le)搖頭:千萬別(bie)這(zhe)么干!

首先,System.out.println 是一個(ge)同步方法,每次調(diao)用(yong)都會導致耗時的 I/O 操作(zuo),頻繁(fan)調(diao)用(yong)會影響(xiang)程序的性能。

而且它只能輸出信息到控制臺,不能靈活控制輸出位置、輸出格式、輸出時機等等。比如你現在想看三天前的日志,System.out.println 的(de)輸(shu)出(chu)早(zao)就被刷沒了(le),你(ni)還得浪費(fei)時間(jian)找半天。

 

你恍然大悟:原(yuan)來如此!那(nei)使用日(ri)志框(kuang)架就能解決這些問題嗎?

魚皮點點頭:沒錯,日(ri)(ri)志(zhi)(zhi)框架(jia)提供了豐富的打日(ri)(ri)志(zhi)(zhi)方法,還可以通(tong)過修改日(ri)(ri)志(zhi)(zhi)配置文(wen)件(jian)來隨心(xin)所(suo)欲地調教(jiao)日(ri)(ri)志(zhi)(zhi),比如把日(ri)(ri)志(zhi)(zhi)同時輸出到控制臺和文(wen)件(jian)中、設(she)置日(ri)(ri)志(zhi)(zhi)格式、控制日(ri)(ri)志(zhi)(zhi)級別等(deng)(deng)等(deng)(deng)。

在下苦心研究日志多年,沉淀了打日志的 8 大邪修秘法,先(xian)傳(chuan)授(shou)你 2 招最基(ji)礎的吧。

 

打日志的 8 大(da)最佳實踐

1、合理選擇(ze)日志級(ji)別

第一招,日志分(fen)級。

你(ni)好奇道:日志還有(you)級(ji)別?蘋果日志、安卓日志?

魚皮(pi)給(gei)了你(ni)一(yi)巴(ba)掌(zhang):可不要(yao)亂說,日志的(de)級別是按照重要(yao)程(cheng)度進行劃分的(de)。

其中 DEBUG、INFO、WARN 和 ERROR 用的最多。

  • 調(diao)試用(yong)的詳細信(xin)息(xi)用(yong) DEBUG

  • 正(zheng)常的業務流程用 INFO

  • 可能有問題但不影響主流(liu)程的(de)用(yong) WARN

  • 出(chu)現異常或錯誤(wu)的(de)用 ERROR

log.debug("用戶對象的詳細信息:{}", userDTO);  // 調試信息
log.info("用戶 {} 開始導入", username);  // 正常流程信息
log.warn("用戶 {} 的郵箱格式可疑,但仍然導入", username);  // 警告信息
log.error("用戶 {} 導入失敗", username, e);  // 錯誤信息

 

你(ni)撓(nao)了撓(nao)頭:俺(an)直接全用(yong) DEBUG 不行么(me)?

魚皮搖(yao)了搖(yao)頭(tou):如(ru)果所有信息(xi)(xi)都用同(tong)一級別,那出了問題時,你怎么(me)快速找到錯誤信息(xi)(xi)?

在生(sheng)產環(huan)境(jing),我(wo)們通常(chang)會把日志級別調高(比如 INFO 或 WARN),這樣 DEBUG 級別的日志就(jiu)不會輸(shu)出了,防(fang)止重要信息被無用日志淹(yan)沒。

你點點頭:俺明白了,不同(tong)的(de)場景用不同(tong)的(de)級(ji)別!

 

2、正(zheng)確記錄日志(zhi)信息

魚皮:沒錯,下面教你第二招。你注意到我剛才寫的日志里有一對大括號 {} 嗎(ma)?

log.info("用戶 {} 開始導入", username);

你(ni)回憶了一(yi)下:對哦(e),那是啥啊?

魚皮:這叫參數化日志。{} 是一個(ge)占位符,日(ri)志(zhi)框架會(hui)在(zai)運行時(shi)自動把后面的參(can)數值替換進去。

你撓了撓頭:我直(zhi)接用字符串拼(pin)接不(bu)行嗎?

log.info("用戶 " username " 開始導入");

魚(yu)皮搖搖頭:不推薦。因為字符(fu)串拼接是在調(diao)用 log 方法之前就執行的,即使這條日志最終不被(bei)輸出,字符(fu)串拼接操(cao)作還是會執行,白(bai)白(bai)浪(lang)費(fei)性能。

 

你點點頭:確實,而(er)且參數化(hua)日志(zhi)比(bi)字符串拼接看起(qi)來舒服~

 

魚(yu)皮(pi):沒錯(cuo)。而(er)且當你要輸(shu)出異常(chang)信息時,也(ye)可(ke)以(yi)使用參數化日志:

try {
   // 業務邏輯
catch (Exception e) {
   log.error("用戶 {} 導入失敗", username, e);  // 注意這個 e
}

這樣日志(zhi)框架會同時記錄上下文信(xin)(xin)息和完整(zheng)的異常(chang)堆棧信(xin)(xin)息,便于(yu)排查問題。

你抱拳:學會了,我這就去打日志!

 

3、把控時(shi)機和(he)內容

很快,你給批量導入(ru)程序(xu)的(de)代碼加上了日志:

@Slf4j
public class UserService {
   public BatchImportResult batchImport(List<UserDTOuserList) {
       log.info("開始批量導入用戶,總數:{}", userList.size());
       int successCount 0;
       int failCount 0;
       for (UserDTO userDTO : userList) {
           try {
               log.info("正在導入用戶:{}", userDTO.getUsername());   
               // 校驗用戶名
               if (StringUtils.isBlank(userDTO.getUsername())) {
                   throw new BusinessException("用戶名不能為空");
              }
               // 保存用戶
               saveUser(userDTO);
               successCount++;
               log.info("用戶 {} 導入成功", userDTO.getUsername());
          } catch (Exception e) {
               failCount++;
               log.error("用戶 {} 導入失敗,原因:{}", userDTO.getUsername(), e.getMessage(), e);
          }
      }
       log.info("批量導入完成,成功:{},失敗:{}", successCount, failCount);
       return new BatchImportResult(successCount, failCount);
  }
}

 

光做這點還不夠(gou),你還翻(fan)出了之前(qian)的屎山代碼,想給每個文件都(dou)打打日志。

 

但打著打著,你就(jiu)不(bu)耐煩了:每段代碼都要打日志,好累啊!但是不(bu)打日志又怕出問題(ti),怎么辦才好?

魚皮(pi)笑道:好問題,這就(jiu)是我要教你的第三招 —— 把握打日志的時機(ji)。

對于重要的業務功能,我建議采用防御性編程,先多多打日志。比如在方(fang)法(fa)代碼的(de)入口(kou)和出(chu)口(kou)記錄參數和返回值、在每個關鍵(jian)步(bu)驟記錄執(zhi)行狀態,而(er)不是等(deng)出(chu)了問題無法(fa)排查(cha)的(de)時(shi)候才追(zhui)悔莫及。之后可以再(zai)慢(man)慢(man)移(yi)除掉不需(xu)要(yao)的(de)日志(zhi)。

 

你(ni)嘆了(le)口氣:這我(wo)(wo)知道,但每個方法都打日志,工(gong)作量太大,都影響我(wo)(wo)摸魚了(le)!

魚皮(pi):別擔心,你可以利(li)用 AOP 切(qie)面編(bian)程,自動給(gei)每個業(ye)務(wu)方法的(de)執行前后添(tian)加(jia)日志,這樣就不會錯過任何一次調(diao)用信息(xi)了。

 

你(ni)雙眼放(fang)光:這(zhe)個好,爽爽爽!

 

魚皮:不過(guo)這樣(yang)做也(ye)有一個缺(que)點,注(zhu)意不要在日志(zhi)中記錄了敏(min)感信息,比如用戶(hu)密碼。萬一你的日志(zhi)不小(xiao)心泄露出去,就相當(dang)于泄露了大(da)量用戶(hu)的信息。

你拍拍胸脯(fu):必須的!

 

4、控制(zhi)日志(zhi)輸出(chu)量

一個星期后(hou),產(chan)品(pin)經(jing)理又來(lai)找你了:小阿巴,你的批(pi)量導入功(gong)能又報錯啦(la)!而且怎么感(gan)覺程序變慢了?

你(ni)完全不慌,淡定地(di)打(da)開服(fu)務器(qi)的日(ri)志文件。結果瞬(shun)間呆住了……

好家伙(huo),滿(man)屏都(dou)是(shi)密密麻麻的日志(zhi),這可怎(zen)么看啊?!

魚(yu)皮(pi)看了看你(ni)的代碼,搖(yao)了搖(yao)頭:你(ni)現(xian)在(zai)每導入一(yi)條(tiao)數據(ju)都要打(da)一(yi)些日(ri)志(zhi),如果用戶導入 10 萬條(tiao)數據(ju),那就是幾十萬條(tiao)日(ri)志(zhi)!不僅刷屏,還會影(ying)響性能。

你(ni)有點委屈:不(bu)是(shi)你(ni)讓我(wo)多(duo)打日志的么?那我(wo)應該怎么辦?

魚(yu)皮:你需要(yao)控制(zhi)日(ri)志的輸出量。

1)可以添加(jia)條件來控制,比如每處理 100 條數據時才記錄一次:

if ((1) 100 == 0) {
   log.info("批量導入進度:{}/{}", 1, userList.size());
}

2)或者在循環中利用(yong) StringBuilder 進行字(zi)符串拼接,循環結束(shu)后統一輸出:

StringBuilder logBuilder new StringBuilder("處理結果:");
for (UserDTO userDTO : userList) {
   processUser(userDTO);
   logBuilder.append(String.format("成功[ID=%s], ", userDTO.getId()));
}
log.info(logBuilder.toString());

3)還可以通過修改日志配置文(wen)件,過濾掉特定級別的日志,防止(zhi)日志刷屏(ping):

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
   <file>logs/app.log</file>
   <!-- 只允許 INFO 級別及以上的日志通過 -->
   <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
       <level>INFO</level>
   </filter>
</appender>

 

5、統(tong)一(yi)日志(zhi)格式

你(ni)開(kai)心(xin)了:好耶,這樣就不會刷屏(ping)了!但是感覺有(you)時候日(ri)(ri)志很雜(za)很亂,尤其(qi)是我想看(kan)某一個(ge)請求(qiu)相關的日(ri)(ri)志時,總(zong)是被(bei)其(qi)他的日(ri)(ri)志干擾,怎么辦?

魚皮:好問題,可以(yi)在日(ri)志配(pei)置文件中定義(yi)統一的日(ri)志格(ge)式,包含時間戳、線程名稱、日(ri)志級別、類(lei)名、方法(fa)名、具體(ti)內容等(deng)關鍵(jian)信息。

<!-- 控制臺日志輸出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
   <encoder>
       <!-- 日志格式 -->
       <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
   </encoder>
</appender>

這(zhe)樣輸出的日志更整齊(qi)易(yi)讀:

 

此外,你還可以通過(guo) MDC(Mapped Diagnostic Context)給日志(zhi)添加額(e)外的上下文信(xin)息,比如(ru)請求 ID、用戶 ID 等(deng),方便(bian)追蹤。

在 Java 代碼中,可以為 MDC 設置屬(shu)性值:

@PostMapping("/user/import")
public Result importUsers(@RequestBody UserImportRequest request) {
   // 1. 設置 MDC 上下文信息
   MDC.put("requestId", generateRequestId());
   MDC.put("userId", String.valueOf(request.getUserId()));
   try {
       log.info("用戶請求處理完成");      
       // 執行具體業務邏輯
       userService.batchImport(request.getUserList());     
       return Result.success();
  } finally {
       // 2. 及時清理MDC(重要!)
       MDC.clear();
  }
}

然后在日志配置文件中就可以使(shi)用這些值了:

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
   <encoder>
       <!-- 包含 MDC 信息 -->
       <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - [%X{requestId}] [%X{userId}] %msg%n</pattern>
   </encoder>
</appender>

這(zhe)樣,每個(ge)請求、每個(ge)用戶的(de)操作一目了然。

 

6、使用(yong)異步日志

你又(you)開心(xin)了:這樣打(da)出(chu)來的日志(zhi),確實舒(shu)服,爽爽爽!但(dan)是(shi)(shi)我打(da)日志(zhi)越多,是(shi)(shi)不是(shi)(shi)程序就會(hui)更慢呢(ni)?有沒有辦法能(neng)優化一下?

魚皮:當然有,可以使用 異步日志

正常情況下,你調用 log.info() 打日志(zhi)(zhi)(zhi)時,程(cheng)(cheng)序會(hui)立刻把日志(zhi)(zhi)(zhi)寫入文件,這個過程(cheng)(cheng)是同步的(de),會(hui)阻塞當前(qian)線(xian)程(cheng)(cheng)。而異步日志(zhi)(zhi)(zhi)會(hui)把寫日志(zhi)(zhi)(zhi)的(de)操作放到另一個線(xian)程(cheng)(cheng)里(li)去做(zuo),不會(hui)阻塞主線(xian)程(cheng)(cheng),性(xing)能更好(hao)。

你眼睛一亮:這(zhe)么(me)厲害?怎么(me)開啟?

魚皮:很簡單,只需(xu)要修改(gai)一(yi)下(xia)配置文件:

<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
   <queueSize>512</queueSize>  <!-- 隊列大小 -->
   <discardingThreshold>0</discardingThreshold>  <!-- 丟棄閾值,0 表示不丟棄 -->
   <neverBlock>false</neverBlock>  <!-- 隊列滿時是否阻塞,false 表示會阻塞 -->
   <appender-ref ref="FILE" />  <!-- 引用實際的日志輸出目標 -->
</appender>
<root level="INFO">
   <appender-ref ref="ASYNC" />
</root>

不過異步日(ri)志(zhi)也有缺點(dian),如(ru)果程序(xu)突然崩潰,緩沖區中(zhong)還沒來得及寫入(ru)文件(jian)的日(ri)志(zhi)可(ke)能會丟失。

所以要權衡一下,看(kan)你的(de)系統更注重性能還是日志的(de)完整性。

你想了想:我們的程序對性能要求比(bi)較(jiao)高,偶爾丟幾條日志問題不大,那(nei)我就用異步日志吧。

 

7、日志管理

接下來的很長一段時間(jian),你混的很舒服,有 Bug 都能很快發現(xian)。

你甚至(zhi)覺得 Bug 太少、工作(zuo)沒什(shen)么激(ji)情,所以沒事(shi)兒就跟新來的實習生阿坤吹吹牛皮:你知道日(ri)志(zhi)么?我可會打它了(le)!

直到有一天,運維小哥(ge)突然(ran)跑過來:阿(a)巴阿(a)巴,服務(wu)器掛了!你快去(qu)看看!

你連忙(mang)登錄服務(wu)器,發現服務(wu)器的硬(ying)盤爆滿了,沒法寫入(ru)新數(shu)據。

你查了一下,發(fa)現日志(zhi)文件(jian)竟然占了 200GB 的空間!

 

你汗流(liu)浹(jia)背了(le),正(zheng)在考慮怎么甩鍋,結果阿(a)坤突然雞叫起(qi)來:阿(a)巴 giegie,你的日志文件是不是從來沒清理過(guo)?

你尷尬地(di)倒了個(ge)立,這樣(yang)眼淚(lei)就不會留下來(lai)。

魚皮嘆了口氣:這就是我要教你的下一招 —— 日志管理。

你(ni)好奇道:怎么管理?我每天登(deng)服務器刪掉一些歷史(shi)文件?

魚皮:人工操(cao)作也太(tai)麻(ma)煩了,我們可以通過(guo)修(xiu)改日志配置文件(jian),讓框(kuang)架(jia)幫忙管理日志。

首先(xian)設置日(ri)(ri)志的滾動(dong)策略,可以根據文(wen)件(jian)大小和日(ri)(ri)期,自動(dong)對日(ri)(ri)志文(wen)件(jian)進行切分。

<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
   <fileNamePattern>logs/app-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
   <maxFileSize>10MB</maxFileSize>
   <maxHistory>30</maxHistory>
</rollingPolicy>

這樣配置后,每天會創建一個新的日志文件(比如 app-2025-10-23.0.log),如果日志文件大小超過 10MB 就再創建一個(比如 app-2025-10-23.1.log),并且只保留最近 30 天的日志。

還(huan)可以(yi)開啟日志壓縮(suo)功能,進一步節(jie)省磁盤空間:

<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
   <!-- .gz 后綴會自動壓縮 -->
   <fileNamePattern>logs/app-%d{yyyy-MM-dd}.log.gz</fileNamePattern>
</rollingPolicy>

你有些激(ji)動:吼(hou)吼(hou),這樣我們(men)就可以按(an)照天數更(geng)快地查(cha)看日志(zhi),服(fu)務器(qi)硬(ying)盤也(ye)有救啦!

 

8、集(ji)成(cheng)日志收(shou)集(ji)系統

兩年后,你(ni)負責(ze)的項目已(yi)經發展成了一(yi)個(ge)大(da)型的分布式(shi)系統,有好幾十(shi)個(ge)微服務。

如今,每(mei)次排查問(wen)題你都(dou)要登(deng)錄到不同的服務器上(shang)查看日(ri)志,非常麻煩。而且有些請(qing)(qing)求的調用鏈路(lu)很長,你得登(deng)錄好幾(ji)(ji)臺服務器、看好幾(ji)(ji)個(ge)服務的日(ri)志,才能追(zhui)蹤到一(yi)個(ge)請(qing)(qing)求的完整調用過(guo)程。

你(ni)簡直要(yao)瘋了!

于是(shi)你找到魚皮求助(zhu):現(xian)在(zai)查日志(zhi)太麻煩(fan)了(le),當年你還(huan)有(you)一招(zhao)沒有(you)教我,現(xian)在(zai)是(shi)不是(shi)……

魚皮點(dian)點(dian)頭:嗯,對于分布式(shi)系統(tong),就必(bi)須要用(yong)專業的日志(zhi)收集系統(tong)了,比如很流行的 ELK。

你好奇:ELK 是啥?伊拉克(ke)?

阿坤搶(qiang)答道:我(wo)知道,就是 Elasticsearch + Logstash + Kibana 這套組合(he)。

簡單(dan)來說,Logstash 負責收集各個服務的日志,然后發送給 Elasticsearch 存(cun)儲和(he)索引,最后通過 Kibana 提供一個可視(shi)化(hua)的界面。

這樣一來,我們可以方便地集中搜索、查看、分(fen)析日志。

你驚訝了:原來日志還能這么(me)玩,以后我所有的項目都(dou)要(yao)用 ELK!

魚(yu)皮擺擺手:不過(guo) ELK 的搭(da)建和運(yun)維成本比較高,對于小(xiao)團(tuan)隊來說可能有點重,還是要按需(xu)采用啊。

 

結局

至此,你已經掌(zhang)握了(le)打日(ri)志的核(he)心(xin)秘法。

只是你(ni)很疑惑,為(wei)何那阿坤竟對日(ri)志系統如(ru)此(ci)熟悉?

阿坤苦笑(xiao)道:我(wo)本來就是日志管理大師,可惜我(wo)上(shang)家公司(si)的同(tong)事從來不打(da)日志,所以我(wo)把他們暴打(da)了一頓后跑路了。

阿巴 giegie 你要記住,日志不是寫給機器看的,是寫給未來的你和你的隊友看的!

你要是(shi)以后不打日志,我就(jiu)打你!

 

更多(duo)編程(cheng)學習資源

posted @ 2025-11-06 11:29  程序員魚皮  閱讀(685)  評論(4)    收藏  舉報