Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reactive WebClient - TraceId is not propagated to scope function #43421

Closed
mkubele opened this issue Dec 4, 2024 · 3 comments
Closed

Reactive WebClient - TraceId is not propagated to scope function #43421

mkubele opened this issue Dec 4, 2024 · 3 comments
Labels
for: external-project For an external project and not something we can fix status: duplicate A duplicate of another issue

Comments

@mkubele
Copy link

mkubele commented Dec 4, 2024

TraceId is not correctly propagated to scope function after a reactive WebClient call.

Demo project is available here

current output:

[6750294cfcbdfb64f056ab0605a90d48-f056ab0605a90d48] com.example.demo.Service                 : Hello, World!
[6750294cfcbdfb64f056ab0605a90d48-f056ab0605a90d48] com.example.demo.Service                 : another log message
[6750294cfcbdfb64f056ab0605a90d48-f056ab0605a90d48] com.example.demo.ServiceClient           : Response received
[                                                 ] com.example.demo.ServiceClient           : Log from also block

expected:

[6750294cfcbdfb64f056ab0605a90d48-f056ab0605a90d48] com.example.demo.Service                 : Hello, World!
[6750294cfcbdfb64f056ab0605a90d48-f056ab0605a90d48] com.example.demo.Service                 : another log message
[6750294cfcbdfb64f056ab0605a90d48-f056ab0605a90d48] com.example.demo.ServiceClient           : Response received
[6750294cfcbdfb64f056ab0605a90d48-f056ab0605a90d48] com.example.demo.ServiceClient           : Log from also block
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Dec 4, 2024
@philwebb
Copy link
Member

philwebb commented Dec 4, 2024

I believe this is the expected behavior, @bclozel or @sdeleuze might be able to confirm for sure. The observation is only active whilst the exchange is in progress (see this code).

Your .also { log.info("Log from also block") } call happens after the exchange has completed and therefore outside of the observation.

@philwebb philwebb closed this as not planned Won't fix, can't repro, duplicate, stale Dec 4, 2024
@philwebb philwebb added status: invalid An issue that we don't feel is valid and removed status: waiting-for-triage An issue we've not yet triaged labels Dec 4, 2024
@philwebb philwebb reopened this Dec 4, 2024
@philwebb
Copy link
Member

philwebb commented Dec 4, 2024

Actually, I take that back. I see now that the trace ID should remain since it's a child of the Service call. I think this will need input from the Framework or Micrometer team.

@philwebb philwebb added status: waiting-for-triage An issue we've not yet triaged and removed status: invalid An issue that we don't feel is valid labels Dec 4, 2024
@bclozel
Copy link
Member

bclozel commented Dec 5, 2024

This log statement does not print the traceId because there is no traceId in the current coroutine execution context; "also" is a coroutine operator:

.also {
	log.info("Log from also block")
}

"map" is a reactor operator and reactor reinstates threadlocals registered with the context propagation library; this log statement prints the traceId because the TraceId has been reinstated by reactor as a threadlocal. This has been enabled with Hooks.enableAutomaticContextPropagation() in your main application class (also see https://docs.spring.io/spring-boot/appendix/application-properties/index.html#application-properties.core.spring.reactor.context-propagation if you would like to use a property instead):

.map {
	log.info("Response received")
	it
}

So to summarize:

  • blocking code is executed on a thread with ThreadLocals
  • reactor is non-blocking and operators can reinstate threadlocals in operators, by looking at the reactor context
  • coroutines are non-blocking and it can reinstate threadlocals in operators, but this must be done manually with the coroutine context

I've amended your sample with the PropagationContextElement class taken from spring-projects/spring-framework#32165 (comment) and the following:

suspend fun getString(): String {
	return withContext(PropagationContextElement(coroutineContext)) {
		client
			.get()
			.retrieve()
			.toEntity(String::class.java)
			.map {
				log.info("Response received")
				it
			}
			.awaitSingle()
			.body!!
			.also {
				log.info("Log from also block")
			}
	}
}

This logs:

2024-12-05T08:53:59.143+01:00  INFO [,67515c1779afeb3d47c600ee55d23b98,47c600ee55d23b98] 7306 --- [ctor-http-nio-3] [67515c1779afeb3d47c600ee55d23b98-47c600ee55d23b98] com.example.demo.Service                 : Hello, World!
2024-12-05T08:53:59.143+01:00  INFO [,67515c1779afeb3d47c600ee55d23b98,47c600ee55d23b98] 7306 --- [ctor-http-nio-3] [67515c1779afeb3d47c600ee55d23b98-47c600ee55d23b98] com.example.demo.Service                 : another log message
2024-12-05T08:53:59.406+01:00  INFO [,67515c1779afeb3d47c600ee55d23b98,47c600ee55d23b98] 7306 --- [ctor-http-nio-3] [67515c1779afeb3d47c600ee55d23b98-47c600ee55d23b98] com.example.demo.ServiceClient           : Response received
2024-12-05T08:53:59.407+01:00  INFO [,67515c1779afeb3d47c600ee55d23b98,47c600ee55d23b98] 7306 --- [ctor-http-nio-3] [67515c1779afeb3d47c600ee55d23b98-47c600ee55d23b98] com.example.demo.ServiceClient           : Log from also block

I'm closing this as a duplicate of I think this is a duplicate of spring-projects/spring-framework#32165

If you believe this feature should be supported, please vote for Kotlin/kotlinx.coroutines#4187

@bclozel bclozel closed this as not planned Won't fix, can't repro, duplicate, stale Dec 5, 2024
@bclozel bclozel added status: duplicate A duplicate of another issue for: external-project For an external project and not something we can fix and removed status: waiting-for-triage An issue we've not yet triaged labels Dec 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: external-project For an external project and not something we can fix status: duplicate A duplicate of another issue
Projects
None yet
Development

No branches or pull requests

4 participants