2017-10-09 75 views
2

我有這個日誌相當嚴重的Web應用程序。我們已經爲每個請求線程實施了對MDC的調用,以便能夠在我們的日誌中跟蹤用戶。記錄可選鍵值

一個的LogMessage可以看看如下:

INFO [2017-10-09 10:10:55,841] user_uuid=123-123-123 com.myapp.SomeClass: Some log message... 

現在的問題是,大部分的時間,沒有當前用戶的存在,我們沒有在上面的日誌例子中user_uuid現場使用。因此,相反,它會是這樣的:

INFO [2017-10-09 10:10:55,841] user_uuid= com.myapp.SomeClass: Some log message... 

有沒有,如果沒有MDC值不寫在日誌中的MDC鍵&值的方法嗎?一些日誌格式我還沒有找到?

我希望它看起來像這樣,如果沒有MDC價值發現:

INFO [2017-10-09 10:10:55,841] com.myapp.SomeClass: Some log message... 

以上(MDC)的實例配置,像這樣:

%-5p [%d{ISO8601,UTC}] user_uuid=%mdc{user_uuid:-} %c: %m%n%rEx 
+0

您可以只顯示完整的MDC(這當然要求您只存儲重要信息),那麼它只會記錄存在的內容。在你的例子中,你已經對'user_uuid ='部分進行了硬編碼,所以這不會去任何地方。 – Kayaman

+0

請參閱https://stackoverflow.com/questions/24616745/how-to-conditionally-add-text-from-mdc-on-a-log4j-pattern以獲得重複。 – Kayaman

回答

1

此項目在您的模式...

user_uuid=%mdc{user_uuid:-} 

...由兩個部分組成:

  1. 靜態「根」(即,分配的左側),這總是出現在輸出中。在Logback初始化時做出決定。

  2. 值(即賦值的右側),如果填充了MDC屬性user_uuid,則該值僅出現在輸出中。包含這個的決定是在運行時爲每個日誌事件做出的。

也許不會告訴你任何新的東西出現,但關鍵的一點是,左側的包容無法通過評估您的應用程序發出的每個日誌事件時踢在任何條件邏輯被撤銷。 Logback的PatternLayoutBase遍歷它的給定模式,每次涉及到條件或可導出的內容時,它會對其進行評估並將評估值附加到正在穿過的模式。所以,爲你的模式;在甚至開始評估MDC條件之前,Logback已經爲當前的StringBuilder分配了「user_uuid =」。

但是,您可以通過與填充user_uuid MDC屬性達到預期的最終目標:user_uuid=<the user id>,然後改變你的登錄模式只需登錄該MDC值不分配。例如:

%-5p [%d{ISO8601,UTC}] %mdc{user_uuid:-}%c: %m%n%rEx 

有了以下日誌調用這個模式...

logger.info("Does this include the user_uuid?"); 
MDC.put("user_uuid", "user_uuid=me "); 
logger.info("Or does this include the user_uuid?"); 

...會發出:

INFO [2017-10-09 11:15:22,420] com.stackoverflow.SomeClassTest: Does this include the user_uuid? 
INFO [2017-10-09 11:15:22,435] user_uuid=me com.stackoverflow.SomeClassTest: Or does this include the user_uuid? 

雖然這是一個有點尷尬,因爲你必須記住,包括在MDC值的後面加上一個空格和該user_uuid MDC值僅適用於該特定模式中記錄有用的(而簡單地包括user_uuid - 沒有左側和等號運算符 - 會更普遍有用)。

如果這些缺點使這個方法unuseable你那麼我認爲你必須卡住成的logback的PatternLayoutBaseFormattingConverter實現某種形式的先行或修改正在進行的StringBuilder如果右手的一些方法賦值的一端返回一個空字符串。

+0

非常全面的答案!非常感謝:) 我將創建一些util類來管理MDC'put'調用。 (這將用'key = '包裝它們 –