日誌到底該如何打印?

最近在做新項目,一直在加班,期間遇到很多問題,我把一部分歸類爲設計原則的問題,當然,這裏的設計原則不是特指那個SOLID五大原則,這裏是指更廣義的設計原則,不喜勿噴。

今天,我們來看第一個問題: 日誌到底該如何打印?

咋一看,這個問題很簡單,其實不然,我隨手寫幾個,您看看。

log.error("xxxxx");

log.error(e.getMessage());

log.error("xxxxx", e.getMessage());

log.error("xxxxx {}", e.message());

log.error("xxxxx {}", e);

好了,就隨便寫這麼多,地鐵上打字不太方便,您認爲上面那些日誌打印方式哪些是正確的?

實話說,沒有正確的,全是錯的。怎麼樣,是不是踩坑了,是不是給別人埋過這樣的坑。

那麼,怎麼打印日誌纔是正確的呢?

如果您使用的是slf4j,那麼,只有下面這一種是正確的:

log.error("xxxxx, userId={}, xxParam={}", userId, xxParam, e);

首先,打印日誌必須帶上上下文信息,比如,用戶ID,關鍵參數,同時,如果是捕獲異常裏面打印的日誌,必須把原來的e打印出來,否則,排查日誌想死的心都有了。

比如,我最近就遇到一個同學,他把遠程調用用一個try catch包着,並在catch中捕獲了異常,打印了日誌"遠程調用錯誤xxx",呵呵,有一次請求失敗,非要說遠程調用失敗,對方出錯了,對方說我沒收到請求呀,兩人撕逼,最後找到我,我一看這代碼,說了一句,把e打印出來再重新調用,結果可想而知,他自己空指針了,呵呵了。

再說回上面的打印方式,有的同學可能會質疑,前面引號裏明明是兩個大括號,後面卻出現3個變量,確定這個e能打印出來?

你是在懷疑我嗎?自己看源碼去。源碼中已經明確寫了如果最後一個參數是Exception類型,就不會參與字符串格式化,會單獨拿出來打印,同時,可以打印出堆棧信息。看源碼去吧,我在地鐵上,就不截圖了。

你以爲本篇文章就結束了嗎?那你就錯了。

有沒有更優雅的日誌打印方式呢?

我認爲,最好的日誌是以解決問題的方式打印日誌。

怎麼理解呢?

我們以服務註冊爲例,當註冊中心地址不通的時候,我們能不能這樣打印呢?

"從 112.112.112.112 到註冊中心 113.113.113.113的網絡不通,請檢查註冊中心是否啓動,網絡防火牆是否暢通,balabala"。

這樣的方式就比較好,給使用者提供解決方案,你只要按着給出的方案排查一下,大概率就能解決了你的問題,這纔是最優雅的打印姿勢。

好了,今天的內容就到這裏,嗐,差點坐過站。

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