日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java日志规约

發布時間:2023/12/31 java 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java日志规约 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在日常的開發中,免不了會遇見Bug.如果系統有一份完善的日志,那么你與Bug交鋒,就是知己知彼,解決Bug自然會比較輕松。

相反,如果沒有一份完善的日志,那么與Bug交鋒,就是敵暗我明,最終只會被Bug整的心力交瘁,頭發稀疏。

所以,作為程序員,一定要把日志打印好。

寫好日志,不但是快速定位問題的好幫手,也是我們保護自己的好好利器。

為了更好的規范我們的日志,現在我們遵循阿里巴巴開發規范中的日志規約。

記錄日志時請思考:這些日志真的有人看嗎?看到這條日志你能做什么?能不能給問題排查帶來好處?

?

阿里規范

  • 應用中不可直接使用日志系統(Log4j、Logback)中的 API,而應依賴使用日志框架
    (SLF4J、JCL–Jakarta Commons Logging)中的 API,使用門面模式的日志框架,有利于維護和各個類的日志處理方式統一
  • 說明:日志框架(SLF4J、JCL–Jakarta Commons Logging)的使用方式(推薦使用 SLF4J)
    使用 SLF4J

    import org.slf4j.Logger; import org.slf4j.LoggerFactory; private static final Logger logger = LoggerFactory.getLogger(Test.class);

    使用 JCL:

    import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; private static final Log log = LogFactory.getLog(Test.class);

    ?
    2. 在日志輸出時,字符串變量之間的拼接使用占位符的方式。
    說明:因為 String 字符串的拼接會使用 StringBuilder 的 append()方式,有一定的性能損耗。使用占位符僅是替換動作,可以有效提升性能。

    正例:logger.debug("Processing trade with id: {} and symbol: {}", id, symbol);

    ?
    3. 避免重復打印日志,浪費磁盤空間,務必在日志配置文件中設置 additivity=false。

    正例:<logger name="com.taobao.dubbo.config" additivity="false">

    ?
    4. 生產環境禁止直接使用 System.out 或 System.err 輸出日志或使用e.printStackTrace()打印異常堆棧。
    ?
    5. 異常信息應該包括兩類信息:案發現場信息和異常堆棧信息。

    正例:logger.error("inputParams:{} and errorMessage:{}", 各類參數或者對象 toString(), e.getMessage(), e);

    ?
    6. 日志打印時禁止直接用 JSON 工具將對象轉換成 String。

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

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

    ?

  • 謹慎地記錄日志。生產環境禁止輸出 debug 日志;有選擇地輸出 info 日志;如果使用warn 來記錄剛上線時的業務行為信息,一定要注意日志輸出量的問題,避免把服務器磁盤撐爆,并記得及時刪除這些觀察日志。
  • 說明:大量地輸出無效日志,不利于系統性能提升,也不利于快速定位錯誤點。

    ?
    8. 可以使用 warn 日志級別來記錄用戶輸入參數錯誤的情況,避免用戶投訴時,無所適從。如非必要,請不要在此場景打出 error 級別,避免頻繁報警。

    說明:注意日志輸出的級別,error 級別只記錄系統邏輯出錯、異常或者重要的錯誤信息。

    ?

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

    其他規范

    ?

    打印日志中的"不要"

    1. 不要使用System.out.println打印日志

    初學者一般在開發中或者調試bug的時候,都會習慣性的使用System.out.println語句,輸出到控制臺中,觀察數據是否正常。開發或者調試完畢,很可能就忘記刪除,直接就發布到生產中去了。

    而在生產環境中,禁止使用System.out.println有兩點原因:

    • 當需要查看日志時,往往是從日志文件中去查看的。使用System.out.println,只會將日志打印到控制臺,并不會保存到日志文件中。
    • System.out.println是一個同步方法,在高并發的情況下,會嚴重影響性能。

    2. 不要使用e.printStackTrace()
    反例:

    try{// 業務代碼處理 }catch(Exception e){e.printStackTrace(); }

    正例:

    try{// 業務代碼處理 }catch(Exception e){log.error("你的程序有異常啦",e); }

    理由:

    • e.printStackTrace()打印出的堆棧日志跟業務代碼日志是交錯混合在一起的,通常排查異常日志不太方便。
    • e.printStackTrace()語句產生的字符串記錄的是堆棧信息,如果信息太長太多,字符串常量池所在的內存塊沒有空間了,即內存滿了,那么,用戶的請求就卡住了

    3.不要記錄了異常,又拋出異常

    反例:

    log.error("IO exception", e); throw new MyException(e);

    理由:

    這樣實現的話,通常會把棧信息打印兩次。這是因為捕獲了MyException異常的地方,還會再打印一次。 這樣的日志記錄,或者包裝后再拋出去,不要同時使用!否則你的日志看起來會讓人很迷惑。

  • 不要重復打印日志
    避免重復打印日志,只會浪費磁盤空間。如果你已經有一行日志清楚表達了意思,避免再冗余打印。
    反例
  • if(user.isVip()){log.info("該用戶是會員,Id:{}",user,getUserId());//冗余,可以跟前面的日志合并一起log.info("開始處理會員邏輯,id:{}",user,getUserId());//會員邏輯 }else{//非會員邏輯 }

    如果你是使用log4j日志框架,務必在log4j.xml中設置 additivity=false,因為可以避免重復打印日志.

    <logger name="com.taobao.dubbo.config" additivity="false">

    打印日志的“要”

  • 日志要打印出方法的入參、出參
    在項目中,經常會涉及到各個系統之間的交互。當出現問題時,為了快速定位是哪個系統出來問題,十分有必要打印出方法的入參和出參。比如說,方法進來的時候,打印入參。方法返回的時候,就是打印出參,返回值。入參的話,一般就是userId或者bizSeq這些關鍵信息。常見打印入參的常見有:
    • 系統接受消息通道的消息開處理事務
    • 系統開發接口供外部應用調用等
    public String testLogMethod(Document doc, Mode mode){log.debug(“method enter param:{},userId);String id = "666";log.debug(“method exit param:{},id);return id; }
  • 要選擇合適的日志格式
    理想的日志格式,應當包括這些最基本的信息:如當前時間戳(一般毫秒精確度)、日志級別,線程名字等等。在logback日志里可以這么配置:
  • <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{HH:mm:ss.SSS} %-5level [%thread][%logger{0}] %m%n</pattern></encoder> </appender>
  • 要使用日志框架SLF4J中的API。
    使用SLF4J框架,可以在部署時遷移到所需的日志記錄框架。這是因為SLF4J提供了對所有流行的日志框架的綁定,例如log4j,JUL,Simple logging和NOP。因此可以在部署時切換到任何這些流行的框架。
  • 無論使用哪種綁定,SLF4J都支持參數化日志記錄消息。由于SLF4J將應用程序和日志記錄框架分離, 因此可以輕松編寫獨立于日志記錄框架的應用程序。而無需擔心用于編寫應用程序的日志記錄框架。

    SLF4J提供了一個簡單的Java工具,稱為遷移器。使用此工具,可以遷移現有項目,這些項目使用日志 框架(如Jakarta Commons Logging(JCL)或log4j或Java.util.logging(JUL))到SLF4J。

  • 建議使用參數占位{},而不是用+拼接。
    這點上面講過了!

  • 要打印出e, 輸出全部錯誤信息
    反例1

  • try {//業務代碼處理 } catch (Exception e) {// 錯誤LOG.error('你的程序有異常啦'); }

    說明:異常e都沒有打印出來,所以壓根不知道出了什么類型的異常。

    反例2

    try {//業務代碼處理 } catch (Exception e) {// 錯誤LOG.error('你的程序有異常啦', e.getMessage()); }

    說明:e.getMessage()不會記錄詳細的堆棧異常信息,只會記錄錯誤基本描述信息,不利于排查問題。

    正例

    try {//業務代碼處理 } catch (Exception e) {// 錯誤LOG.error('你的程序有異常啦', e); }

    總結

    以上是生活随笔為你收集整理的Java日志规约的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。