異常日志規范

目錄

一、錯誤碼

二、異常處理

三、日志規約


一、錯誤碼

強制:

1、錯誤碼的制訂原則:快速溯源、溝通標準化。

1)錯誤碼必須能夠快速知曉錯誤來源,可快速判斷是誰的問題。

2)錯誤碼必須能夠清晰地比對(代碼中容易equals)?。

3)錯誤碼有利于團隊快速對錯誤原因達成一致。

2、錯誤碼不體現版本號和錯誤等級信息。

說明:錯誤碼以不斷追加的方式進行兼容。錯誤等級由日志和錯誤碼本身的釋義決定。

3、當全部正常,但不得不填充錯誤碼時,返回五個零(00000)?。

4、錯誤碼為字符串類型,共5位,分為錯誤產生來源、四位數字編號兩部分。

說明:錯誤產生來源分為A、B、C三種,

????????A表示錯誤來源于用戶,例如參數錯誤、用戶安裝版本過低、用戶支付超時等;

????????B表示錯誤來源于當前系統,例如業務邏輯出錯、程序健壯性差等;

????????C表示錯誤來源于第三方服務,例如CDN服務出錯、消息投遞超時等;

四位數字編號從0001到9999,大類之間的步長間距預留100。

5、編號不與公司業務架構和組織架構掛鉤,以先到先得為原則在統一平臺上辦理,一旦審批生效,編號即被永久固定。

6、錯誤碼使用者避免隨意定義新的錯誤碼。

說明:在代碼中使用錯誤碼時,盡可能在原有錯誤碼附表中找到語義相同或者相近的錯誤碼。

7、錯誤碼不能直接輸出給用戶作為提示信息使用。

說明:堆棧、錯誤碼(errorCode)?、錯誤信息(errorMessage)、提示信息(userTip)是一個有效關聯并互相轉義的和諧整體,但請勿越俎代庖。

推薦:

1、errorCode之外的業務獨特信息由errorMessage承載,不要讓errorCode本身涵蓋過多的具體業務屬性。

2、在獲取第三方服務錯誤時,向上拋出允許本系統轉義,由C轉為B,并且在錯誤信息上帶上原有的errorCode。

參考:

1、錯誤碼分為一級宏觀錯誤碼、二級宏觀錯誤碼、三級宏觀錯誤碼。

說明:在無法確定的錯誤場景中,可以直接使用一級宏觀錯誤碼,分別是:A0001(用戶端錯誤)?、B0001(系統執行出錯)?、C0001(調用第三方服務出錯)?。

正例:調用第三方服務出錯是一級,中間件出錯是二級,消息服務出錯是三級。

2、錯誤碼的后三位數字與HTTP狀態碼沒有任何關系。

3、錯誤碼盡量有利于具有不同文化背景的開發者進行交流與代碼協作。

說明:英文單詞形式的錯誤碼不利于非英語母語國家(如阿拉伯語國家、希伯來語國家、俄羅斯語國家等)的開發者之間互相協作。

4、錯誤碼即人性,感性認知+口口相傳,使用純數字編排錯誤碼不利于感性記憶和分類。

二、異常處理

強制:

1、Java類庫中定義的可以通過預檢查方式規避的RuntimeException不應該通過catch的方式處理,如:NullPointerException、IndexOutOfBoundsException等。

說明:無法通過預檢查的異常不在此列,比如當解析字符串形式的數字時,可能存在數字格式錯誤,通過catch NumberFormatException實現。

2、異常被捕獲后不要用來做流程控制和條件控制。

說明:異常設計的初衷是解決程序運行中的各種意外,且異常的處理效率比條件判斷方式要低很多。

3、catch時請分清穩定代碼和非穩定代碼。穩定代碼一般指本機運行且執行結果確定性高的代碼。對于非穩定代碼的catch,盡可能在進行異常類型的區分后,再做對應的異常處理。

