Skip to content

Conversation

@srikanthccv
Copy link
Member

Description

The path value of the ASGI scope is a non-generalized path. This is not an issue in other frameworks such as fastapi or falsk where the templatized path is accessible. This PR updates the span name to not contain the high cardinal value for ASGI instrumentation span names. The highly cardinal span names will become a problem when used with the span metrics connection from the collector.

The spec guidelines say https://opentelemetry.io/docs/specs/otel/trace/api/#span

The span name concisely identifies the work represented by the Span, for example, an RPC method name, a function name, or the name of a subtask or stage within a larger computation. The span name SHOULD be the most general string that identifies a (statistically) interesting class of Spans, rather than individual Span instances while still being human-readable. That is, “get_user” is a reasonable name, while “get_user/314159”, where “314159” is a user ID, is not a good name due to its high cardinality. Generality SHOULD be prioritized over human-readability.

@srikanthccv srikanthccv requested a review from a team as a code owner March 9, 2025 03:36

def get_default_span_details(scope: dict) -> Tuple[str, dict]:
"""
Default span name is the HTTP method and URL path, or just the method.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we update the comment and also reference the one you mentioned in the PR description?

([#3882](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3882))
- `opentelemetry-instrumentation-aiohttp-server`: delay initialization of tracer, meter and excluded urls to instrumentation for testability
([#3836](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3836))
- `opentelemetry-instrumentation-asgi` remove high cardinal path from span name
Copy link
Member

@emdneto emdneto Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

plus remove the protocol type from the span name if http?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to see you @srikanthccv 👋

Is the span name being modified here supposed to follow the OTel HTTP server semconv or is it a more internal span? This change would be a breakage for anyone relying on this particular name, but if it's not the main {method} {target} span it may be OK.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the span name being modified here supposed to follow the OTel HTTP server semconv or is it a more internal span?

Correct, specifically this part of the spec: If there is no (low-cardinality) {target} available, HTTP span names SHOULD be {method}. The path value of the ASGI scope for both HTTP and WebSocket contains the non-templatized path. The change in this PR removes the path as the target and just sets the method as recommended.

Some examples image

This change would be a breakage for anyone relying on this particular name

Agreed, but at the same time, it doesn't follow the semantic convention and spec guidelines for span names. I would say it's a necessary breaking change. Even from the end-user perspective, I believe this is a useful change; otherwise, IDs (from messaging-adjacent apps, in my experience) become part of the name, leading to no meaningful aggregation for server spans. In many deployments, the spanmetrics connector is used to derive metrics from these spans, which creates a problem.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, but at the same time, it doesn't follow the semantic convention and spec guidelines for span names. I would say it's a necessary breaking change. Even from the end-user perspective, I believe this is a useful change

Ya I agree, maybe we can just gate this behind the new semconv stability opt in like we do here?

attributes = collect_request_attributes(
scope, self._sem_conv_opt_in_mode
)

How hard would that be to do?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me take a look at it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went through the code. It should be possible to keep the old and new name following the opt in mode. Let me know if we should make it opt-in.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi! 👋

There is a similar PR open for the aiohttp server instrumentation that will also introduce a breaking change to span name in order to follow semconv and reduce cardinality: #3896 (comment) . @aabmass should that PR also include an opt-in? cc @krnr

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO it would be better since the purpose of the opt-in was to prevent breaking people

Any objections to that though? Does it work for you @srikanthccv ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, but at the same time, it doesn't follow the semantic convention and spec guidelines for span names. I would say it's a necessary breaking change. Even from the end-user perspective, I believe this is a useful change

Ya I agree, maybe we can just gate this behind the new semconv stability opt in like we do here?

attributes = collect_request_attributes(
scope, self._sem_conv_opt_in_mode
)

How hard would that be to do?

expected_old = [
{
"name": "GET / http receive",
"name": "GET receive",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't have a ton of context on these tests, but this still doesn't seem to be following the HTTP semconv. What is receive here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are the internal spans created in the receive and send callable of the ASGI application https://asgi.readthedocs.io/en/latest/specs/main.html#applications. The name will be {method} receive or {method} send depending on the event. Does that clarify?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah so these are in addition to the standard HTTP semconv, generally showing as child spans? SGTM

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah so these are in addition to the standard HTTP semconv, generally showing as child spans?

Yes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Ready for review

Development

Successfully merging this pull request may close these issues.

5 participants