I want to use OpenTelemetry with an Async application, and I want to be 101% sure that it will work as intended. Specifically, I'm worried about what happens with the current_span
when we switch back and forth between asynchronous functions. I have this fear that if I rely on tracer.start_as_current_span
to set the span in each function, and then I pass execution to another function which also sets the current_span
, then when execution passes back to the first function it won't be tied to the correct span anymore.
Now, I have tried testing this a bit, and found no evidence that it breaks. But I also haven't found any documentation that says it explicitly won't break. Can anyone confirm?
I've done the following basic test, but I'm worried it misses something:
async def async_span():
with tracer.start_as_current_span(name=f"span_{uuid.uuid4}") as span:
for x in range(1000):
assert trace.get_current_span() == span
await asyncio.sleep(0.0001 * randint(1, 10))
async def main():
with tracer.start_as_current_span(name="parent"):
await asyncio.gather(*(async_span() for _ in range(10)))
OpenTelemetry for Python supports asynchronous code.
Went through the code for version 1.24.0/0.45b0 of opentelemetry-python
. The code contains abstract context class _RuntimeContext
. _RuntimeContext
has single implementation ContextVarsRuntimeContext
that utilizes contextvars
. ContextVarsRuntimeContext
is used as a default context.