-
Notifications
You must be signed in to change notification settings - Fork 40.8k
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
Spring Boot 3 Webflux project missing traceId and spanId in logs #33372
Comments
This is the expected behavior. See spring-projects/spring-framework#29466 I'm keeping this opened for now as we need to find the best place to document this. |
Interesting, we are switching from Spring Cloud Sleuth to Micrometer and with SCS this all worked just like it did in a MVC app. Was that sheer luck? I am trying to understand the answers spring-projects/spring-framework#29466, does it mean we have to wrap each time we want pass the traceId and spanId to the logs? |
I was also surprised when upgraded and didn't see the traceId/spanId in the logs anymore. It'd be really helpful to document the change of behaviour and how to make it work in webflux applications. |
I guess we are expected to open the scope using the observation located in the context, aren't we? This allowed the creation of the traceId/spanId. However the WebClient doesn't seem to be propagating the correlation headers. Could you point at how we can achieve that? I think Sleuth automatically instrumented the WebClient, is there an equivalent with Micrometer Tracing or we should implement it by ourselves?
Notice the |
For now yes, you can read more about it here https://micrometer.io/docs/observation#instrumentation_of_reactive_libraries |
@marcingrzejszczak thanks for the clarification, I'll go over the references you provided. |
I've updated the sample, now it looks like this:
The
I can see the generated traceId/spanId in the
What am I missing? |
@codependent You should inject the auto-configured |
@wilkinsona How strange, I updated it to use the The sample project I'm using is available here in case you can have a look a it: https://github.com/codependent/demotracing
|
I had a look at the Webflux sample and adapted the code:
Now I can see that the log correlation almost works as expected:
If you look at the last line of the log, that correspondes to the Modifying the code to include another nested
It seems the change from Sleuth to Micrometer Tracing is going to need quite a lot of work on our codebases. Can you confirm this is the proper usage? BTW, thanks for your answers. |
For now, if you want to have the loggers have correlated MDC context, then yes, it will require some work. Because you could instead of doing I'm in touch with @OlegDokuka and the reactor team to work on something more automated that would resemble how Sleuth worked but would be more performant and less buggy. But that will take some time. |
Great to know! One last thing, it'd be good to document how to proceed with Kotlin coroutines as well. This approach doesn't look quite idiomatic, is there a better (more idiomatic) way to do the MDC setup in this case?
|
Hmm theoretically if you have |
@marcingrzejszczak
Unfortunately MDC doesn't seem to be set and traceId is null:
|
I'm not an expert with kotlin - can you debug that the kotlin classes in micrometer do actually get called? |
What I've seen so far is:
When
Here the Unlike the Reactive sample, with coroutines
|
@codependent I'm also interested in getting this to work in a webflux+coroutine environment and I think I know why you sample code doesn't work. As far as I've understood, the As we are in the "reactor" world here, we need to have a way of building this context element from the reactor context instead. I managed to get it to work by using the following snippet on filter (I'm using functional endpoints):
I've quickly tested this and it seems to be working fine, I'm able to log with all MDC fields, including trace and span id. Anyway, I think there could be a simpler way to achieve this, as this is verbose and also feels that is doing more steps than needed:
I'm deducting this based on my understanding of coroutines and reactor contexts, I don't understand much what happens behind the scenes on the tracing part, so be aware that I could be assuming wrong things here. It would be nice to have a better way to achieve here. Maybe an extension that could build the context element directly from the reactor context? Would it be also nice it we could manage to get the traceId/spanId and any other baggage fields from the reactor context directly, instead of having to having to inject a tracer and doing these workarounds (on spring sleuth, it was possible to set and extract baggage values purely on the reactor context, here I couldn't find a direct way). |
@rp199 you nailed it! I agree with you, things were quite easier with Sleuth, where all the instrumentation was completely transparent from our code. This new approach feels kind of invasive but I guess there must be good reasons (performance, bugs...) for it. As you mentioned it'd be nice to have a simpler way to deal with the obvervations and context propagation. |
Hello to all. I have created the following helper (still hacky code, will improve it later)
This works and I am seeing Also using the io.micrometer.context-propagation the |
@rp199 you mentioned that you applied it using a filter, I guess you meant a I was wondering if there could be a way to move up that configuration to a traditional
I'm scraching my head to see if I can come up with a way to configure the appropriate context without having to modify lots of places in a huge codebase. @akoufa That's a nice workaround, the only downside is that we would need to wrap quite a few methods, for different log levels and number of arguments:
Besides, when having multiple calls...
... each one of them sets up the current Observation into the context. I wonder if it might be less performant that setting it up only once per request using |
@codependent Yes unfortunately my solution has a downside to adapt every log statement or at least the important ones like debug, error needed for log correlation when debugging. But I did not found any other less invasive solution yet. I think you just need to add |
You don't need to use |
Still not able to see the traceid and spanid propagate to calls inside methods like .doOnError() or .onErrorResume(). Were those cases be handled as well? @marcingrzejszczak |
@VinishKumar1 this part will be covered with #34201 |
@bclozel When I define the depedencies listed above, I get the following in the logs
Is this expected ? Aren't Coroutines supported yet ? |
I thought that we are supporting Coroutines - https://github.com/micrometer-metrics/micrometer/blob/v1.10.4/micrometer-core/src/main/kotlin/io/micrometer/core/instrument/kotlin/AsContextElement.kt |
@marcingrzejszczak Yes using the manual approach e.g. creating a coroutine wrapper around
|
@bclozel @marcingrzejszczak I have created a sample project: https://github.com/akoufa/springbootissues In this project I see wrong trace id and span id log statements inside |
@marcingrzejszczak using new versions, the behavior of the traceId and SpanId would be the same as Sleuth had? I tried using those but it is still not propagating the traceId and spanId to the other threads. 11:27:45->[XNIO-1 task-2] [INFO] - [63f8c961d374727e2acbbd4585e64428, 3ef262641c3e01ce] - log entry 1 |
After checking with several samples, #34201 will indeed fix the problem initially reported. I'm closing this issue as superseded. We don't expect this issue to cover all possible behavior differences with Sleuth, so others should have dedicated issues. @fernandofraga109 please create a new issue with a sample application demonstrating the behavior. It's hard to know without a concrete application where the problem is. It's very likely not in Spring Boot, but probably more in Spring Framework, Reactor Netty or Micrometer directly. We can start with an issue in Spring Framework. Thanks! |
I have the same problem like you @fernandofraga109. |
Hi @silverwind85, Kafka and Rabbit (messaging frameworks) Reactive programming I hope that helps you. |
I reproduced case my issue https://github.com/silverwind85/TraceIdExample |
@silverwind85 I had the same problem. Lately I was able to get traceIds back in logs with spring-boot-starter version 3.0.5 without using the fix to set @EnableReactiveMethodSecurity(useAuthorizationManager = false) What I had to do:
@Configuration
class ObservationConfig(
private val observationHandlers: Set<ObservationHandler<*>>
) {
@Bean
fun observationRegistry(tracer: Tracer): ObservationRegistry {
val observationRegistry = ObservationRegistry.create()
val observationConfig = observationRegistry.observationConfig()
observationHandlers.forEach(observationConfig::observationHandler)
return observationRegistry
}
} I found that as I debugged and saw that somehow the observationHandlers were not registered for the ObservationRegistry, thus making it return I found that within io.micrometer.observation.SimpleObservationRegistry.isNoop() |
I added this bean but it didn't help |
@silverwind85 sadly I wasn't able to create a pull-request for your repository but I was able to make it work when:
val traceId = tracer.currentSpan()?.context()?.traceId()
@RestControllerAdvice
open class ErrorController(
private val tracer: Tracer
) {
@ExceptionHandler(Throwable::class)
open fun handleAny(
ex: Throwable,
): ResponseEntity<String> {
val traceId = tracer.currentSpan()?.context()?.traceId()
println("${ErrorController::class.simpleName}: TrackingId: $traceId")
return ResponseEntity.ok(
"whoops"
)
}
} outcome:
|
@lukasT Thanks for you help but I need use GlobalErrorAttributes extend DefaultErrorAttributes. Too many changes in the application. From my perspective, this should be corrected. I'm wonderd other people don't have this problem |
This's way too complicated after Sleuth, still no solution to propagate same traceID between microservices ? P.s. I'm having same issue with Java spring and graphql client |
Total noob question here, but from what I could see, even though I use I plan to upgrade the SpringBoot in some applications, and I have a custom library that implements Sleuth, creates/reads spans, and sets in a ThreadLocalSpan (it works for MVC and Webflux projects once Sleuth automatically correlates the observations). By using Micrometer, from what I could see, this method wouldn't work until enabling |
I can confirm that 3.0.7 RELEASE have fixed the main problem for me, still initial request have wrong traceIDs, probably another issue but after that every request have same traceID in between microservices. |
@gabrielfmagalhaes if you require assistance for instrumenting your library, please reach out to the micrometer community on the Slack channel so we can help you. @rsercano if there is a bug with graphql instrumentation, please share a sample application demonstrating the problem and create a new issue in the spring graphql project. To anyone here: this issue is closed and is not meant to address any issue related to observability and Spring. Adding more comments about somewhat related problems is not helping. The issue title might be too broad in the first place. |
Even with |
@silverwind85 I am encountering a similar issue and also need to use |
@roja-polukonda I don't understand the link between |
@bclozel In our application, we use |
When upgrading to Spring Boot 3 (and Micrometer) I noticed the traceId and spanId are not added to the logs when it's a Webflux project.
Webflux: https://github.com/sanderino666/webflux-micrometer-logs
2022-11-26T17:27:44.991+01:00 INFO [,,] 19376 --- [ctor-http-nio-3] com.example.demo.DemoApplication : home() has been called
MVC: https://github.com/sanderino666/mvc-micrometer-logs
2022-11-26T17:24:12.050+01:00 INFO [,63823dabe8475ad8d31ec1fc81853dcc,d31ec1fc81853dcc] 1848 --- [nio-8080-exec-1] com.example.demomvc.DemoMvcApplication : home() has been called
The text was updated successfully, but these errors were encountered: