如何使錯誤日誌更加方便排查問題

2022-01-13 13:21:26 字數 3078 閱讀 5140

在程式中打錯誤日誌的主要目標是為更好地排查問題和解決問題提供重要線索和指導。但是在實際中打的錯誤日誌內容和格式變化多樣,錯誤提示上可能殘缺不全、沒有相關背景、不明其義,使得排查解決問題成為非常不方便或者耗時的操作。而實際上,如果程式設計的時候稍加用心,就會減少排查問題的很多無用功。 在闡述如何編寫有效的錯誤日誌之前, 了解錯誤是怎麼產生的,  非常重要。

錯誤是如何煉成的

對於當前系統來說, 錯誤的產生由三個地方引入:

1.  上層系統引入的非法引數。 對於非法引數引入的錯誤, 可以通過引數校驗和前置條件校驗來截獲錯誤;

2.  與下層系統互動產生的錯誤。 與下層互動產生的錯誤, 有兩種: 

對於這種情況, 可以採用超時補償機制,預先將任務記錄下來,通過定時任務在後續將資料訂正過來。

更好的設計方案 ?  

對於這種情況, 需要與下層開發人員溝通, 協調子系統之間的互動;

需要根據下層返回的錯誤碼和錯誤描述做適當的處理或給予合理的提示資訊。

無論哪一種情況, 都要假設下層系統可靠性一般, 做好出錯的設計考慮。

3.  本層系統處理出錯。 

原因一: 疏忽導致。疏忽是指程式設計師能力完全可避免此類錯誤但實際上沒做到。比如將 && 敲成了 & , == 敲成了 = ;  邊界錯誤, 復合邏輯判斷錯誤等。 疏忽要麼是程式設計師注意力不夠集中, 比如處於疲倦狀態、加班通宵、邊開會邊寫程式; 要麼是急著實現功能,沒有顧及程式的健壯性等。

原因三: 邏輯耦合緊密導致。由於業務邏輯耦合緊密, 隨著軟體產品一步步發展, 各種邏輯關係錯綜複雜, 難以看到全域性狀況, 導致區域性修改影響波及到全域性範圍,造成不可預知的問題。

原因十: 業務不熟悉導致的錯誤。在中大型系統, 部分業務邏輯和業務互動都比較複雜, 整個的業務邏輯可能存在於多個開發同學的大腦裡, 每個人的認識都不是完整的。這很容易導致業務編碼錯誤。 

改進措施: 通過多人討論和溝通, 設計正確的業務用例, 根據業務用例來編寫和實現業務邏輯; 最終的業務邏輯和業務用例必須完整存檔; 在業務介面中註明該業務的前置條件、處理邏輯、後置校驗和注意事項; 當業務變化時, 需要同步更新業務注釋; **review。 業務注釋是業務介面的重要文件, 對業務理解起著重要的快取作用。

原因十一: 設計問題導致的錯誤。比如同步序列方式會有效能、響應慢的問題, 而併發非同步方式可以解決效能、響應慢的問題, 但會帶來安全、正確性的隱患。非同步方式會導致程式設計模型的改變, 新增非同步訊息推送和接收等新的問題。使用快取能夠提高效能, 但是又會存在快取更新的問題。 

改進措施: 編寫和仔細評審設計文件。 設計文件必須闡述背景、需求、所滿足的業務目標、要達到的業務效能指標、可能的影響、設計總體思路、詳細方案、預見該方案的優缺點及可能的影響; 通過測試和驗收, 確保改設計方案確實滿足業務目標和業務效能指標。

原因十二: 未知細節問題導致的錯誤。比如緩衝區溢位、 sql 注入攻擊。 從功能上看是沒有問題的, 但是從惡意使用上看, 是存在漏洞的。 再比如, 選擇 jackson 庫做 json 字串解析, 預設情況下, 當物件新增字段時會導致解析出錯。必須在物件上加 @jsonignoreproperties(ignoreunknown = true) 註解才能正確應對變化。如果選用其他 json 庫就不一定有這個問題。

改進措施:  一方面要通過經驗積累, 另一方面, 考慮安全問題和例外情況, 選擇成熟的經過嚴格測試的庫。

原因十三: 隨時間變化而出現的bug。有些解決方案在過去看來是很不錯的,但在當前或者未來的情景中可能變得笨拙甚至不中用,也是常見的事情。比如像加密解密演算法, 在過去可能認為是完善的, 在破解之後就要慎重使用了。

系統出現的常見錯誤:

1.  實體在資料庫中的記錄不存在, 必須指明是哪個實體或實體標識;

2.  實體配置不正確, 必須指明是哪個配置有問題,正確的配置應該是什麼;

4.  實體操作前置條件不滿足, 必須指明需要滿足什麼前置條件,當前的狀態是什麼;

5.  實體操作後置校驗不滿足, 必須指明需要滿足什麼後置校驗, 當前的狀態是什麼;

6.  效能問題導致超時, 必須指明是什麼導致的效能問題,後續如何優化;

7.  多個子系統互動通訊出錯導致之間的狀態或資料不一致?

大多數錯誤都是由多種原因組合產生。 但每一種錯誤必定有其原因。 在解決錯誤之後, 要深入分析錯誤是如何發生的, 如何避免這些錯誤再次發生。 努力就能成功, 但是:反思才能進步 !

如何編寫更容易排查問題的錯誤日誌

if ((storagetype == storagetype.dfs1 || storagetype ==storagetype.dfs2)

&& (zone.hasstoragetype(storagetype.io3) ||zone.hasstoragetype(storagetype.io4))) else

catch

(exception ex)

沒有指明插入失敗的 control ip. 如果加上 control ip 關鍵字, 更容易搜尋和鎖定錯誤。

if(alimonitorreporter == null

) else

if (diskwbps == null && diskrbps == null && diskwiops == null    && diskriops == null

)

4. 排查問題的引導內容不明確:

if (!ncresourceservice.isncresourceenough(ncresourcedo,    vmresourcecondition)) 

解決方案:  通過改進程式或程式技巧, 盡可能揭示出具體的差異所在, 減少人工比對的操作。

日誌排查問題總結

寫在前面 因為公司負責的專案流程鏈路很長,經常需要排查問題定位問題。目前專案是把每個service的方法前後都加上了入參和返回值的列印。接管專案後,總結了一下通過日誌定位問題的經驗,希望以後排查問題能有一些幫助。第二版 運單後台排查問題的方法總結 邏輯熟悉時 4.再根據測試 現場人員描述的描述以及自...

排查問題 檢視日誌的正確開啟方式

開啟超大日誌檔案,檢視日誌 用分割檔案的命令 split b 200m catalina.out 每個檔案200m 檢視日誌 方式一 tail f aaa.log 實時follow aaa.log n x aaa.log x 最後幾行 xf aaa.log 注 tailf 等同於tail f n 1...

效能優化 記憶體持續上公升,該如何排查問題

你肯定遇到過記憶體溢位,或是記憶體使用率過高的問題。碰到記憶體持續上公升的情況,其實我們很難從業務日誌中檢視到具體的問題,那麼面對多個程序以及大量業務執行緒,我們該如何精準地找到背後的原因呢?常用的監控和診斷記憶體工具 工欲善其事,必先利其器。平時排查記憶體效能瓶頸時,我們往往需要用到一些 linu...