2

I am trying to setup tracing of multithread application. I have set up ThreadPool:

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setThreadNamePrefix("XXXXXX-");
        executor.initialize();

so there are several threads. One of the threads is listening to the SQS queue:

@Scheduled(fixedRateString = "${processing.queue.period:60000}")
public void process() {
..........................................................................
    for (SQSMessage sqsMessage : sqsMessages) {
        String messageReceiptHandle = null;
        try {
             messageReceiptHandle = sqsMessage.getReceiptHandle();
             processMessage(sqsMessage);
        }                               
    }
}
..........................................................................

    public void processMessage(SQSMessage sqsMessage) throws InterruptedException {

        log.debug("Start Processing request: '{}'.", sqsMessage);
        monitoringWorker.addEntityForMonitoring(sqsMessage, processor);
        processor.processMessage(sqsMessage);
        monitoringWorker.removeEntityForMonitoring(sqsMessage.getStagingPrefix());
    }

In this code snipet

monitoringWorker.addEntityForMonitoring(sqsMessage, processor);

sqsMessage is propagated to another scheduler:

@Component
public class MonitoringWorker {

   private List<EntityToMonitor> entitiesForMonitoring = new ArrayList<>();

   public void addEntityForMonitoring(AssetSQSMessage assetSQSMessage, AssetProcessorService service) {
        entitiesForMonitoring.add(new EntityToMonitor(assetSQSMessage, service));
    }

   @Scheduled(fixedDelay = 1000)
   public void monitor() {
        for (EntityToMonitor entity : entitiesForMonitoring) {
            log.info("testmessage");
        }
   }

the idea is to trace all the process from recieving message from SQS till the end of processing logic but all the thread has different trace ids, And when MonitoringWorker starts to process the message it takes another thread with different traceid:

enter image description here

How can I keep the same traceid, spanid could be different in Spring Cloud Sleuth 2.2.3

Dezmond1983
  • 31
  • 1
  • 4

2 Answers2

2

Use LazyTraceExecutor. This class propagates traceIds to new threads and create new spanIds in the process.

For more details see

Sudhir
  • 1,339
  • 2
  • 15
  • 36
  • Well yes, it perfectly works for ```@Async```. But I need ```@Scheduler```. And LazyTraceExecutor has different interface with Schedulers. – Dezmond1983 Jun 12 '20 at 15:17
  • @Dezmond1983 In the same article, `@Scheduled` support is also explained. Did you see that? Does it address your need? – Sudhir Jun 12 '20 at 15:22
  • It works only because they are using single thread in thread pull. If we are using several threads... It will have different traceIds. – Dezmond1983 Jun 12 '20 at 16:12
2

you can use LazyTraceThreadPoolTaskExecutor.

@Configuration
public class BeanConfigurations {

    private final BeanFactory beanFactory;

    @Autowired
    public BeanConfigurations(BeanFactory beanFactory){
        this.beanFactory=beanFactory;
    }

    @Bean("asyncExecutor")
    public TaskExecutor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor= new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(20);
        executor.setMaxPoolSize(30);
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setThreadNamePrefix("Async-");
        return new LazyTraceThreadPoolTaskExecutor(beanFactory,executor);
    }
}
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103