說明:對大段代碼進行try-catch,將使程序無法根據不同的異常做出正確的“應激”反應,也不利于定位問題,這是一種不負責任的表現。

正例:在用戶注冊的場景中,如果用戶輸入非法字符,或用戶名稱已存在,或用戶輸入的密碼過于簡單,那么在程序上會作出分門別類的判斷,并提示用戶。

4、捕獲異常是為了處理異常,不要捕獲了卻什么都不處理而拋棄之,如果不想處理它,請將該異常拋給它的調用者。最外層的業務使用者必須處理異常,將其轉化為用戶可以理解的內容。

5、在事務場景中,拋出異常被catch后,如果需要回滾,那么一定要注意手動回滾事務。

6、finally塊必須對資源對象、流對象進行關閉操作,如果有異常就要做try-catch操作。

說明:對于JDK 7及以上版本,可以使用try-with-resources方式。

7、不要在finally塊中使用return。

說明:try塊中的return語句執行成功后,并不馬上返回,而是繼續執行finally塊中的語句,如果此處存在return語句,則在此直接返回,無情地丟棄try塊中的返回點。

8、捕獲異常與拋異常必須完全匹配,或者捕獲異常是拋異常的父類。

9、在調用RPC、二方包或動態生成類的相關方法時,捕獲異常必須使用Throwable類攔截。

說明:通過反射機制調用方法,如果找不到方法,則拋出NoSuchMethod Exception。在什么情況下會拋出NoSuchMethodError呢?二方包在類沖突時,仲裁機制可能導致引入非預期的版本使類的方法簽名不匹配,或者在字節碼修改框架(比如:ASM)動態創建或修改類時,修改了相應的方法簽名。對于這些情況,即使在代碼編譯期是正確的,在代碼運行期也會拋出NoSuchMethodError。

推薦:

1、方法的返回值可以為null,不強制返回空集合或者空對象等,必須添加注釋充分說明在什么情況下會返回null值。此時數據庫id不支持存入負數而拋出異常。

說明:防止產生NPE是調用者的責任。即使被調用方法返回空集合或者空對象,對調用者來說,也并非高枕無憂,必須考慮到遠程調用失敗、序列化失敗、運行時異常等場景返回null值的情況。

2、防止產生NPE是程序員的基本修養,注意NPE產生的場景。

1)當返回類型為基本數據類型,return包裝數據類型的對象時,自動拆箱有可能產生NPE。

????????反例:public int f() { return Integer對象}, 如果為null,則自動拆箱,拋NPE。

2)數據庫的查詢結果可能為null。

3)集合里的元素即使isNotEmpty,取出的數據元素也可能為null。

4)當遠程調用返回對象時,一律要求進行空指針判斷,以防止產生NPE。

5)對于Session中獲取的數據,建議進行NPE檢查,以避免空指針。

6)級聯調用obj.getA().getB().getC();的一連串調用,易產生NPE。

????????正例:使用JDK 8的Optional類防止產生NPE。

3、定義時區分unchecked / checked異常,避免直接拋出new RuntimeException(),更不允許拋出Exception或者Throwable,應使用有業務含義的自定義異常。推薦業界已定義過的自定義異常,如:DAOException /ServiceException等。

參考:

1、對于公司外的HTTP/API開放接口,必須使用“errorCode”?;應用內部推薦異常拋出;跨應用間RPC調用優先考慮使用Result方式,封裝isSuccess()方法、?“errorCode”和“errorMessage”?。

說明:關于RPC方法返回方式使用Result方式的理由。

1)使用拋異常返回方式,調用方如果沒有捕獲到,就會產生運行時錯誤。

2)如果不加棧信息,只是new自定義異常,加入自己理解的errorMessage,對于調用端解決問題的幫助不會太多。如果加了棧信息,在頻繁調用出錯的情況下,數據序列化和傳輸的性能損耗也是問題。

