2014-01-15 126 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