日誌瘦身騷操作:從 5G 優化到 1G,牛逼!!

来源:https://www.cnblogs.com/javastack/archive/2023/01/10/17039150.html
-Advertisement-
Play Games

作者:明明如月學長 鏈接:https://juejin.cn/post/7117046503616544804 一、背景 在日常開發中,通常為了方便調試、方便查問題,會列印很多 INFO 級別的日誌。 隨著訪問量越來越大,一不小心,某個日誌文件一天的 size 就大於了某個閾值(如 5G),於是,收 ...


作者:明明如月學長
鏈接:https://juejin.cn/post/7117046503616544804

一、背景

在日常開發中,通常為了方便調試、方便查問題,會列印很多 INFO 級別的日誌。

隨著訪問量越來越大,一不小心,某個日誌文件一天的 size 就大於了某個閾值(如 5G),於是,收到了優化日誌大小的告警,一定時間內不優化反饋給你主管,囧...

日誌過大容易導致一些運維操作消耗機器性能,如日誌文件檢索、數據採集、磁碟清理等。

那麼,日誌瘦身哪些常見的思路呢? 本文結合某個具體案例談談我的看法。

推薦一個開源免費的 Spring Boot 最全教程:

https://github.com/javastacks/spring-boot-best-practice

二、日誌瘦身方法論

2.1 只列印必要的日誌

有時候為了方便測試,臨時列印很多 INFO 級別日誌。對於這種日誌,等項目上線前,可以將非必要的日誌刪除或者調整為 DEBUG 級別。


但有些場景下有些日誌可列印為 DEBUG 也可列印為 INFO,列印成 INFO 級別占空間,列印成 DEBUG 級別線上查問題的時候又需要用到,腫麽辦?

我們可以對日誌工具類進行改造,支持上下文傳遞某個開關時(正常調用沒有這個開關,通過公司的 Tracer 或者 RPC上下文傳遞),可以臨時將 DEBUG日誌提升為 INFO級別。 偽代碼如下:

if(log.isDebugEnable()){
   log.debug(xxx);
}else if(TracerUtils.openDebug2Info()){
 log.info("【debug2info】"+xxx);
}

這樣,可以將一些糾結是否要列印成 INFO 日誌的 log 列印成 DEBUG 級別,查問題時自動提升為INFO 日誌。 為了避免誤會,區分 DEBUG 提升 INFO 的日誌和普通 INFO 日誌,加上 類似【debug2info】 日誌首碼。

當然,你也可以搞一些其他騷操作,這裡只是舉個例子,請自行舉一反三。

2.2 合併列印

有些可以合併的日誌,可以考慮合併。

如在同一個方法前後都列印了 INFO 日誌:

INFO [64 位traceId] XXXService 執行前 size =10 INFO [64 位traceId] XXXService 執行後 size =4

可以合併成一條:

INFO [64 位traceId] XXXService 執行前 size =10 執行後 size =4

2.3 簡化&縮寫&壓縮

某個日誌非常有必要,但是列印的對象有些大,如果可以滿足問題排查需求的情況下,我們可以:

(1)選擇只列印其 ID

(2)創建一個只保留關鍵欄位的日誌專用對象,轉化為日誌專用對象,再列印。

(3)可以用縮寫,如 write 簡化為 w, read 簡化為 r, execute 簡化為e 等;比如 pipeline 中有 20個核心 bean ,列印日誌時可以使用不同的編號替代 bean 全稱,如 S1,S2 ,雖然沒那麼直觀,但既可以查問題,又降低了日誌量。

三、優化案例

3.1 場景描述

一個業務場景涉及很多 bean, 為了復用一些通用邏輯,這些 bean 都繼承自某個抽象類。 在抽象類中,定義了執行 bean 前後的一些通用邏輯,如執行前後列印當前 pipeline 中 item 的數量。 最後一個 bean 執行完結果轉換後需要列印出結果。

3.2 優化分析

3.2.1 只列印必要日誌

(1)由於當前 bean 執行前 相當於前一個 bean 執行後,因此只列印執行後的日誌就可以,執行前的INFO 日誌可以刪除或者改為 DEBUG (只列印必要日誌)

(2)通常問題只出現在執行前後 size 不一致的情況下,因此執行後列印日誌前可以加個判斷,如果執行前後 size 相同則不列印。(只列印必要日誌) 偽代碼如下:

if(sizeBefore != sizeAfter){
log.info("service:{}, 前size:{},後size:{}", getName(),sizeBefore, sizeAfter)
}

推薦一個開源免費的 Spring Boot 最全教程:

https://github.com/javastacks/spring-boot-best-practice

這招效果很明顯,因為大多數 bean 的執行前後 size 是相同的,就不會列印這條日誌。 而假設之前有 20 個,這條日誌就需要列印 20次,改進後可能只需要列印 2-3 次。