2、避免出現重復的代碼(Don't Repeat Yourself)?,即DRY原則。

說明:隨意復制和粘貼代碼,必然導致代碼的重復,當以后需要修改時,需要修改所有的副本,容易遺漏。必要時抽取共性方法或公共類,甚至將代碼組件化。

三、日志規約

強制:

1、應用中不可直接使用日志系統(Log4j、Logback)中的API,而應依賴使用日志框架(SLF4J、JCL--Jakarta Commons Logging)中的API,使用門面模式的日志框架,有利于維護日志并保證各個類的日志處理方式統一。

2、所有日志文件至少保存15天,因為有些異常具備以“周”為頻次發生的特點。對于當天日志,以“應用名.log”保存在“/home/admin/應用名/logs/”目錄下,過往日志格式: {logname}.log.{保存日期},日期格式:yyyy-MM-dd。

3、根據國家法律,網絡運行狀態、網絡安全事件、個人敏感信息操作等相關記錄,留存日志的時間不少于六個月,并且進行網絡多機備份。

4、應用中的擴展日志(如打點、臨時監控、訪問日志等)命名方式:appName_logType_logName.log。logType為日志類型,如stats/monitor/access等;logName為日志描述。這種命名的好處是通過文件名就可以知道日志文件屬于哪個應用,哪種類型,有什么目的,這也有利于歸類查找。

說明:推薦對日志進行分類,如將錯誤日志和業務日志分開存放,既便于開發人員查看,也便于通過日志及時監控系統。

5、當輸出日志時,字符串變量之間的拼接使用占位符的方式。

說明:因為String字符串的拼接會使用StringBuilder的append()方式,所以有一定的性能損耗。使用占位符僅是替換動作,可以有效提升性能。

6、對于trace/debug/info級別的日志輸出,必須進行日志級別的開關判斷。

說明:在debug(參數)的方法體內,雖然當第一行代碼is Disabled(Level.DEBUG_INT)為真時(Slf4j的常見實現Log4j和Logback)會直接return,但是參數可能會進行字符串拼接運算。此外,如果debug(getName())這種參數內有getName()方法調用,則會浪費方法調用的開銷。

7、避免重復打印日志,否則會浪費磁盤空間,務必在日志配置文件中設置additivity=false。

8、在生產環境中禁止直接使用System.out或System. err輸出日志,或使用e.printStackTrace()打印異常堆棧。

說明:只有每次Jboss重啟時,標準日志輸出文件與標準錯誤輸出文件才滾動,如果大量輸出送往這兩個文件,則容易造成文件大小超過操作系統大小限制。

9、異常信息應該包括兩類:案發現場信息和異常堆棧信息。如果不處理,那么通過關鍵字throws往上拋出。

10、打印日志時,禁止直接用JSON工具將對象轉換成String。

說明:如果對象里某些get方法被覆寫,存在拋出異常的情況,則可能會因為打印日志而影響正常的業務流程的執行。

正例:打印日志時,僅打印業務相關屬性值或者調用其對象的toString()方法。

推薦:

1、謹慎地記錄日志。在生產環境中禁止輸出debug日志;有選擇地輸出info日志;如果使用warn記錄剛上線時的業務行為信息,則一定要注意日志輸出量的問題,避免把服務器磁盤撐爆,并及時刪除這些觀察日志。

說明:大量地輸出無效日志,既不利于提升系統性能,也不利于快速定位錯誤點。記錄日志時請思考:這些日志真的有人看嗎?看到這條日志你能做什么?能不能給問題排查帶來好處?

2、可以使用warn日志級別記錄用戶輸入參數錯誤的情況,避免當用戶投訴時無所適從。

說明:如非必要,請不要在此場景中打出error級別,避免頻繁報警。注意日志輸出的級別,error級別只記錄系統邏輯出錯、異常等重要的錯誤信息。

3、盡量用英文描述日志錯誤信息。如果日志中的錯誤信息用英文描述不清楚,可以使用中文描述,否則容易產生歧義。

說明:國際化團隊或海外部署的服務器,由于字符集問題,【強制】使用全英文注釋和描述日志錯誤信息。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ---內容來源《阿里巴巴開發手冊》

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/81565.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/81565.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/81565.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SOLID 面對象設計的五大基本原則

SOLID 原則的價值 原則核心價值解決的問題SRP職責分離,提高內聚性代碼臃腫、牽一發而動全身OCP通過擴展而非修改實現變化頻繁修改現有代碼導致的風險LSP確保子類行為的一致性繼承濫用導致的系統不穩定ISP定制化接口,避免依賴冗余接口過大導致的實現負擔…

Python 裝飾器詳解

裝飾器是 Python 中一種強大的語法特性,它允許在不修改原函數代碼的情況下動態地擴展函數的功能。裝飾器本質上是一個高階函數,它接受一個函數作為參數并返回一個新的函數。 基本裝飾器 1. 簡單裝飾器示例 def my_decorator(func):def wrapper():prin…

無損耗協議:PROFINET和EtherNet IP網關的高效安裝指南

作為風力發電機組監控系統的重要組成部分,PROFINET和EtherNet/IP協議轉換網關倍訊BX-606-EIP的安裝至關重要。作為安裝工,我們要確保網關安裝的高效順利,保證風力發電機組的穩定運行。 首先,我們需要仔細檢查網關的硬件接口,確保所有連接線纜與設備端口相匹配。網關…

Axure元件動作四:設置選中

親愛的小伙伴,在您瀏覽之前,煩請關注一下,在此深表感謝!如有幫助請訂閱專欄! Axure產品經理精品視頻課已登錄CSDN可點擊學習https://edu.csdn.net/course/detail/40420 課程主題:設置選中 主要內容:選中效果全面解析 應用場景:元件、元件組合需要被選中場景 案例展…

大模型為什么學新忘舊(大模型為什么會有災難性遺忘)?

字數:2500字 一、前言:當學霸變成“金魚” 假設你班上有個學霸,數學考滿分,英語拿第一,物理稱霸全校。某天,他突然宣布:“我要全面發展!從今天起學打籃球!” 一周后&am…

通過SMTP協議實現Linux郵件發送配置指南

一、環境準備與基礎配置 1. SMTP服務開通(以qq郵箱為例) 登錄qq郵箱網頁端,進入「設置」-「POP3/SMTP/IMAP」 開啟「SMTP服務」并獲取16位授權碼(替代郵箱密碼使用) 記錄關鍵參數: SMTP服務器地址&#…

react中安裝依賴時的問題 【集合】

目錄 依賴升級/更新 1、 npm install --save-dev 與 npm install 的區別 1. ?安裝位置(依賴類型)? 2. ?package.json 中的區別? 3. ?示例 4. ?何時使用哪種方式? 2、npm install 和 yarn add 有什么不一樣嗎 ?命令語法?: …

Coze 實戰教程 | 10 分鐘打造你的AI 助手

> 文章中的 xxx 自行替換,文章被屏蔽了。 📱 想讓你的xxx具備 AI 對話能力?本篇將手把手教你,如何用 Coze 平臺快速構建一個能與用戶自然交流、自動回復提問的 xxx助手,零代碼、超高效! 📌…

【Spring Cloud Gateway】Nacos整合遇坑記:503 Service Unavailable

一、場景重現 最近在公司進行微服務架構升級,將原有的 Spring Cloud Hoxton 版本升級到最新的 2021.x 版本,同時使用 Nacos 作為服務注冊中心和配置中心。在完成基礎框架搭建后,我使用 Spring Cloud Gateway 作為API 網關,通過 N…

寶塔面板屏蔽垃圾搜索引擎蜘蛛和掃描工具的辦法

首先進入寶塔面板,文件管理進入/www/server/nginx/conf目錄,新建空白文件kill_bot.conf。然后將以下代碼保存到當前文件中。 #禁止垃圾搜索引擎蜘蛛抓取if ($http_user_agent ~* "CheckMarkNetwork|Synapse|Nimbostratus-Bot|Dark|scraper|LMAO|Ha…

Docker拉取鏡像報錯Error response from daemon: Get “https://registry-1.docker.io/v2/“

記一次Docker拉取鏡像的報錯 使用docker拉取鏡像時,出現報錯 [rootcentos8 ~]# sudo docker pull mysql:8.0 Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.T…

Ansible模塊——文件內容修改

修改文件單行內容 ansible.builtin.lineinfile 可以按行修改文件內容,一次修改一行,支持正則表達式。 選項名 類型 默認值 描述 attributesstrnull 設置目標文件的 Linux 文件系統屬性(attribute bits),作用類似于…

如何用PDO實現安全的數據庫操作:避免SQL注入

如何用PDO實現安全的數據庫操作:避免SQL注入 在現代Web應用程序中,數據庫操作是核心功能之一。然而,SQL注入是一種常見的安全漏洞,攻擊者可以通過惡意輸入來操控數據庫,從而獲取敏感信息或破壞數據。使用PHP的PDO&…

使用大語言模型從零構建知識圖譜(中)

從零到一:大語言模型在知識圖譜構建中的實操指南 ©作者|Ninja Geek 來源|神州問學 還沒有看過上篇的讀者可以閱讀《使用大語言模型從零構建知識圖譜(上)》了解整個系列的內容 通過創建一個自定義流程來自動上傳業務數據 在這一節&#…

pycharm連接github(詳細步驟)

【前提:菜鳥學習的記錄過程,如果有不足之處,還請各位大佬大神們指教(感謝)】 1.先安裝git 沒有安裝git的小伙伴,看上一篇安裝git的文章。 安裝git,2.49.0版本-CSDN博客 打開cmd(…

uniapp在APP上如何使用websocket--詳解

UniApp 在 APP 端如何使用 WebSocket以及常見問題 一、WebSocket 基礎概念 WebSocket 是一種在單個TCP連接上進行全雙工通信的協議,適用于實時數據傳輸場景(如聊天室、實時游戲、股票行情等)。 與傳統HTTP對比 特性WebSocketHTTP連接方式…

物聯網賦能7×24H無人值守共享自習室系統設計與實踐!

隨著"全民學習"浪潮的興起,共享自習室市場也欣欣向榮,今天就帶大家了解下在物聯網的加持下,無人共享自習室系統的設計與實際方法。 一、物聯網系統整體架構 1.1 系統分層設計 層級技術組成核心功能用戶端微信小程序/H5預約選座、…

【Linux】ELF與動靜態庫的“暗黑兵法”:程序是如何跑起來的?

目錄 一、什么是庫? 1. C標準庫(libc) 2. C標準庫(libstdc) 二、靜態庫 1. 靜態庫的生成 2. 靜態庫的使用 三、動態庫 1. 動態庫的生成 2. 動態庫的使用 3. 庫運行的搜索路徑。 (1)原因…

滲透測試流程-中篇

#作者:允砸兒 #日期:乙巳青蛇年 四月廿一(2025年5月18日) 今天筆者帶大家繼續學習,網安的知識比較雜且知識面很廣,這一部分會介紹很多需要使用的工具。會用各種工具是做網安的基礎,ok咱們繼續…

[創業之路-358]:從歷史輪回到制度躍遷:中國共產黨創業模式的超越性密碼

人類文明的演進如同一條螺旋上升的階梯,從原始社會的公有制到資本主義私有制的巔峰,再到社會主義對公有制的重構,每一次制度迭代都伴隨著對前序文明的揚棄。中國共產黨自誕生之日起,便以“為人類求解放”為使命,在革命…