feat(server-utils): Emit low cardinality graphql span names - #23542
feat(server-utils): Emit low cardinality graphql span names#23542andreiborza wants to merge 7 commits into
Conversation
size-limit report 📦
|
With span streaming enabled, name graphql spans after the operation type or the graphql phase, and stop renaming the enclosing root span with the operation. Names are unchanged in static mode. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013bjBXkGkJo8eL8hkz48byi
….processing.type Follows the GraphQL OpenTelemetry Working Group, which added a dedicated attribute for the processing type rather than widening graphql.operation.type. Parse, validate and resolve spans take the static fallback name and carry the phase as an attribute instead. Claude-Session: https://claude.ai/code/session_013bjBXkGkJo8eL8hkz48byi
f11596c to
ca3bd08
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ca3bd08. Configure here.
Duplicating them is how the two paths drift, which is the opposite of what the mirroring was for. The `graphql:*` channel names stay local to the subscriber, since only it uses them. Claude-Session: https://claude.ai/code/session_013bjBXkGkJo8eL8hkz48byi
| attributes: { | ||
| [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, | ||
| [SEMANTIC_ATTRIBUTE_SENTRY_OP]: GRAPHQL, | ||
| [GRAPHQL_PROCESSING_TYPE]: PROCESSING_TYPE_EXECUTE, |
There was a problem hiding this comment.
Bug: The setupOperationChannel function hardcodes the graphql.processing.type attribute to 'execute', causing GraphQL subscription operations to be incorrectly tagged.
Severity: LOW
Suggested Fix
Modify setupOperationChannel to accept a processingType parameter. Pass 'execute' for execute channels and a new 'subscribe' value for subscribe channels. This will ensure subscription spans are correctly tagged with graphql.processing.type = 'subscribe'.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: packages/server-utils/src/integrations/graphql/graphql-dc-subscriber.ts#L217
Potential issue: The `setupOperationChannel` function is used for both GraphQL `execute`
and `subscribe` operations. However, it hardcodes the `GRAPHQL_PROCESSING_TYPE`
attribute to `PROCESSING_TYPE_EXECUTE` ('execute') for all operations it handles. As a
result, spans for GraphQL subscription operations are incorrectly tagged with
`graphql.processing.type = 'execute'`. This is a semantic error, as subscriptions are a
distinct operation type in GraphQL. This will mislead users who are filtering or
analyzing telemetry data, as they won't be able to distinguish subscription operations
from execute operations based on this attribute.
Did we get this right? 👍 / 👎 to inform future reviews.
| import { loggingTransport } from '@sentry-internal/node-integration-tests'; | ||
|
|
||
| Sentry.init({ | ||
| traceLifecycle: 'stream', |
There was a problem hiding this comment.
superduper-l: Theoretically we don't need to add this line as it is on by default
|
|
||
| return startInactiveSpan({ | ||
| name: | ||
| client && hasSpanStreamingEnabled(client) ? GRAPHQL_SPAN_NAME_FALLBACK : `${SPAN_NAME_RESOLVE} ${path.join('.')}`, |
There was a problem hiding this comment.
suuuper-l: You think this could be a helper function? Something like getSpanName(`${SPAN_NAME_RESOLVE} ${path.join('.')}`) could maybe safe some bytes as it is used 9 times.

What
With span streaming enabled, graphql spans are now named after the operation type (
GraphQL query), orGraphQL Operationwhere the SDK has no operation type, instead of after the client-supplied operation name or resolver field path.useOperationNameForRootSpanalso no longer renames the enclosing root span. Every graphql span now carriesgraphql.processing.type, which says whether it is a parse, validate, execute or resolve span.Why
Span names must be low cardinality when span streaming is enabled, and the operation name and field path both come from the client. A low-cardinality name cannot also say which part of request processing a span covers, so
graphql.processing.typecarries that instead, following the GraphQL OpenTelemetry Working Group proposal in open-telemetry/semantic-conventions#3515. Blocked on getsentry/sentry-conventions#572, which defines the attribute; the key is inlined until that ships.Closes: #23526