2014-01-15 127 views
0

我希望爲每個應用程序使用單獨的日誌文件,同時只使用一個logback.xml文件。因此我使用的是SiftingAppender未將MDC值傳遞給請求

每個應用程序都有它自己的WebApplicationInitializer,它分配一個特定的MDC

當我啓動我的Tomcat服務器時,所有的日誌文件都會按照它們應該分割的方式進行分割。

但是,當我向服務器發送請求時,日誌輸出被寫入未知的文件。顯然,MDC值不能被讀取。

據我所知,MDC值是從父線程複製到子線程。每個請求的線程在哪裏創建,以便我可以在那裏分配MDC值?

回答

2

雖然經典的servlet容器如Tomcat使用線程每個請求模型,你不能依靠單一的線程來一個Web應用程序的任何映射。這是因爲請求是從容器管理的線程的池中提供的,例如。想象一個線程池3個線程A,B和C,這些服務請求,其中的兩個web應用W1和W2以循環方式之間交替:

request 1 on W1 serviced by A 
request 2 on W2 serviced by B 
request 3 on W1 serviced by C 
request 4 on W2 serviced by A 
... 

正如你可以看到,螺紋的第一處理請求,以webapp W1,後來被重新用於請求web應用程序W2。因此,您無法將一個Web應用程序ID分配給一個線程並完成它。取而代之的是,在每一個請求,你必須

  • 集在web-app ID在線程MDC處理請求
  • 移除請求的線程在web-app ID處理完成後,前

這兩項任務都可以通過Servlet Filter完成。 logback documentation也在「MDC and Managed Threads」部分對此進行了說明。甚至有一個sample filter implementation可用,您可以修改以適應您的需求。

+0

另請參見https://stackoverflow.com/questions/6073019/how-to-use-mdc-with-thread-pools –

+1

給出的答案適用於您的程序控制創建線程(或創建線程池)。請注意,Web應用程序通常不是這種情況。 – Pyranja

+0

我在傳入過濾器中設置MDC屬性,並在傳出過濾器中清除它,並且我的Servlet容器(Tomcat)上運行了一個**單** Web應用程序。 假設每個線程在任何給定的時間只處理一個請求,這仍然是安全的嗎? – Shakkalakka