sentry-python icon indicating copy to clipboard operation
sentry-python copied to clipboard

`set_tags` missing from python SDK

Open bityob opened this issue 3 years ago • 5 comments

According to unified-api page, each SDK should have a set_tags method.

https://develop.sentry.dev/sdk/unified-api/

image

I found it was dicscussed and implemented 2 years ago in this PR #530 but the PR was closed.

Can this feature be added?

Thanks

bityob avatar Feb 16 '22 14:02 bityob

thx for the issue @bityob, we know we have to generally clean up the tags/context/user API a bit. We'll try to fit this at some point. See also #933.

sl0thentr0py avatar Feb 16 '22 14:02 sl0thentr0py

@sl0thentr0py is there any update? :)

We are currently thinking how to extend our contextual logging (works in similar fashion as scope stacking in Sentry), but we can't use push_scope cause it's not automatically reporting errors.

So we ended up with using configure_scopeand following

  • capturing scope tags on __enter__
  • setting up specific tags overrides for actual functionality in the context
  • if anything raises exception in the context manager it will have the new tags
  • re-hydrating the captured scope tags on __exit__ to get it to previous state

We are having a pretty much nested context managers and works pretty well, but there is a downside of using private scope attribute _tags given there is not getter.

Would it be okay for you guys to add set_tags and along with that get_tags to Scope? If yes, i can make that change pretty fast. :) ⏩ :shipit:

Thanks

VojtechBartos avatar Apr 08 '22 10:04 VojtechBartos

@sl0thentr0py is there any update? :)

We are currently thinking how to extend our contextual logging (works in similar fashion as scope stacking in Sentry), but we can't use push_scope cause it's not automatically reporting errors.

So we ended up with using configure_scopeand following

  • capturing scope tags on __enter__
  • setting up specific tags overrides for actual functionality in the context
  • if anything raises exception in the context manager it will have the new tags
  • re-hydrating the captured scope tags on __exit__ to get it to previous state

We are having a pretty much nested context managers and works pretty well, but there is a downside of using private scope attribute _tags given there is not getter.

Would it be okay for you guys to add set_tags and along with that get_tags to Scope? If yes, i can make that change pretty fast. :) fast_forward :shipit:

Thanks

Can you share your context manager?

Will be helpful maybe for us too

bityob avatar Aug 16 '22 19:08 bityob

Ok, I came up with this context manager to handle sentry tags -

@contextmanager
def sentry_tags_session(logger=None, **tags):
    with sentry_sdk.configure_scope() as scope:
        try:
            curr_tags = scope._tags.copy()
            for k, v in tags.items():
                scope.set_tag(k, v)
            yield
        except:
            if logger:
                # Log here to have the exception attached with the tags too
                logger.exception("Failed inside sentry_tags_session context")
            raise
        finally:
            # Must clear explicitly the scope, because it's not handled by sentry_sdk,
            # and need also to restore the previous sentry tags because calling `clear()` remove all tags...
            scope.clear()
            for k, v in curr_tags.items():
                scope.set_tag(k, v)

bityob avatar Aug 16 '22 20:08 bityob

@bityob we have something similar :)

@contextmanager
def create_logging_ctx(context: LoggingContext) -> Generator[None, None, None]:
    # NOTE(vojta) unfortunately we can't use Sentry push_scope given the fact it
    # wont automatically capture any excentions happening inside the push_scope context
    # manager and you have to do it manually. For there reason we have ended up with
    # using configure_scope, which actually tweaks the root scope, but with leaving
    # context manager keep the values. To make it work, we are capturing the actual tags
    # on entering and re-hydrating them on exiting the context manager
    with sentry_sdk.configure_scope() as scope:
        # there is no official API how to get all the scope tags se we have to use
        # private attribute and in meantime we have asked about potentially extending
        # the API
        # https://github.com/getsentry/sentry-python/issues/1344#issuecomment-1092700348
        captured_tags = dict(scope._tags)

        _LOGGING_CONTEXTS.append(context)

        # setting up the sentry tags to be able to see the information on the issues and
        # be able to search by them. Context not suitable for this purpose
        # https://docs.sentry.io/platforms/python/enriching-events/tags/
        for tag_name, tag_value in context.tags.items():
            scope.set_tag(tag_name, tag_value)

        # in case that wrapped funcionality inside by the logging context trigger any
        # exception we need to make sure we always do clean up aka remove Sentry scopes
        # and logging context
        try:
            yield
        finally:
            # re-hydrating the captured tags only for the keys which has been set from
            # the logging context
            for tag_name in context.tags.keys():
                value = captured_tags.get(tag_name)
                if value is None:
                    # value set from logging context, but not in the original captured logs
                    # so instead of rewriting, just removing
                    scope.remove_tag(tag_name)
                    continue
                scope.set_tag(tag_name, value)

            _LOGGING_CONTEXTS.pop()

VojtechBartos avatar Aug 17 '22 07:08 VojtechBartos