Temporarily disable without re-initializing the client?
Problem Statement
It would be nice to have a documented simple mechanism other than reinitializing the client for disabling its transmissions.
The scenario is that I need to disable it only briefly and then reenable it again right after, but I don't have access to all of the original values that were given as part of the initial client configuration.
Solution Brainstorm
Peeking inside at the current client's contained options seems...wrong? Though if you tell me that it's fine to do so then I'll be ok with that answer too.
@fiendish Here's an idea for you: you can replace the client's transport, which is responsible for sending events to Sentry, with a no-op transport while you wish for sending to be disabled, then replace the transport with the original value afterwards. Perhaps, something like the following would work for you:
import contextlib, sentry_sdk
from sentry_sdk.transport import Transport
class NoOpTransport(Transport):
def capture_envelope(
self, _ # type: Envelope
):
# type: (...) -> None
pass
@contextlib.contextmanager
def sentry_sending_disabled():
client = sentry_sdk.get_client()
old_transport = client.transport
client.transport = NoOpTransport()
try:
yield
finally:
client.transport = old_transport
# Code block where you wish to disable Sentry sending:
with sentry_sending_disabled():
... # nothing that happens here will get sent to Sentry
Please note, I have not tested this snippet yet, so please make sure to test it before you use it 🙂
Let me know whether this works for you!
This issue has gone three weeks without activity. In another week, I will close it.
But! If you comment or otherwise update it, I will reset the clock, and if you remove the label Waiting for: Community, I will leave it alone ... forever!
"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀
Thank you @szokeasaurusrex!
I'm now using a variant of your suggestion (capture_event too for old-sentry-version compat)
class NoOpTransport(sentry_sdk.transport.Transport):
capture_envelope = capture_event = lambda self, _: None # type: ignore
with patch.object(sentry_sdk.Hub.current.client, "transport", NoOpTransport()):
...
and it appears to be working. I feel vaguely uneasy about reaching into Hub.current.client instead of using get_client(), so I may belt-and-suspenders do both in case the internal Hub interface changes in the future.
Glad to hear that this solution is working for you!
Just one clarification: what Sentry SDK version are you running? 1.x or 2.x? The Hub API is deprecated in 2.x, and so if you are using some 2.x version, you should be using sentry_sdk.get_client() to get the client instead or accessing it through the Hub.
Also, I would strongly advise against using unittest.mock.patch.object to modify the client. patch.object is only meant to be used inside test code, not in production. Instead, you should use something like the context manager I provided in my comment above, which I have also repeated below for your convenience:
@contextlib.contextmanager
def sentry_sending_disabled():
# If you are on Sentry SDK 1.x, you can use sentry_sdk.Hub.current.client below, instead
client = sentry_sdk.get_client()
old_transport = client.transport
client.transport = NoOpTransport()
try:
yield
finally:
client.transport = old_transport
# Code block where you wish to disable Sentry sending:
with sentry_sending_disabled():
... # nothing that happens here will get sent to Sentry
Just one clarification: what Sentry SDK version are you running? 1.x
1.x still for now. Deprecating patterns is probably good for sentry's future, but I'll personally still need library interop across old sentry versions so won't get rid of trying to access Hub entirely. I'll just be putting it behind a try or something.
patch.object is only meant to be used inside test code
Heh. No worries. Though, I will note that "only meant to be" and "only able to be" are non-identical sets. In practice it actually works fine in a production prototype. But I appreciate your suggestions still and will likely steer toward something more like it in a future version.