自研日誌實用工具類

来源:https://www.cnblogs.com/BillySir/archive/2023/04/01/17279071.html
-Advertisement-
Play Games

今天我來分享一個關於日誌的問題和解法。 問題 沒有界面的後端程式在實際運行中發生了什麼事,通常是通過日誌來探查。所以日誌非常重要。資料庫記錄了程式運行的結果,日誌記錄了程式運行的過程。但是日誌經常出現一個問題,日誌量太多,以至於把重要的日誌淹沒在裡面。未能及時地發現問題,或者當有問題出現的時候,在日 ...


  今天我來分享一個關於日誌的問題和解法。

問題

  沒有界面的後端程式在實際運行中發生了什麼事,通常是通過日誌來探查。所以日誌非常重要。資料庫記錄了程式運行的結果,日誌記錄了程式運行的過程。但是日誌經常出現一個問題,日誌量太多,以至於把重要的日誌淹沒在裡面。未能及時地發現問題,或者當有問題出現的時候,在日誌中找原因真的是很痛苦。

  對於這個問題,第1招就是把日誌進行分級,差不多是每一種日誌工具都提供了這個功能。常見的有info、warn、error這些級別。當使用級別進行過濾之後,往往發現日誌還是太多。就需要進一步分析原因了。

  在實際項目中發現有這麼幾種情況:
1. 有大量的日誌,內容基本相同,只是有一兩個值不同。如“發現無法轉成long類型的字元串:xxx”
2. 還有一類日誌是內容完全相同,如“意外發現xxx屬性的值是null”

至於為什麼會有大量的這種日誌,大概率是它在迴圈內部,甚至是多重迴圈的內部。

解法

解法一:少寫日誌

  怕日誌多而在寫日誌代碼時猶豫,甚至就不寫了。當出問題後找不到日誌,無法為定位問題提供幫助。此法不可取。

解法二:硬編碼控制日誌數量

  設置一些標誌或計數器來使迴圈內的同一類日誌只列印一條或少數幾條,那麼日誌的邏輯跟業務的邏輯會混在一起,程式的整體邏輯變得複雜。此法是下策。

  如何讓程式員大膽寫日誌,而又不會出現日誌太多,同時日誌的邏輯也很少摻雜到業務邏輯中呢?

解法三:日誌工具類

  我寫了一個日誌的實用類來解決這個問題。

1. 拼接

  它是將多條日誌拼接為一條來輸出。採用“首碼+主體+尾碼”的形式,在初始化時設置好首碼和尾碼,在接收日誌條目時拼接條目,最後的輸出形式是“首碼+條目1, 條目2, …+尾碼”。如果條目數為0,則前尾碼都不會輸出。所以,“發現無法轉成long類型的字元串:aaa”,“發現無法轉成long類型的字元串:bbb”“發現無法轉成long類型的字元串:ccc”,會拼接這樣一條:“發現無法轉成long類型的字元串:aaa,bbb,ccc”。合成後的內容長度就大大減少。

2. 條目數限制

  假如類似的情況發生1000次,拼接後的日誌還是很長。作為人來講,只需要看到前面的若幹條目,就瞭解了這個問題,通常是沒必要看到全部的值。所以這個日誌工具提供了條目數的限制,對於超過限制的條目,則不會輸出。比如條目數的限制是2,那輸出的結果就是“發現無法轉成long類型的字元串:aaa,bbb”

3. 同值合併

  對於內容完全相同的日誌,就會直接進行合併,並記錄一個次數,不相鄰的除外。原本是好幾屏幕的“意外發現xxx的值是null”。合併成一條:“[1000*]意外發現xxx的值是null”。(此法是向瀏覽器的控制台學習)

4. 長度限制

  除此之外,還提供了總長度的限制,即是對“首碼+條目1, 條目2, …+尾碼”的總長度的限制。如果某個條目加進去之後整體長度超過這個限制了,那麼這個條目就會被丟棄。首碼尾碼是不會被丟棄的,但如果“首碼+尾碼”已經超出限制了,根據“如果條目數為0,則前尾碼都不會輸出”最終沒有輸出。

5. 異常

  此日誌類實現特定的介面(Closable),做到了即使在業務代碼發生異常的情況下,也不會漏了輸出優化後日誌。用法:

