question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

asyncio.gather tracing produces nested spans

See original GitHub issue

I’ve got the following code:

import asyncio
import sentry_sdk

async def foo():
    with sentry_sdk.start_span(op="foo"):
        await asyncio.sleep(1)

async def bar():
    with sentry_sdk.start_span(op="bar"):
        await asyncio.sleep(1)

with sentry_sdk.start_span(op="root"):
    await asyncio.gather(foo(), bar(), return_exceptions=True)

I see that bar is nested under foo, and foo is nested under root in the Performance UI.

root
    |- foo
         |- bar

Expected behavior: both foo and bar are nested under root and are on the same level.

root
    |- foo
    |- bar

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
untitakercommented, Jul 31, 2020

yes, our asyncio support is somewhat limited at the moment. As a workaround you can do:

import asyncio
import sentry_sdk

async def foo():
    with sentry_sdk.Hub(sentry_sdk.Hub.current):
        with sentry_sdk.start_span(op="foo"):
            await asyncio.sleep(1)

async def bar():
    with sentry_sdk.Hub(sentry_sdk.Hub.current):
        with sentry_sdk.start_span(op="bar"):
            await asyncio.sleep(1)

with sentry_sdk.start_span(op="root"):
    await asyncio.gather(asyncio.create_task(foo()), asyncio.create_task(bar()), return_exceptions=True)

I am not sure if create_task is strictly necessary or if gather does that for you. If gather already creates independent tasks then we can potentially handle this case transparently.

0reactions
antonpirkercommented, Oct 10, 2022

I have now created a reproduction repo: https://github.com/getsentry/minimum_python_async/blob/main/task1.py

And I created a new AsyncioIntegration that produces now this output: Image

Which is the output we want to have 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Using nested asyncio.gather() inside another asyncio.gather()
So performance wise if I run all tasks in the master_method or if I run them with this nested structure they should be...
Read more >
Issue 22239: asyncio: nested event loop - Python tracker
My approach makes this possible where it has previously not been possible at all, so I think this represents a big improvement to...
Read more >
Manual Instrumentation | OpenTelemetry
When you view spans in a trace visualization tool, child will be tracked as a nested span under parent . Creating spans with...
Read more >
Tracing creating nested spans - help
I'm using tracing and async_std to iterate over a Stream: messages .for_each(|delivery| { async_std::task::spawn(async { let span = span!(
Read more >
Class TraceSpan (1.7.2) | Python client library | Google Cloud
A span represents a single timed event within a trace. Spans can be nested and form a trace tree. Often, a trace contains...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found