在执行程序服务中记录父线程名称

时间:2015-04-21 18:40:09

标签: java multithreading spring logging spring-integration

我在Spring-integration上下文中使用Spring task:executor。调用任务时,日志如下所示:
2015-04-21 10:56:14,371 INFO [com.Class] (activatorExecutor-2:null) Processing user: abc
下面是我的log4j转换模式:
%d %-5p [%c] (%t:%x) %m%n %throwable{10}

问题是,是否可以将调用线程的名称放入MDC中,或者作为子线程名称的前缀,如下所示:
2015-04-21 10:56:14,371 INFO [com.Class] (activatorExecutor-2:parentThread1) Processing user: abc
或者这个:
2015-04-21 10:56:14,371 INFO [com.Class] (parentThread1_activatorExecutor-2:null) Processing user: abc
这样我就可以关联到哪个线程激活了这个执行器任务。谢谢。

2 个答案:

答案 0 :(得分:3)

我没有一个完整的经过深思熟虑的解决方案,但我建议您查看Java Configuration approach

我可以看到您应该能够选择Executor的实现来用于通过@EnableAsyncAsyncConfigurer运行您的主题。示例(ThreadPoolTaskExecutor)中提供的实现具有方法ExecutorConfigurationSupport#setThreadFactory(ThreadFactory),您可以使用该方法自定义线程的创建方式。

您可以创建ThreadFactory的实现,它使用委托ThreadFactory来实际创建线程,但您现在可以使用一个钩子来根据您的条件命名线程。如上所述进行连接,希望它能为您解决。

 @Configuration
 @EnableAsync
 public class AppConfig implements AsyncConfigurer {

      @Bean
      public MyAsyncBean asyncBean() {
          return new MyAsyncBean();
      }

      @Override
      public Executor getAsyncExecutor() {
          ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
          executor.setCorePoolSize(7);
          executor.setMaxPoolSize(42);
          executor.setQueueCapacity(11);
          //executor.setThreadNamePrefix("MyExecutor-");
          executor.setThreadFactory(myThreadFactory());
          executor.initialize();
          return executor;
      }

      public ThreadFactory myThreadFactory() {
          return new MyCustomThreadFactoryThatKnowsHowToProperlyNameThreads();
      }

      @Override
      public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
          return MyAsyncUncaughtExceptionHandler();
      }
  }

这是不那么经过深思熟虑的部分发挥作用的地方。我想我会让你想出最适合你需要的ThreadFactory实现。

答案 1 :(得分:1)

您的log4j模式正常(嵌套诊断上下文),但您需要通过调用以下方式自行提供:

org.apache.log4j.NDC.push("parentThread1");

...在适当的地方"。


或者你使用"映射"诊断上下文,带有模式:

... %X{myKey} ...

..和喂养:

org.apache.log4j.MDC.put("myKey", "parentThread1");