業務系統日誌記錄規範總結

業務系統日誌記錄規範

注意

  1. 應用中應該充滿了日誌記錄信息,日誌甚至比邏輯代碼還要多;
  2. 集成 seluth ,開啓消息鏈路;不開啓日誌上傳,不集成 zipkin;
  3. 應該避免日誌記錄過程中出現異常,比如 log.debug(requst.getid) ,這條日誌記錄之前一定要判斷 request 是否爲空;日誌記錄中使用的信息一定時穩定的,提前準備好的,最好不是專門爲此次日誌記錄專門準備的;
  4. 日誌應只記錄標識性信息,具體信息從具體存儲裏取;
  5. 日誌應該同時支持人和計算機都可以讀;人可讀的意思的,要成句子;計算機可讀的意思是要有明確的分割符,可以支持正則等工具抽取其中有意義的信息;
  6. service 或 manager 層內有 if…else 或者 switch 這樣的分支時,要在分支的首行打印日誌,用來確定進入了哪個分支;
  7. 對於 trace / debug / info 級別的日誌輸出,必須進行日誌級別的開關判斷。warn 和 error 不用開關判斷;

日誌級別 trace 和 debug

測試環境要實現的目標是,不需要重新完整的調試程序,可以直接定位到出問題的 service 內的邏輯分支,最多在進行一次小範圍的測試;
要實現這個目標,需要記錄 service 入參出參,debug級別的日誌,只在非生產環境中使用;

日誌級別 info

  1. info級別的日誌只在 service 層和 manager 層存在,體現業務邏輯運行的路徑,工具類等的不要記錄;
  2. Service 方法中對於系統/業務狀態的變更處記錄
  3. 主要邏輯中的分步驟記錄

日誌級別 warn

  1. 有容錯機制的時候出現的錯誤情況,有異常,但是你有 Plan B;
  2. 業務異常的記錄,比如:當接口拋出業務異常時,應該記錄此異常;
  3. warn 日誌級別來記錄用戶輸入參數錯誤的情況,避免用戶投訴時,可以追溯信息;

日誌級別 error

error 級別只記錄系統邏輯出錯、異常或者重要的錯誤信息。
異常在程序中,一般會沿着調用鏈路,層層上拋,直到service層,在最終處理異常的地方記錄log.error(e);log.error和往外拋異常,不應該同時出現;

錯誤異常

錯誤異常分爲程序異常(系統異常)和業務異常;

程序異常會導致程序不能正常執行;業務異常不會,業務異常的處理屬於業務邏輯的一部分;
ERROR 級別的日誌,一出,意味着開發運維人員要介入了,要操作確認一下東西,要維修一些東西了;

業務系統開發過程中,不需要 log.error 記錄異常,讓框架和容器(Tomcat等)來做;
業務異常的需要開發者開發對應的異常處理邏輯,業務異常不是程序異常;比如用戶登陸失敗;
業務異常的處理屬於正常的業務邏輯,不應該log.error,不重要的可以不log,重要的可以使用log.warn記錄,避免用戶投訴時,可以追溯信息;

數據庫或者kafka在應用啓動時連不上是如何處理的,在應用運行過程中是如何處理的?啓動時,依賴的插件有問題,應用直接啓動不起來;如果應用已經啓動起來了,觸發到跟其交互時,拋出異常,程序還是正常執行;

ExceptionHandler的默認的處理邏輯

ExceptionHandler的默認的處理邏輯不要喫掉所有的異常,log.error打印出來,這個邏輯主要用來處理程序異常,業務異常都應有對應的處理邏輯;

@ExceptionHandler(Throwable.class)
@ResponseBody
public String handle(Throwable e) {
	log.error(e.getMessage(),e);
	//構造返回信息
	return e.getMessage();
}

程序異常

各個組件的異常信息可以各自處理;比如SQLExcption,需要如果SQL 出異常,異常的信息中會有SQL相關的信息,如果直接返回給前端,會造成安全問題,前端對此異常也不關心,而後端開發者關心的信息應該都記錄在日誌中,以方便分析問題;

@ExceptionHandler(SQLException.class)
@ResponseBody
public String handle(SQLException e) {
	log.error(e.getMessage(),e);
	//構造返回信息,記得脫敏
	return e.getMessage();
}

各個組件的SDK一般都會有自己的異常體系;可以根據情況直接對頂級異常類,或者典型的異常子類進行處理;
接入外部組件時,首先分析其SDK的異常體系,編寫對應的ExceptionHandler

org.apache.kafka.common.KafkaException
org.springframework.kafka.KafkaException
java.sql.SQLException

鏈路追蹤

多個進程間的日誌聯動
集中式日誌存儲系統的存在,讓在一個入口處理業務系統的日誌成爲了可能,產生了高級的用法,鏈路追蹤;
用戶的一個動作觸發的在各個系統的所有的執行邏輯,使用一個標識將其聯繫起來,開發人員分析的時候,可以根據此標識查詢所有相關的日誌,哪裏出問題,一目瞭然;

遠程調用

遠程調用的plan b,就是熔斷降級裏面的Plan B;
外部接口部分,客戶端請求參數(REST/WS),調用第三方時的調用參數和調用結果使用info

如果出異常,調用過程異常或者返回錯誤碼,根據情況選擇拋出異常或者啓用Plan B;
拋出異常意味着程序正常流程執行結束,需要處理這個異常,warn記錄此異常,然後返回用戶結果;
Plan B意味着程序還可以正常執行下去,warn記錄發生了此事件,出現異常轉入Plan B;

遠程調用過程中出異常,意味着需要開發人員介入,應該記錄 error 級別的異常;
如果是返回的錯誤碼是非成功執行的錯誤碼,這時候應該根據錯誤碼的級別拋出不同的異常,處理異常的地方根據遠程調用的接口的重要程度評估使用不同的日誌級別。

驗證日誌

提交代碼前,確定通過日誌可以看到一個功能的整個執行流程,可以通過日誌進行問題定位程序執行的路徑;

參考

用JAVA日誌來寫詩
JAVA - 優雅的記錄日誌(log4j實戰篇)
Alibaba Java Coding Guidelines
小白學習如何打日誌
正確的打日誌姿勢
Java常用日誌框架介紹

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章