try (LogUtil log = LogUtil.builder().logger(LOGGER).build()) {
    // ...A
    log.write(“any message”);
    // ...B
}

如果A處發生異常,自然沒有任何輸出。如果B處發生異常,則不影響前面的“any message”的輸出。

  以上的條目數限制、同值合併、總長度限制等功能可單獨使用,也可組合使用。所以可能會看到這樣的結果:
“發現無法轉成long類型的字元串:aaa,bbb,[99*]aaa,[56*]ccc”

 

  這個日誌實用工具是對現有日誌組件的封裝,而現有的日誌組件是log4j。不管使用哪個日誌組件,都可以加上這種封裝。我並沒有修改日誌組件,只是給他套了一層“殼”。

  實際投入使用後,在我們的項目中發現,有一種相同的日誌產生了947條,在過去是刷了好多屏,而且還不知道他多少條,現在合成之後就是一條,並且打上了“[947*]”,不僅沒有刷屏,還很清晰的看到了條數。

  乾凈,舒服。


博主簡介:佘煥敏(shé),洋名 Billy Sir。
關註編程基礎技術,並致力於研究軟體的自動化生成。 對編程規範化、面向對象的極致使用也有著濃厚的興趣。 同時非常希望能夠寫程式到65歲。
只有工匠精神,才能把常人覺得單調乏味的代碼,當作作品雕刻成藝術品。
微信贊賞碼
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 集合論是SQL語言的根基 1.1. UNION 1.1.1. SQL-86標準 1.2. NTERSECT和EXCEPT 1.2.1. SQL-92標準 1.3. 除法運算(DIVIDE BY) 1.3.1. 沒有被標準化 2. 註意事項 2.1. SQL能操作具有重覆行的集合,可以通過可選項 ...
  • 說明 有讀者反饋: 學習uniapp ios 插件開發不知道從哪些文章看起,沒有一個清晰的學習路線 本文就做一個解答。 首先本系列的文章是作者精心排過序的,如果想要完整的學習uniapp ios原生插件開發技術的話,建議是按文章順序瀏覽。 當然您如果有相關的開發經驗,且只對某一技術實現感興趣的話,也 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 最近碰到這樣一個問題,在一張封面上直接顯示書名,可能會存在書名看不太清楚的情況(容易受到背景干擾),如下 為瞭解決這個問題,設計師提了一個“究極”方案,將書名背後的圖片模糊一下,這個在 CSS 中很好實現,僅需backdrop-filte ...
  • 路由守衛 作用:對路由進行許可權控制 配置路由守衛應在暴露前配置 分類:全局守衛、獨享守衛、組件內守衛 首先先給需要鑒權的路由設置好meta配置項。 meta配置項:是vue-router中的一個對象,主要用於存儲路由的元數據(meta data)信息。這些元數據信息可以是一些描述性的內容,比如頁面的 ...
  • 泛型、Trait、生命周期 一、提取函數消除重覆 fn main() { let number_list = vec![34, 50, 25, 100, 65]; let mut largest = number_list[0]; for number in number_list { if num ...
  • Spring是什麼? Spring是一個輕量級的控制反轉(IoC)和麵向切麵(AOP)的容器框架。 Spring的優點 通過控制反轉和依賴註入實現松耦合。 支持面向切麵的編程,並且把應用業務邏輯和系統服務分開。 通過切麵和模板減少樣板式代碼。 聲明式事務的支持。可以從單調繁冗的事務管理代碼中解脫出來 ...
  • 無論對於什麼業務來說,用戶數據信息的安全性無疑都是非常重要的。尤其是在數字經濟大火背景下,數據的安全性就顯得更加重要。數據脫敏可以分為兩個部分,一個是DB層面,防止DB數據泄露,暴露用戶信息;一個是介面層面,有些UI展示需要數據脫敏,防止用戶信息被人刷走了。 v需求背景 DB層面的脫敏今天先不講,今 ...
  • 去年公司由於不斷發展,內部自研系統越來越多,所以後來搭建了一個日誌收集平臺,並將日誌收集功能以二方包形式引入各個自研系統,避免每個自研系統都要建立一套自己的日誌模塊,節約了開發時間,管理起來也更加容易。 這篇文章主要介紹如何編寫二方包,並整合到各個系統中。 先介紹整個ELK日誌平臺的架構。其中xia ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...