[
https://issues.apache.org/jira/browse/CAMEL-23283?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18072426#comment-18072426
]
Bjorn Beskow commented on CAMEL-23283:
--------------------------------------
Same argument for nesting spans: Given the following minimalistic route:
{{from("jms:queue:test")}}
{{ .process(exchange ->}}
{{{} Observation{}}}{{{}.createNotStarted("jms-transformer",
observationRegistry){}}}
{{ .observe(() -> log.info("Transformed message from jms queue"))}}
{{ );}}
This route uses the Observation API (via an injected observationRegistry) to
programmatically create a child span, which to my understanding is the
idiomatic way to create a nested span with Micrometer. Hence the route will
create two spans: one span for the "jms:queue:test" message consumption, and
one span "jms-transformer" created programmatically.
If this route is triggered by a JMS message with a traceparent header (i.e. a
propagated context from the caller), the two spans are created with the correct
structure: they both have the common traceId provided in the traceparent header.
But if the route is triggered by a JMS message *without* a traceparent header
(i.e. a new traceId is created by camel-micrometer-observability), the
structure becomes incorrect: the first span for the message consumption has the
newly created traceId, but the programmatically second span gets yet another,
newly created and unique traceId.
To my understanding, that is wrong. I cannot understand why
camel-micrometer-observability should behave differently in those two cases?
> OpenTelemetry/Micrometer traces are not correctly structured for
> JMS-initiated routes
> -------------------------------------------------------------------------------------
>
> Key: CAMEL-23283
> URL: https://issues.apache.org/jira/browse/CAMEL-23283
> Project: Camel
> Issue Type: Task
> Components: camel-tracing
> Affects Versions: 4.15.0, 4.16.0, 4.17.0, 4.18.0, 4.18.1
> Reporter: Bjorn Beskow
> Priority: Minor
> Attachments: jms-micrometer-observability.zip
>
>
> When using camel-micrometer-observability, traces and spans are not correctly
> structured if a traceId and root span is not already present (as a result of
> OTEL context propagation from the caller, or by a Spring Boot framework
> component in front of the camel component).
> The effect is twofold:
> * traceId and spanId is not put in the MDC context, and hence not present in
> any logs created.
> * Nested spans created programmatically using the Micrometer Observation API
> are not properly nested (they get their own, unique traceId's).
> The attached sample project pinpoints the problem: For an exchange with a
> "traceparent" propagated from the caller, everything works as expected. For
> an exchange without a propagated existing trace, the tests show that the MDC
> is not properly populated and any nested spans have the wrong structure.
> This seems to be caused by missing scope management:
> MicrometerObservabilitySpanAdapter::activate() only calls span.start() but
> doesn't put the
> span into the tracer's thread-local scope. This means tracer.currentSpan()
> returns null during route execution, hence the span is invisible to e.g.
> programmatic child span creation that relies on tracer.currentSpan() to find
> a parent span (for example via the ObservationRegistry). It also becomes
> invisible for the MDC context.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)