Mikrometerspur für die asynchrone Methode und die geplante MethodeJava

Java-Forum
Anonymous
 Mikrometerspur für die asynchrone Methode und die geplante Methode

Post by Anonymous »

Ich habe eine Spring Boot-Anwendung mit geplanten Jobs, die asynchrone Methoden aufrufen. Die geplante Methode erhält automatisch eine Trace-ID, diese wird jedoch nicht an die asynchronen Methoden weitergegeben, es sei denn, ich erstelle manuell Spans in den asynchronen Methoden. Ich benötige für jede geplante Ausführung eine gemeinsame Trace-ID für alle Vorgänge mit unterschiedlichen Span-IDs für jeden asynchronen Vorgang.
Aktuelles Setup:
Spring Boot 3.5.4 Micrometer 1.15.2 mit Brave Bridge zum Tracing von Log4j2 mit MDC für strukturierte Protokollierung ThreadPoolTaskExecutor für asynchrone Verarbeitung
Gibt es eine Möglichkeit, meinen aktuellen Ansatz sauberer zu gestalten? sieht robust aus?
Hier ist der Code
Das mache ich gerade, es scheint zu funktionieren, sieht es korrekt aus? Sehen Sie irgendwelche Probleme? Gibt es eine sauberere Lösung?
AsyncConfig.java

Code: Select all

import io.micrometer.context.ContextSnapshot;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Configuration
@EnableAsync
public class AsyncConfig {

public static final String THREAD_POOL_NAME = "threadPoolTaskExecutor";

@Value("${thread-pools.data-poller.max-size:10}")
private int threadPoolMaxSize;

@Value("${thread-pools.data-poller.core-size:5}")
private int threadPoolCoreSize;

@Value("${thread-pools.data-poller.queue-capacity:100}")
private int threadPoolQueueSize;

@Bean(name = THREAD_POOL_NAME)
public ThreadPoolTaskExecutor getThreadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setMaxPoolSize(threadPoolMaxSize);
executor.setCorePoolSize(threadPoolCoreSize);
executor.setQueueCapacity(threadPoolQueueSize);
// Add context propagation
executor.setTaskDecorator(runnable ->
ContextSnapshot.captureAll().wrap(runnable)
);
return executor;
}
}
DataProcessor.java

Code: Select all

import io.micrometer.tracing.Span;
import io.micrometer.tracing.Tracer;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Slf4j
@Service
@RequiredArgsConstructor
public class DataProcessor {

@NonNull
private final Tracer tracer;

public static final String THREAD_POOL_NAME = "threadPoolTaskExecutor";

@Async(THREAD_POOL_NAME)
public void processPendingData() {
Span span = tracer.nextSpan().name("process-pending-data").start();
try (Tracer.SpanInScope ws = tracer.withSpan(span)) {
log.info("Processing pending items");
// Now shows correct traceId and unique spanId!
// Business logic here
} finally {
span.end();
}
}

@Async(THREAD_POOL_NAME)
public void processRetryData() {
Span span = tracer.nextSpan().name("process-retry-data").start();
try (Tracer.SpanInScope ws = tracer.withSpan(span)) {
log.info("Processing retry items");
// Now shows correct traceId and unique spanId!
// Retry logic here
} finally {
span.end();
}
}
}
PollingService.java

Code: Select all

import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

@Slf4j
@Service
@EnabledScheduling
@RequiredArgsConstructor
public class PollingService {

@NonNull
private final DataProcessor dataProcessor;

// the trace id automatically spawns for this
@Scheduled(fixedDelay = 5000)
public void pollData() {
log.info("Starting data polling");
// Shows traceId and spanId correctly in logs

// These async calls lose trace context
dataProcessor.processPendingData();
dataProcessor.processRetryData();
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post