<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      打印高質(zhì)量日志的10條軍規(guī)

      大家好,我是蘇三,又跟大家見面了。

      前言

      去年雙十一大促,我面對監(jiān)控大屏上瘋狂跳動的紅色指標,顫抖著打開服務(wù)器日志,看到的卻是這樣的畫面:

       
      vbscript
      體驗AI代碼助手
      代碼解讀
      復制代碼
      用戶登錄失敗  
      訂單創(chuàng)建出錯 null  
      ERROR 非法參數(shù)

      那一刻我突然頓悟:寫不好日志的程序員,就像不會寫病歷的醫(yī)生

      這篇文章跟大家一起聊聊打印優(yōu)質(zhì)日志的10條軍規(guī),希望對你會有所幫助。

      最近準備面試的小伙伴,可以看一下這個寶藏網(wǎng)站(Java突擊隊):www.susan.net.cn,里面:面試八股文、面試真題、項目實戰(zhàn)、工作內(nèi)推什么都有

      第1條:格式統(tǒng)一

      反例(管理看到會扣錢) :

       
      lua
      體驗AI代碼助手
      代碼解讀
      復制代碼
      log.info("start process");
      log.error("error happen"); 

      無時間戳,無上下文。

      正解代碼

       
      xml
      體驗AI代碼助手
      代碼解讀
      復制代碼
      <!-- logback.xml核心配置 -->
      <pattern>
          %d{yy-MM-dd HH:mm:ss.SSS} 
          |%X{traceId:-NO_ID} 
          |%thread 
          |%-5level 
          |%logger{36} 
          |%msg%n
      </pattern>

      在logback.xml中統(tǒng)一配置了日志的時間格式、tradeId,線程、等級、日志詳情都信息。

      日志的格式統(tǒng)一了,更方便點位問題。

      圖片

      第2條:異常必帶堆棧

      反例(同事看了想打人) :

       
      php
      體驗AI代碼助手
      代碼解讀
      復制代碼
      try {
          processOrder();
      } catch (Exception e) {
          log.error("處理失敗"); 
      }

      出現(xiàn)異常了,日志中沒打印任何的異常堆棧信息。

      相當于自己把異常吃掉了。

      非常不好排查問題。

      正確姿勢

       
      c
      體驗AI代碼助手
      代碼解讀
      復制代碼
      log.error("訂單處理異常 orderId={}", orderId, e); // e必須存在!

      日志中記錄了出現(xiàn)異常的訂單號orderId和異常的堆棧信息e。

      第3條:級別合理

      反面教材

       
      c
      體驗AI代碼助手
      代碼解讀
      復制代碼
      log.debug("用戶余額不足 userId={}", userId); // 業(yè)務(wù)異常應(yīng)屬WARN
      log.error("接口響應(yīng)稍慢"); // 普通超時屬INFO

      接口響應(yīng)稍慢,打印了error級別的日志,顯然不太合理。

      正常情況下,普通超時屬INFO級別。

      級別定義表

      級別 正確使用場景
      FATAL 系統(tǒng)即將崩潰(OOM、磁盤爆滿)
      ERROR 核心業(yè)務(wù)失敗(支付失敗、訂單創(chuàng)建異常)
      WARN 可恢復異常(重試成功、降級觸發(fā))
      INFO 關(guān)鍵流程節(jié)點(訂單狀態(tài)變更)
      DEBUG 調(diào)試信息(參數(shù)流水、中間結(jié)果)

      第4條:參數(shù)完整

      反例(讓運維罵娘) :

       
      c
      體驗AI代碼助手
      代碼解讀
      復制代碼
      log.info("用戶登錄失敗");

      上面這個日志只打印了“用戶登錄失敗”這個文案。

      誰在哪登錄失敗?

      偵探式日志

       
      c
      體驗AI代碼助手
      代碼解讀
      復制代碼
      log.warn("用戶登錄失敗 username={}, clientIP={}, failReason={}", 
          username, clientIP, "密碼錯誤次數(shù)超限");

      登錄失敗的業(yè)務(wù)場景,需要記錄哪個用戶,ip是多少,在什么時間,登錄失敗了,失敗的原因是什么。

      時間在logback.xml中統(tǒng)一配置了格式。

      這樣才方便快速定位問題:

      圖片

      第5條:數(shù)據(jù)脫敏

      血淚案例
      某同事打印日志泄露用戶手機號被投訴。

      我在記錄的日志中,需要對一下用戶的個人敏感數(shù)據(jù)做脫敏處理。

      例如下面這樣:

       
      typescript
      體驗AI代碼助手
      代碼解讀
      復制代碼
      // 脫敏工具類
      public class LogMasker {
          public static String maskMobile(String mobile) {
              return mobile.replaceAll("(\d{3})\d{4}(\d{4})", "$1****$2");
          }
      }
      
      // 使用示例
      log.info("用戶注冊 mobile={}", LogMasker.maskMobile("13812345678"));

      第6條:異步保性能

      問題復現(xiàn)
      某次秒殺活動中直接同步寫日志,導致大量線程阻塞:

       
      c
      體驗AI代碼助手
      代碼解讀
      復制代碼
      log.info("秒殺請求 userId={}, itemId={}", userId, itemId); 

      高并發(fā)下IO阻塞。

      致命傷害分析:

      1. 同步寫日志導致線程上下文切換頻繁
      2. 磁盤IO成為系統(tǒng)瓶頸
      3. 高峰期日志打印耗時占總RT的25%

      正確示范(三步配置法)

      步驟1:logback.xml配置異步通道

       
      xml
      體驗AI代碼助手
      代碼解讀
      復制代碼
      <!-- 異步Appender核心配置 -->  
      <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">  
          <!-- 不丟失日志的閾值:當隊列剩余容量<此值時,TRACE/DEBUG級別日志將被丟棄 -->  
          <discardingThreshold>0</discardingThreshold>  
          <!-- 隊列深度:建議設(shè)為 (最大并發(fā)線程數(shù) × 2) -->  
          <queueSize>4096</queueSize>  
          <!-- 關(guān)聯(lián)真實Appender -->  
          <appender-ref ref="FILE"/>  
      </appender>  

      步驟2:日志輸出優(yōu)化代碼

       
      c
      體驗AI代碼助手
      代碼解讀
      復制代碼
      // 無需前置判斷,框架自動處理  
      log.debug("接收到MQ消息:{}", msg.toSimpleString()); // 自動異步寫入隊列  
      
      // 不應(yīng)做復雜計算后再打印(異步前仍在業(yè)務(wù)線程執(zhí)行)  
      // 錯誤做法:  
      log.debug("詳細內(nèi)容:{}", computeExpensiveLog());  

      流程圖如下:圖片

      步驟3:性能關(guān)鍵參數(shù)公式

       
      scss
      體驗AI代碼助手
      代碼解讀
      復制代碼
      最大內(nèi)存占用 ≈ 隊列長度 × 平均單條日志大小  
      推薦隊列深度 = 峰值TPS × 容忍最大延遲(秒)  
      例如:10000 TPS × 0.5s容忍 ? 5000隊列大小  

      風險規(guī)避策略

      1. 防隊列堆積:監(jiān)控隊列使用率,達80%觸發(fā)告警
      2. 防OOM:嚴格約束大對象toString()的調(diào)用
      3. 緊急逃生:預設(shè)JMX接口用于快速切換同步模式

      第7條:鏈路追蹤

      混沌場景
      跨服務(wù)調(diào)用無法關(guān)聯(lián)日志。

      我們需要有鏈路追蹤方案。

      全鏈路方案

       
      less
      體驗AI代碼助手
      代碼解讀
      復制代碼
      // 攔截器注入traceId
      MDC.put("traceId", UUID.randomUUID().toString().substring(0,8));
      
      // 日志格式包含traceId
      <pattern>%d{HH:mm:ss} |%X{traceId}| %msg%n</pattern>

      可以在MDC中設(shè)置traceId。

      后面可以通過traceId全鏈路追蹤日志。

      流程圖如下:圖片

      最近建了一些工作內(nèi)推群,各大城市都有,歡迎各位HR和找工作的小伙伴進群交流,群里目前已經(jīng)收集了不少的工作內(nèi)推崗位:京東、聯(lián)想、騰訊、字節(jié)等等。加蘇三的微信:li_su223,備注:所在城市,即可進群。

      第8條:動態(tài)調(diào)參

      半夜重啟的痛
      線上問題需要臨時開DEBUG日志,比如:查詢用戶的某次異常操作的日志。

      熱更新方案

       
      less
      體驗AI代碼助手
      代碼解讀
      復制代碼
      @GetMapping("/logLevel")
      public String changeLogLevel(
          @RequestParam String loggerName, 
          @RequestParam String level) {
          
          Logger logger = (Logger) LoggerFactory.getLogger(loggerName);
          logger.setLevel(Level.valueOf(level)); // 立即生效
          return "OK";
      }

      有時候我們需要臨時打印DEBUG日志,這就需要有個動態(tài)參數(shù)控制了。

      否則每次調(diào)整打印日志級別都需要重啟服務(wù),可能會影響用戶的正常使用。

       
      rust
      體驗AI代碼助手
      代碼解讀
      復制代碼
      journey
          title 日志級別動態(tài)調(diào)整
          section 舊模式
              發(fā)現(xiàn)問題 --> 修改配置 --> 重啟應(yīng)用 --> 丟失現(xiàn)場
          section 新模式
              發(fā)現(xiàn)問題 --> 動態(tài)調(diào)整 --> 立即生效 --> 保持現(xiàn)場

      第9條:結(jié)構(gòu)化存儲

      混沌日志

       
      體驗AI代碼助手
      代碼解讀
      復制代碼
      用戶購買了蘋果手機 訂單號1001 金額8999

      上面的日志拼接成了一個字符串,雖說中間有空格分隔了,但哪些字段對應(yīng)了哪些值,看起來不是很清楚。

      我們在存儲日志的時候,需要做結(jié)構(gòu)化存儲,方便快速的查詢和搜索。

      機器友好式日志

       
      json
      體驗AI代碼助手
      代碼解讀
      復制代碼
      {
        "event": "ORDER_CREATE",
        "orderId": 1001,
        "amount": 8999,
        "products": [{"name":"iPhone", "sku": "A123"}]
      }

      這里使用了json格式存儲日志。

      日志中的數(shù)據(jù)一目了然。

      第10條:智能監(jiān)控

      最失敗案例
      某次用戶開通會員操作,錯誤日志堆積3天才被發(fā)現(xiàn),黃花菜都涼了。

      我們需要在項目中引入智能監(jiān)控。

      ELK監(jiān)控方案

      圖片

      報警規(guī)則示例

       
      vbnet
      體驗AI代碼助手
      代碼解讀
      復制代碼
      ERROR日志連續(xù)5分鐘 > 100條 → 電話告警  
      WARN日志持續(xù)1小時 → 郵件通知

      總結(jié)

      研發(fā)人員的三大境界

      1. 青銅System.out.println("error!")
      2. 鉆石:標準化日志 + ELK監(jiān)控
      3. 王者
        • 日志驅(qū)動代碼優(yōu)化
        • 異常預測系統(tǒng)
        • 根因分析AI模型

      最后的靈魂拷問
      下次線上故障時,你的日志能讓新人5分鐘定位問題嗎?

      這5個項目,太炸裂了

      posted @ 2025-07-03 09:36  CharyGao  閱讀(30)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产精品内射在线免费看| 99精品全国免费观看视频| 亚洲欧美牲交| 日韩一区二区三区女优丝袜| 久草热久草热线频97精品| 男人扒女人添高潮视频| 九九热免费在线播放视频| 国产一区二区三区精美视频| 国产亚洲第一精品| 亚洲国产精品无码一区二区三区 | a级黑人大硬长爽猛出猛进| 成人午夜免费无码视频在线观看 | 中文字幕国产日韩精品| 亚洲国产精品久久久久秋霞影院| 国产精品国产三级国产午| 国产色悠悠综合在线观看| 极品无码国模国产在线观看| 男女性高爱潮免费网站| 韩国精品福利视频一区二区| 91麻精品国产91久久久久| 国内少妇偷人精品免费| 国产精品无码无片在线观看3d| 亚洲欧美日韩尤物AⅤ一区| 国产精品欧美福利久久| 亚洲色成人网站www永久四虎| 尹人香蕉久久99天天拍| 人妻日韩精品中文字幕| 巨熟乳波霸若妻在线播放| 亚洲中文字幕精品久久久久久动漫| 亚洲情综合五月天| 久青草久青草视频在线观看| 亚洲国产成人综合精品| 欧美日韩国产综合草草| 亚洲欧美成人久久综合中文网| 精品国产午夜福利在线观看| 免费视频爱爱太爽了| 中文字幕不卡在线播放| 潘金莲高清dvd碟片| 偷拍一区二区三区在线视频 | 亚洲国产欧美在线人成aaaa| av中文字幕一区二区|