Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Temporarily disable without re-initializing the client? #3112

Open
fiendish opened this issue May 30, 2024 · 5 comments
Open

Temporarily disable without re-initializing the client? #3112

fiendish opened this issue May 30, 2024 · 5 comments
Labels
Component: Transport Dealing with the transport Question

Comments

@fiendish
Copy link

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 fiendish added the Enhancement New feature or request label May 30, 2024
@szokeasaurusrex
Copy link
Member

@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!

@sl0thentr0py sl0thentr0py added Question Component: Transport Dealing with the transport and removed Enhancement New feature or request labels May 31, 2024
@getsantry
Copy link

getsantry bot commented Jun 25, 2024

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 🥀

@getsantry getsantry bot added the Stale label Jun 25, 2024
@fiendish
Copy link
Author

fiendish commented Jun 26, 2024

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.

@szokeasaurusrex
Copy link
Member

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

@fiendish
Copy link
Author

fiendish commented Jun 27, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Transport Dealing with the transport Question
Projects
Status: No status
Development

No branches or pull requests

4 participants