2017-02-25 79 views
1

我想在基於Vert.x的項目中添加一些額外的調試信息,該項目正好使用io.vertx.core.logging.Logger進行日誌記錄。使用Lambda表達式參數化的Vert.x日誌語句

就我所知,通過查看the Javadoc,該類不提供具有與功能接口匹配的簽名的方法。

我想要輸出的日誌消息可以基於相當大的值集合。我想避免不必要的轉換。

這似乎讓我用下面的模式:

if (LOGGER.isDebugEnabled()) { 
    LOGGER.debug(buildMyLargeCollectionsStringRepresentation()); 
} 

此,在另一方面,讓我的代碼檢查isDebugEnabled()一次又一次。

爲了簡潔和潛在的優化,我寧願將它留給框架。

有沒有辦法以類似於java.util.Logger class的方式使用供應商?

回答

1

它看起來不像。但有一點小心,你可能沒有像isDebugEnabled()這樣的守衛功能。記錄器通常在格式化字符串之前檢查記錄函數內部的日誌級別。如果它確定日誌記錄級別匹配,則它將執行字符串格式設置,其中包括調用toString()對傳入以包含在格式化字符串中的任何參數。如果避免將複雜表達式直接傳遞到記錄器方法中,而是將表達式封裝在一個對象中,而該對象的功能將評估您希望記錄的表達式,那麼您可能會獲得警衛表達式的好處,而無需使用它們。

我不知道vertx如何將它的apis綁定到JUL日誌。這可能是第一個Object參數將作爲JUL中的供應商參數傳遞。如果沒有,你可以嘗試下面的技術,它可以適用於任何對其參數調用toString()的通用字符串記錄機制。

考慮下面的,它使用SLF4J的參數註釋:

debug("Doing something with {}", some_expression_that_is_expensive); 

在這個例子中,some_expression_that_is_expensive將被稱爲每次debug函數被調用時,調試日誌記錄是否被啓用。如果你不是有類如

class EncapsulatedExpression { 
    @Override 
    public String toString() { 
     return some_expression_that_is_expensive; 
    } 
} 

然後,你可以調用

debug("Doing something with {}", new EncapsulatedExpression()); 

然後some_expression_that_is_expensive如果日誌級別爲調試只會被調用。

你是在正確的軌道上說,一個Supplier將提供類似的懶評價一個更一般的方式,所以要得到你想要的,你需要一個工具來創造一些可以封裝Supplier,其toString()會造成什麼供應商進行評估。也許,像這樣的工作:

class ToStringSupplier<T> { 
    private Supplier<T> supplier; 

    public ToStringSupplier(Supplier<T> supplier){ 
     this.supplier = supplier; 
    } 

    public static <T> ToStringSupplier<T> lazily(Supplier<T> supplier){ 
     return new ToStringSupplier<>(supplier); 
    } 

    @Override 
    public String toString(){ 
     return Objects.toString(supplier.get()); // supplier could safely return null 
    } 
} 

你可以使用這樣的:

debug("Doing something with {}", lazily(() -> some_expression_that_is_expensive));