You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
When collecting a ChannelFlow, on which first map and then flowOn(span.asContextElement()) was called, after the the collect{} call completes, Context.current() still contains the span used earlier, while coroutineContext.getOpenTelemetryContext() returns an empty context.
Given that no direct calls to makeCurrent() or close() were made, this feels like a bug in the kotlin-extension.
Steps to reproduce
The following test fails:
importio.opentelemetry.api.GlobalOpenTelemetryimportio.opentelemetry.context.Contextimportio.opentelemetry.extension.kotlin.asContextElementimportio.opentelemetry.extension.kotlin.getOpenTelemetryContextimportkotlinx.coroutines.flow.channelFlowimportkotlinx.coroutines.flow.flowOnimportkotlinx.coroutines.flow.mapimportkotlinx.coroutines.test.runTestimportkotlin.test.Testimportkotlin.test.assertEqualsclassCollectChannelFlowSpanContextTest {
val tracer by lazy {
GlobalOpenTelemetry.getTracer("CollectChannelFlowSpanContextTest")
}
@Test
funcollectChannelFlowWithSpanDoesNotLeakContext() = runTest {
val constructedFlow = channelFlow<Nothing?> { }
val transformedFlow = constructedFlow.map { it } //.map prevents fusion of flowOn into channelFlowval flowExecutionSpan = tracer.spanBuilder("flowSpan").startSpan()
transformedFlow.flowOn(flowExecutionSpan.asContextElement()).collect { }
flowExecutionSpan.end()
assertEquals(coroutineContext.getOpenTelemetryContext(), Context.current())
}
}
Both .map { it } (or a similar flowOn-fusion-blocking operator) and channelFlow are required for this to occur. Removing the call to map or replacing the channelFlow with a normal flow both result in the test passing / the correct context being returned.
What did you expect to see?
I expected Context.current() to return the empty root context, just like coroutineContext.getOpenTelemetryContext().
What did you see instead?
The context returned by Context.current() was not empty: org.opentest4j.AssertionFailedError: expected: <{}> but was: <{opentelemetry-trace-span-key=PropagatedSpan{ImmutableSpanContext{traceId=00000000000000000000000000000000, spanId=0000000000000000, traceFlags=00, traceState=ArrayBasedTraceState{entries=[]}, remote=false, valid=false}}}>
What version and what artifacts are you using?
Artifacts: opentelemetry-api, opentelemetry-context, opentelemetry-extension-kotlin
Version: 1.48.0
How did you reference these artifacts?
Additional context
Original symptom of the bug was an incorrectly attached span.
After the Flow::collect call (which in my case was Flow::toSet() instead), the following span was attached to the span of the flow, not the "parent" span spanning the whole function.
The code that led to this was part of a custom kotlin http-request library, which I wanted to add first-party span-data to. I then simplified the code until I was left with the above test.
As part of a different project I am working on (kotlin multiplatform opentelemetry facade) I also have an additional kotlin implementation of the ContinuationInterceptor targeting JavaScript, which appears to not have this problem. I will see if I can share it tomorrow, although I have not checked if it passes your existing tests here.
The text was updated successfully, but these errors were encountered:
Describe the bug
When collecting a
ChannelFlow
, on which firstmap
and thenflowOn(span.asContextElement())
was called, after the thecollect{}
call completes,Context.current()
still contains the span used earlier, whilecoroutineContext.getOpenTelemetryContext()
returns an empty context.Given that no direct calls to
makeCurrent()
orclose()
were made, this feels like a bug in the kotlin-extension.Steps to reproduce
The following test fails:
Both
.map { it }
(or a similarflowOn
-fusion-blocking operator) andchannelFlow
are required for this to occur. Removing the call tomap
or replacing thechannelFlow
with a normalflow
both result in the test passing / the correct context being returned.What did you expect to see?
I expected
Context.current()
to return the empty root context, just likecoroutineContext.getOpenTelemetryContext()
.What did you see instead?
The context returned by
Context.current()
was not empty:org.opentest4j.AssertionFailedError: expected: <{}> but was: <{opentelemetry-trace-span-key=PropagatedSpan{ImmutableSpanContext{traceId=00000000000000000000000000000000, spanId=0000000000000000, traceFlags=00, traceState=ArrayBasedTraceState{entries=[]}, remote=false, valid=false}}}>
What version and what artifacts are you using?
Artifacts:
opentelemetry-api
,opentelemetry-context
,opentelemetry-extension-kotlin
Version:
1.48.0
How did you reference these artifacts?
Environment
Java-Compiler: Oracle OpenJDK 17 (javac)
Kotlin-Compiler: 2.1.10, K2
OS: Windows10
Gradle: 8.10
IDE: IntelliJ IDEA 2024.3.4.1 (Ultimate Edition)
Additional context
Original symptom of the bug was an incorrectly attached span.
After the
Flow::collect
call (which in my case wasFlow::toSet()
instead), the following span was attached to the span of the flow, not the "parent" span spanning the whole function.The code that led to this was part of a custom kotlin http-request library, which I wanted to add first-party span-data to. I then simplified the code until I was left with the above test.
As part of a different project I am working on (kotlin multiplatform opentelemetry facade) I also have an additional kotlin implementation of the ContinuationInterceptor targeting JavaScript, which appears to not have this problem. I will see if I can share it tomorrow, although I have not checked if it passes your existing tests here.
The text was updated successfully, but these errors were encountered: