TraceId does not propagate between threads
See original GitHub issueDescribe the bug TraceId does not propagate between threads since version 2.2.2.RELESE of sleuth (Spring Cloud Hoxton.SR3) I’ve tested with verison 2.2.1.RELEASE (Hoxton.SR2) - works correctly On newest version - 2.2.5.RELEASE issue still persists.
Sample Here’s test Controller:
` package app.testing;
import brave.Span;
import brave.Tracer;
import brave.propagation.TraceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import java.util.Optional;
@RestController
public class TraceIdController {
private Tracer tracer;
@Autowired
public TraceIdController(Tracer tracer) {
this.tracer = tracer;
}
@GetMapping(value = "/api/v1/traceId/test")
public Mono<TraceIdDto> get() {
String traceId = getTraceId().orElse(null);
return Mono.defer(() -> Mono.just(getTraceId()))
.subscribeOn(Schedulers.elastic())
.map(elasticThreadId -> new TraceIdDto(traceId, elasticThreadId.orElse(null)));
}
private Optional<String> getTraceId() {
return Optional.of(tracer)
.map(Tracer::currentSpan)
.map(Span::context)
.map(TraceContext::traceIdString);
}
}
package app.testing;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class TraceIdDto {
private String nativeThreadTraceId;
private String elasticThreadTraceId;
}
`
And junit test that shows the problem: ` package app.testing;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class TraceIdControllerTest {
@Autowired
private WebTestClient webTestClient;
@Test
public void testTraceId() {
TraceIdDto traceIdDto = webTestClient.get().uri("/api/v1/traceId/test")
.exchange().expectStatus().isOk()
.expectBody(TraceIdDto.class)
.returnResult().getResponseBody();
assertThat(traceIdDto.getNativeThreadTraceId()).isEqualTo(traceIdDto.getElasticThreadTraceId());
}
}
`
Proposed solution
I’ve investiagted sleuth code a little bit, and I think the problem is in SleuthContextListener. I’ve compered this class with ContextRefreshedListener that existed in 2.2.1 version.
It seems like SleuthContextListener sets refreshed and closed flags to false, when appropriate event comes, instead to true.
... listener.refreshed.compareAndSet(false, event instanceof ContextRefreshedEvent); listener.closed.compareAndSet(false, event instanceof ContextClosedEvent); ...
Issue Analytics
- State:
- Created 3 years ago
- Reactions:2
- Comments:18 (9 by maintainers)

Top Related StackOverflow Question
@marcingrzejszczak here you go: https://github.com/jacekmg/sleuth-trace-id-propagation-test Let me know if that’s sufficient for you.
@vinodnholkar I didn’t find any new solutions, besides manual scope update that @marcingrzejszczak proposed.