3.2.2 日誌合併

(2)為了方便查問題還需要列印執行前的 size ,那麼將執行前的 size 記錄在記憶體中,列印執行後日誌時多列印出執行前的 size。(合併列印) 偽代碼如下:

log.info("service:{}, 執行前size:{}", getName(),sizeBefore)

log.info("service:{}, 執行後size:{}", getName(),sizeBefore, sizeAfter)

合併後

log.info("service:{}, 前size:{},後size:{}", getName(),sizeBefore, sizeAfter)

3.2.3 日誌精簡

對於最終結果,將結果對象(如 XXDTO)轉化為只包括關鍵信息,如 id, title 的日誌對象(XXSimpleLogDTO),轉化為日誌對象後再列印。

log.info("resultId:{}",result.getId());

或者

log.info("result:{}",toSimpleLog(result));

3.3 效果評估

該日誌一天產生 5 G 左右,這裡百分之80% 左右都是列印執行前後的 size,10%左右是列印最終結果, 還有一些其他的日誌。 經過上述方法優化後,每天日誌量不足 1G。

在滿足排查問題的需要,又實現日誌瘦身之間進行了取捨。

四、總結

日誌瘦身需要進行權衡,保留排查問題的必要日誌情況下儘可能精簡。

可以採用刪除不必要日誌,合併日誌,日誌簡化等方式進行優化。

我們還可以進行一些騷操作,支持線上 DEBUG 臨時提升 INFO (當然也可以使用 arthas )來輔助我們查問題。

你還有哪些不錯的日誌瘦身技巧? 歡迎在文章末尾評論和我交流。

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2022最新版)

2.勁爆!Java 協程要來了。。。

3.Spring Boot 2.x 教程,太全了!

4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!

5.《Java開發手冊(嵩山版)》最新發佈,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Redis 數據結構-雙向鏈表 最是人間留不住,朱顏辭鏡花辭樹。 1、簡介 Redis 之所以快主要得益於它的數據結構、操作記憶體資料庫、單線程和多路 I/O 復用模型,進一步窺探下它常見的五種基本數據的底層數據結構。 Redis 常見數據類型對應的的底層數據結構。 String:簡單動態字元串。 L ...
  • 前言 今天給大家介紹的是Python爬蟲批量下載相親網站圖片數據,在這裡給需要的小伙伴們代碼,並且給出一點小心得。 首先是爬取之前應該儘可能偽裝成瀏覽器而不被識別出來是爬蟲,基本的是加請求頭,但是這樣的純文本數據爬取的人會很多,所以我們需要考慮更換代理IP和隨機更換請求頭的方式來對相親網站圖片數據進 ...
  • 一、MybatisPlusMax簡介 MybatisPlusMax是MybatisPlus的增強包,秉承只拓展不修改的理念,對MybatisPlus做增強。 正如MybatisPlus是對MyBatis的增強,MybatisPlusMax是對MybatisPlus的增強,拓展理念一脈相承。 Myba ...
  • 相較於最初的 Bourne shell,現代 bash 版本的最大改進之一體現在算術方面。早期的 shell 版本沒有內建的算術功能,哪怕是給變數加1,也得調用單獨的程式來完成。 1、算術方法一: $(( )) 只要都是整數運算,就可以在 $(( )) 的算術表達式內使用所有的標準運算符。還有一個額 ...
  • 大家好,我是三友~~ 這篇文章我準備來聊一聊RocketMQ消息的一生。 不知你是否跟我一樣,在使用RocketMQ的時候也有很多的疑惑: 消息是如何發送的,隊列是如何選擇的?消息是如何存儲的,是如何保證讀寫的高性能?RocketMQ是如何實現消息的快速查找的?RocketMQ是如何實現高可用的?消 ...
  • 原文:JavaFx 頁面和控制項設置快捷鍵 - Stars-One的雜貨小窩 之前說過一篇window系統全局快捷鍵的設置,本期主要是講解JavaFx應用程式的快捷鍵設置,還是有所區別的 這裡主要是Tornadofx為例進行講解,以Kotlin語言為例,由於比較簡單,就不貼截圖了,下麵例子都是自己測試 ...
  • 2023-01-10 一、Mybatis中獲取主鍵自增數據 要獲取自增數據時,需要在映射文件中的“<insert>”中添加兩個屬性,例如獲取自增的id ①EmployeeMapper.xml中的<mapper>標簽內部 <insert id="insertEmployee" useGenerated ...
  • 在高併發下,Java程式的GC問題屬於很典型的一類問題,帶來的影響往往會被進一步放大。不管是「GC頻率過快」還是「GC耗時太長」,由於GC期間都存在Stop The World問題,因此很容易導致服務超時,引發性能問題。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...