天天看點

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

業務系統日志記錄規範

注意

  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 級别的異常;

如果是傳回的錯誤碼是非成功執行的錯誤碼,這時候應該根據錯誤碼的級别抛出不同的異常,處理異常的地方根據遠端調用的接口的重要程度評估使用不同的日志級别。

驗證日志

參考