1. 程式人生 > >大明對日誌的經驗總結

大明對日誌的經驗總結

一定的 調用 如果 系統 及其 deb 也不能 null 失敗

前言

說一個自己經歷過的事情,有一次我在開發一個通過csv文件批量導入交易的job的時候,在UAT環境上進行性能測試,發現執行失敗了。通過查看日誌發現,機器空間不足了,df -h一看發現32G的機器只有20k的空間,然後一看日誌文件的大小,就占了20G。日誌這東西,不能記得太多,不然影響性能而且占空間,也不能記得太少,不然出了問題,日誌查不到關鍵的信息

經驗

1. 使用直接SLF4J,而非具體的日誌框架

在項目開發中,應該在代碼中直接使用SLF4J,而非LOG4J、Logback等一些框架。SLF4J是Java裏上事實上的日誌標準接口,通過門面模式,可以很方便替換具體日誌框架的實現,降低了業務代碼與日誌框架的耦合度。

2. 生產環境只打印INFO級別的日誌信息

一般而言,debug及其以下級別的信息都是沒有必要顯示出來的,除非是開發定位bug的時候。

3. 使用isDebugEanbled等相似方法降低日誌性能消耗

頻繁計算日誌是否應該記錄會對系統性能產生影響,通過顯示調用判斷是否需要打印方法如isDebugEanbled來優化性能:

if (logger.isDebugEnabled()) {
    logger.debug("this is debug message");
}

4. 使用lambda表達式

該經驗針對第三條進一步優化。
如果我們簡單封裝了日誌方法,比如

public void degbug(String message) {
    if (logger.isDebugEnabled()) {
        logger.debug(message);
    }
}

這樣雖然通過isDebugEnabled方法判斷使用需要打印日誌提高了性能,但是如果message本身是有多個字符串拼接而成的話仍然會消耗一定的資源,比如調用上文的debug方法:

debug("client" + (clientId) + "is error");

盡管使用isDebugEnabled方法,但是在該方法調用入參的時候會先拼接message這個參數,然後在調用isDebugEnabled方法進行判斷,如果此時是不需要打印的話,那麽這個拼接message的消耗就白白浪費了。應該先判斷是否需要打印,然後在拼接字符串。我們可以使用lambda表達式懶求值的特性實現:

public void degbug(Supplier<String> supplier) {
    if (logger.isDebugEnabled()) {
        logger.debug(supplier != null ? supplier.get() : null);
    }
}

說明

基於slf4j簡單封裝,實現了以上經驗的第三、四點。

下載地址:Github, 碼雲。

大明對日誌的經驗總結