Skip to content
New issue

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

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

Already on GitHub? # to your account

Custom transactions being overwritten by ASGI integration #3663

Closed
ripperdoc opened this issue Oct 16, 2024 · 4 comments · Fixed by #3664
Closed

Custom transactions being overwritten by ASGI integration #3663

ripperdoc opened this issue Oct 16, 2024 · 4 comments · Fixed by #3664

Comments

@ripperdoc
Copy link

How do you use Sentry?

Sentry Saas (sentry.io)

Version

2.16.0

Steps to Reproduce

I'm working on some custom instrumentation. I have some code that creates a manual transaction, like this:

scope = sentry_sdk.get_current_scope()
transaction = scope.start_transaction(
    name="ttr"
    op="function",
    start_timestamp=<timestamp>,
)
scope.span = transaction

Sentry is setup like this and uses FastAPI automatic instrumentation.

    sentry_sdk.init(
        dsn=dsn,
        debug=True,
        sample_rate=or_default(default_config.sentry_error_sample_rate, 1.0),
        enable_tracing=True,
        traces_sample_rate=tracing_rate,
        environment=os.getenv("SENTRY_ENVIRONMENT"),
        release=version,
    )

Expected Result

In Sentry.io I keep seeing a different transaction called /sessions/{session_id} which corresponds to a websocket endpoint we have, instead of seeing ttr.

Actual Result

I debugged this and tracked it down to this code in asgi.py

def event_processor(self, event, hint, asgi_scope):
        # type: (Event, Hint, Any) -> Optional[Event]
        request_data = event.get("request", {})
        request_data.update(_get_request_data(asgi_scope))
        event["request"] = deepcopy(request_data)

        # Only set transaction name if not already set by Starlette or FastAPI (or other frameworks)
        already_set = event["transaction"] != _DEFAULT_TRANSACTION_NAME and event[
            "transaction_info"
        ].get("source") in [
            TRANSACTION_SOURCE_COMPONENT,
            TRANSACTION_SOURCE_ROUTE,
        ]
        if not already_set:
            name, source = self._get_transaction_name_and_source(
                self.transaction_style, asgi_scope
            )
            event["transaction"] = name
            event["transaction_info"] = {"source": source}

            logger.debug(
                "[ASGI] Set transaction name and source in event_processor: '%s' / '%s'",
                event["transaction"],
                event["transaction_info"]["source"],
            )

        return event

The incoming ttr transaction has event["transaction_info"]["source"] = "custom" which means already_set = False as it's not considered a valid source here and thereby the transaction name is overwritten.

I would expect that my custom transaction is not modified.

(on a separate note, the docs don't mention that I need to set my transaction on the current scope manually, I first thought it would happen when I call start_transaction on the scope)

@sl0thentr0py
Copy link
Member

right that's a bug, thanks for the report, will fix!

@sl0thentr0py
Copy link
Member

sl0thentr0py commented Oct 16, 2024

also as a side note, unless you really need to start a transaction, if there's already a transaction started by sentry's asgi integration, you can simply do the following in your request handler function:

sentry_sdk.get_current_scope().set_transaction_name("my_custom_transaction", source=TRANSACTION_SOURCE_CUSTOM)

to override the transaction name.

@ripperdoc
Copy link
Author

ripperdoc commented Oct 16, 2024

also as a side note, unless you really need to start a transaction, if there's already a transaction started by sentry's asgi integration, you can simply do the following in your request handler function:

sentry_sdk.get_current_scope().set_transaction_name("my_custom_transaction", source=TRANSACTION_SOURCE_CUSTOM)
to override the transaction name.

Ok, thanks a lot! So on that topic, I have a related question. We have an open websocket that receives a lot of messages per second. Every time a message is received, Sentry seems to go through at least parts of the motions of creating a transaction. This seems wasteful, and also has the effect that it will override any manually created transaction set on the same scope, as in my code. I feel like the best would be to stop websocket from being instrumented automatically, but I don't see any configuration exposed for doing that on the ASGI or Starlette integrations, or?

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 Oct 16, 2024
@sl0thentr0py
Copy link
Member

sl0thentr0py commented Oct 16, 2024

No, that's currently not configurable sadly.

The way to stop some transactions being created would be with a traces_sampler function
https://docs.sentry.io/platforms/python/configuration/sampling/#setting-a-sampling-function

so

def traces_sampler(sampling_context):
    if sampling_context["asgi_scope"]["type"] == "websocket":
         return 0.0
    return 1.0

sentry_sdk.init(
    # ...
    traces_sampler=traces_sampler,
)

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants