Support/document initializing SDK when a third-party library controls the asyncio event loop
Problem Statement
User reported via ZD ticket: Some frameworks (in this case LiveKit agents) create and manage their own asyncio event loop internally. Users can only access the async entrypoint after the loop is already set up by the framework. This prevents calling sentry_sdk.init(..., integrations=[AsyncioIntegration()]) early enough to capture errors in synchronous startup code or in the main process that runs before the loop is created. Current workarounds initialize Sentry without AsyncioIntegration, flush/close, and re-init inside the async entrypoint, but double init is unsupported and adds startup latency.
Solution Brainstorm
Provide a supported or document how users should handle this case.
thanks @kerenkhatiwada, this is a known limitation of our AsyncioIntegration. We need to think what we can do here but I'll backlog it for now.
thanks @kerenkhatiwada, this is a known limitation of our
AsyncioIntegration. We need to think what we can do here but I'll backlog it for now.
Thanks - I raised this issue through support.
Currently we do something along the lines of
def shutdown_sentry():
sentry_sdk.flush(timeout=5.0)
# Use the new Sentry 2.x API instead of deprecated Hub
client = sentry_sdk.get_client()
if client is not None:
client.close(timeout=3.0)
if __name__ == "__main__":
sentry_sdk.init(...)
# various sync code here of our own, and some sync code within livekit.start_worker()
livekit.start_worker() # calls entrypoint() within LiveKit framework, on a new process creating an asycio event loop
async def entrypoint():
shutdown_sentry()
sentry_sdk.init(integrations=AsyncioIntegration())
await start()
Which is problematic as it adds latency and "mess" into the entrypoint (which is when a voice agent starts operations).
Are you aware of any better workaround for time being?
Hey @bml1g12, as a workaround, instead of the shutdown/reinit, I'm thinking you could just call the patch_asyncio function directly. This is the actual function the AsyncioIntegration uses to set up tracing/error monitoring for asyncio tasks. So basically you'd do:
+ from sentry_sdk.integrations.asyncio import patch_asyncio
- def shutdown_sentry():
- sentry_sdk.flush(timeout=5.0)
- # Use the new Sentry 2.x API instead of deprecated Hub
- client = sentry_sdk.get_client()
- if client is not None:
- client.close(timeout=3.0)
if __name__ == "__main__":
sentry_sdk.init(...)
# various sync code here of our own, and some sync code within livekit.start_worker()
livekit.start_worker() # calls entrypoint() within LiveKit framework, on a new process creating an asycio event loop
async def entrypoint():
- shutdown_sentry()
- sentry_sdk.init(integrations=AsyncioIntegration())
+ patch_asyncio()
await start()
This way you'd avoid the overhead of setting up the whole SDK client machinery, but you should still get the event loop instrumented.