2013-11-15 102 views
2

我想爲日誌語句添加一個唯一的標識符,這樣我就可以在每個日誌語句中添加文檔(外部例如wiki),以便用戶可以快速訪問相關消息使用id的文檔。我想使用的日誌框架是SLF4J/logback。使用SLF4J時日誌消息的ID

我無法找到有關相關方法的文檔,除了關於審計框架的一些內容。

有一種Marker概念,我認爲它可以用於ID注入,或者我可以將ID添加到消息文本本身。

我該如何將ID添加到日誌報表中「正確的方式」?我有沒有想過的可能性?

編輯

術語唯一ID只是指出有應該每日誌語句的標識符。開發者將這樣一個ID添加到一個表/枚舉/不管手動,這可能是錯誤的。 這樣的ID必須是穩定的,所以文檔可以基於它。所以ID本身並不是我想知道的。

我的問題是:將ID與消息文本一起推入記錄器的正確方法是什麼?如果我將標識嵌入到消息文本中,還是存在其他可能性,標記是否適合這種需求?

所以,基本上,我會用

logger.info(IDMarkers.DB_CONNECTION_FAILED, "no connection to the database"); 

或而不只是

logger.info("[{}] no connection to the database", LogIDs.DB_CONNECTION_FAILED); 

第一種方法的優點是顯示的ID是高達記錄系統/它的配置。

+0

你想如何使id唯一?通過電話?通過線程?通過代碼行? – zenbeni

+0

@zenbeni:日誌語句(例如'logger.debug('some message text')')應該得到ID。這樣的陳述會產生例如每個呼叫都有一個日誌條目,如[ID1234]某個消息文本。 –

+0

在運行時獲取執行上下文很昂貴:http://stackoverflow.com/questions/17473148/dynamically-get-the-current-line-number所以我認爲你應該在消息中靜態執行它。 – zenbeni

回答

0

唯一在一定範圍內是唯一的。最終,即使每個intlong值都將被使用。

所以想想「唯一性」對你來說意味着什麼。然後使用一個包裝器,它將確保您的日誌記錄通過插入的該ID進行處理。

請注意,對於slf4j,您正在處理的是一個interface,這將使許多日誌記錄API 一致。這意味着你可能不會選擇子類,甚至無法注入接口的實現來確保一致的日誌記錄。因此,您將受限於像包裝您的日誌API(最好通過「一致」界面)的技術。

package mypackage.log; 

public class LoggerWrapper implements org.log4j.Logger { 

    private org.log4j.Logger logger; 

    public LoggerWrapper(org.log4j.Logger logger) { 
    this.logger = logger; 
    } 

    public String getUniqueId() { 
    return ...; 
    } 

    public void info(String message, Object params...) { 
    logger.info(String.format("[%d] %s", getUniqueId(), message), params)); 
    } 

    ... implement all the other methods ... 
} 

,這意味着你將不得不作出自己的LoggerFactory界面太

public Logger getLogger(String name) { 
    return new LoggerWrapper(org.sql4j.LoggerFactory(name)); 
} 

雖然上面的代碼有瑕疵(不實際測試吧);希望它會給你一個想法。

+0

我更新了我的問題,指出它的方向。你提出的解決方案會給我一個獨特的ID每個日誌條目,這將不支持我將文檔鏈接到日誌聲明... –

+0

我的解決方案會給你一個唯一的ID爲你想要的任何東西。例如,你可以用一個常量字符串構造包裝器,然後它將成爲每個記錄器的唯一日誌ID。或者你可以在'getUniqueId()'中使用線程檢測代碼來爲每個線程設置一個唯一的ID。由您決定獨特性。 –