Clean up span operations #22446

Description

@Lms24

Description

Currently, many of our instrumentations send span ops that are not defined in conventions. This has two reasons:

  1. The span op is simply still missing in conventions and needs to be added
  2. SDKs sent suboptimal, maybe, too fragmented ops. For example, ops that include the framework or library name (e.g. middleware.express or function.sveltekit). Ops should be a bit more general than that.

I (okay, mostly my clanker, followed by a manual review) audited our instrumentations and these are the places we should make changes to:

Add to conventions

EffortPriorityCategoryCurrent op(s)Replacement or conventions actionRegistry statusRationale / other findingsPreserve detail inProduction locations
XSHighRoutingrouterAdd generic router to conventionsMissingThis is the common framework-neutral replacement target for frontend and backend router spans. Router work is distinct from both navigation roots and generic middleware.ui.framework; navigation.phase; code.namespace or framework; router.name; route attributespackages/angular/src/tracing.ts
packages/sveltekit/src/client/svelte4BrowserTracing.ts
packages/sveltekit/src/client/svelte5BrowserTracing.ts
packages/ember/addon/utils/instrumentEmberAppInstanceForPerformance.ts
packages/core/src/integrations/express/patch-layer.ts
packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
packages/server-utils/src/integrations/tracing-channel/koa.ts
packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
XSHighUIui.interaction.click|hover|drag|pressKeep ui.interaction.* and add all four leaves to conventionsMissingEvent Timing and INP interaction spans remain distinct from ui.action roots. Register click, hover, drag, and press as the finite interaction taxonomy.Keep DOM event type and INP metric identity as attributespackages/browser-utils/src/metrics/browserMetrics.ts
packages/browser-utils/src/metrics/inp.ts
packages/browser-utils/src/metrics/webVitalSpans.ts
packages/browser/src/tracing/browserTracingIntegration.ts
XSHighUIui.long-task / ui.long-animation-frameKeep both operations and add them to conventionsMissing; ui.task is not equivalentLong Task and Long Animation Frame are distinct browser performance APIs. The generic ui.task operation is not a semantic replacement.browser.performance.entry_type=long-task|long-animation-framepackages/browser-utils/src/metrics/browserMetrics.ts
XSMediumBrowserbrowser.${timingPhase}Keep the browser timing-phase ops and add them to conventionsOnly browser is currently registeredCurrent finite values include browser.unloadEvent, redirect, domContentLoadedEvent, loadEvent, connect, TLS/SSL, cache, DNS, request, and response. These phases remain useful as distinct operations.Keep browser.performance.phase as complementary detailpackages/browser-utils/src/metrics/browserMetrics.ts
XSMediumBrowsermeasureKeep measure and add it to conventionsMissingPerformanceMeasure is a distinct, fixed, useful category.Keep the PerformanceEntry name in the span namepackages/browser-utils/src/metrics/browserMetrics.ts
XSMediumBrowserresource.${initiatorType}Keep initiator-type leaves, add them to conventions, and retain resource.other as fallbackPartially registeredRegister the browser-standard initiator types, including currently undocumented values such as worker, icon, frame, object, ping, or track. Values outside the recognized browser set must still map to resource.other.resource.initiator_typepackages/browser-utils/src/metrics/browserMetrics.ts
XSMediumHTTPnavigation.redirectKeep navigation.redirect and add it to conventionsMissingRedirect timing is a stable navigation category worth retaining as its own operation.navigation.type=redirectpackages/browser/src/tracing/browserTracingIntegration.ts
XSMediumStorageobject.get|head|put|delete|list|upload_part|multipart_upload.abort|create|completeKeep object.* and add an object-storage category to conventionsMissingUnlike framework suffixes, these are a finite, provider-neutral API taxonomy for a domain not represented by current conventions. If a smaller taxonomy is preferred, normalize to object.read/write/delete before registration.cloud provider and bucket/object identity remain attributespackages/cloudflare/src/instrumentations/worker/instrumentR2.ts
XSMediumUIui.mount / ui.update / ui.unmountAdd ui.mount, ui.update, and ui.unmount to conventions; ui.render already existsGeneric lifecycle leaves are incompleteThese are framework-neutral replacement targets for equivalent React, Vue, and Svelte lifecycle work.ui.framework; ui.component_name; ui.lifecycle_phasepackages/react/src/profiler.tsx
packages/vue/src/tracing.ts
packages/svelte/src/performance.ts
XSMediumUIui.webvital.lcp / ui.webvital.clsKeep and add both to conventionsMissingThese are fixed, cross-framework browser concepts. They are better convention candidates than framework-specific lifecycle leaves.web_vital.name and measurement value remain authoritativepackages/browser-utils/src/metrics/lcp.ts
packages/browser-utils/src/metrics/cls.ts
packages/browser-utils/src/metrics/webVitalSpans.ts
XLHighGen AIgen_ai.embeddings / gen_ai.generate_content / gen_ai.rerankembeddings / generate_content / rerankMissingThese are fixed, provider-neutral, semantically distinct model operations. Add their unprefixed forms to conventions, then migrate SDK emission consistently.gen_ai.operation.name and gen_ai.operation.typepackages/core/src/tracing/langchain/embeddings.ts
packages/core/src/tracing/openai/index.ts
packages/core/src/tracing/google-genai/index.ts
packages/core/src/tracing/workers-ai/index.ts
packages/core/src/tracing/vercel-ai/index.ts
packages/server-utils/src/integrations/tracing-channel/openai.ts
packages/server-utils/src/integrations/tracing-channel/google-genai.ts
packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts

Replace with another op

Note: The additive "gap" rows — adding a sentry.op to spans that currently emit none, which is not breaking — were split out into #23138 (rate-limit, DO WebSocket, DataLoader prime/clear/clearAll, GraphQL, generic-pool, Effect). The row numbering below therefore skips 21–23.

Row #EffortPriorityCategoryCurrent op(s)Replacement or conventions actionRegistry statusRationale / other findingsPreserve detail inProduction locations
1SHighFaaShttp.request (Firebase Functions)function.gcphttp.request missingThe wrapper instruments all Firebase function trigger types, not only HTTP. A fixed http.request op is semantically wrong.faas.trigger already exists; keep faas.provider=firebasepackages/node/src/integrations/tracing/firebase/otel/patches/functions.ts
2SHighHTTPhttp.client.${serviceIdentifier}http.clientDynamic suffix missingService identity belongs in attributes; endpoint-derived suffixes fragment grouping and can be high-cardinality.rpc.service or server.address / cloud.service.namepackages/google-cloud-serverless/src/integrations/google-cloud-http.ts
3SHighHTTPhttp.client.prefetch / http.server.prefetchhttp.client / http.serverMissing; base ops existOTel inference fabricates unregistered suffixes. Preserve direction and move prefetch to data.sentry.http.prefetch=truepackages/opentelemetry/src/utils/parseSpanDescription.ts
4SHighMessagingfaas.queue plus sentry.op=queue.process on one spanqueue.process onlyqueue.process exact; faas.queue missingCloudflare passes conflicting values. The sentry.op attribute wins, so faas.queue is effectively dead and should be removed.packages/cloudflare/src/instrumentations/worker/instrumentQueue.ts
5SHighRPCgrpc.${serviceIdentifier}grpcDynamic suffix missingService identity can be high-cardinality and already has standard RPC attributes.rpc.service; rpc.methodpackages/google-cloud-serverless/src/integrations/google-cloud-grpc.ts
6SHighUIui.angular.init / ui.angular.${methodKey}ui.mount for init; function for TraceMethodParent ui.angular existsThe method-key suffix is user-controlled and unbounded. Component initialization is a mount; arbitrary decorated methods are functions.ui.framework=angular; code.function.namepackages/angular/src/tracing.ts
7SHighUIui.ember.route.before_model|model|after_model|setup_controllerfunctionMissingThese are route-hook functions. The hook name is already available and should not be encoded in sentry.op.code.function.name; ember.route.hookpackages/ember/addon/index.ts
8SHighUIui.ember.runloop.${queue}ui.taskMissing; ui.task existsQueue values are phase details and Ember can be configured with custom queues.ui.framework=ember; ember.runloop.queuepackages/ember/addon/utils/instrumentEmberGlobals.ts
9SMediumBrowserpaintbrowser.paintbrowser.paint existsRename the raw paint operation to the registered browser-specific operation.Keep the PerformanceEntry name in the span namepackages/browser-utils/src/metrics/browserMetrics.ts
10SMediumFaaSfunction.aws.lambdafunction.awsfunction.aws existsLambda is already implied by provider/runtime attributes; use the registered provider-level operation.faas.name; cloud.provider=aws; cloud.platform=aws_lambdapackages/aws-serverless/src/requestSpanOptions.ts
11SMediumHTTPhttp.client.streamhttp.clientMissing; parent existsStreaming changes response behavior but not the HTTP operation category.http.response.body.streaming=truepackages/browser/src/integrations/fetchStreamPerformance.ts
12SMediumUIui.ember.component.render / component.definition / initui.render / function / ui.mountOnly parent ui.ember existsMap render and initialization to cross-framework lifecycle ops. Component definition lookup is generic function work.ui.framework=ember; ui.component_name; code.function.namepackages/ember/addon/utils/instrumentEmberGlobals.ts
13MHighCachecache.has_item|get_item|get_item_raw|get_items|get_keys|set_item|set_item_raw|set_items|remove_item|clearcache.get / cache.put / cache.removeOnly target ops existThis is the exact over-granularity the cache conventions avoid. Map has/get/list to get; set variants to put; remove/clear to remove.db.operation.name already preserves the unstorage methodpackages/nuxt/src/runtime/utils/instrumentStorage.ts
packages/nitro/src/runtime/hooks/captureStorageEvents.ts
14MHighDatabasedb.redis / db.redis.connectdb.query for commands; db for connectMissing; db and db.query existThe datastore belongs in db.system.name. Library/system-specific op leaves are redundant.db.system.name=redis; db.operation.namepackages/server-utils/src/redis/redis-dc-subscriber.ts
packages/server-utils/src/integrations/tracing-channel/redis.ts
15MHighFaaSfaas.cron / faas.email / function.step.dofunctionMissingCloudflare trigger/workflow phase belongs in attributes. Do not add a new op per trigger.faas.trigger=timer|email; code.function.name; workflow.step.namepackages/cloudflare/src/instrumentations/worker/instrumentScheduled.ts
packages/cloudflare/src/instrumentations/worker/instrumentEmail.ts
packages/cloudflare/src/workflows.ts
16MHighFaaSfaas.trigger.toString() inferred as opInfer function.<provider>, http.server, or queue.process from semantic evidenceArbitrary valuesOTel inference currently promotes an attribute value directly into sentry.op. Custom trigger strings can create unbounded ops.Retain faas.trigger as data; never use it verbatim as oppackages/opentelemetry/src/utils/parseSpanDescription.ts
17MHighGen AIrpc on AWS Bedrock inference spanschat or generate_contentrpc exists but is semantically wrong hereBedrock adds GenAI attributes but inherits the generic AWS SDK rpc op. Select the GenAI operation from the Bedrock request type.packages/server-utils/src/integrations/tracing-channel/aws-sdk/index.ts
packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/bedrock-runtime.ts
18MHighMiddlewareapp_creation.nestjs / request_context.nestjs / event.nestjs / plugin.hapifunctionMissingThese represent executable functions or setup work. Keep lifecycle/event/plugin identity in attributes.code.function.name; nestjs.type; hapi.type; event.namepackages/nestjs/src/integrations/wrap-route.ts
packages/nestjs/src/integrations/helpers.ts
packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
19MHighRPCrpc.server / mcp.server / mcp.notification.client_to_server|server_to_clientrpcOnly rpc existsMCP is JSON-RPC and tRPC is RPC. Direction, method, notification kind, and protocol belong in attributes rather than op suffixes.rpc.system=mcp|trpc; rpc.method; jsonrpc.*; messaging directionpackages/core/src/trpc.ts
packages/core/src/integrations/mcp-server/spans.ts
packages/core/src/integrations/mcp-server/attributes.ts
20MMediumFaaSfunction.gcp.http / event / cloud_eventfunction.gcpfunction.gcp existsTrigger type belongs in faas.trigger. The existing suffixes split one provider category.faas.triggerpackages/google-cloud-serverless/src/gcpfunction/http.ts
packages/google-cloud-serverless/src/gcpfunction/events.ts
packages/google-cloud-serverless/src/gcpfunction/cloud_events.ts
24LHighGen AIgen_ai.create_agent / gen_ai.models / gen_ai.unknown / ai.runfunction for create/models/unknown fallback; map ai.run to a known AI op when evidence existsMissingAgent compilation and model metadata calls are not inference operations. Unknown strings should not become conventions. Vercel AI's fallback should use an explicit mapping or a generic function op.gen_ai.operation.name; code.function.name; retain provider SDK methodpackages/core/src/tracing/langgraph/index.ts
packages/core/src/tracing/anthropic-ai/index.ts
packages/core/src/tracing/openai/index.ts
packages/core/src/tracing/vercel-ai/index.ts
25LHighMessagingmessage / message.produce / message.consumequeue.publish / queue.receive / queue.processmessage* missing; queue.* existsKafka, AMQP, and Deno use a parallel non-convention taxonomy. Use messaging.operation.type to distinguish publish, receive, and process. Deno must not infer all ops from SpanKind alone.messaging.system; messaging.operation.typepackages/server-utils/src/integrations/tracing-channel/kafkajs/spans.ts
packages/server-utils/src/integrations/tracing-channel/amqplib.ts
packages/opentelemetry/src/utils/parseSpanDescription.ts
packages/deno/src/opentelemetry/tracer.ts
26LHighMiddlewarerequest_handler.<library> / handler.nestjs / hono.requestfunction; use http.server only for a true inbound/internal HTTP boundaryMissingTerminal framework handlers are functions, not new op categories. Hono app.request() is an in-process HTTP dispatch and should use http.server with HTTP attributes.code.function.name; framework handler type; HTTP attributes for Hono dispatchpackages/core/src/integrations/express/patch-layer.ts
packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
packages/node/src/integrations/tracing/connect/vendored/instrumentation.ts
packages/node/src/integrations/tracing/hono/index.ts
packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts
packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts
packages/elysia/src/withElysia.ts
packages/nestjs/src/integrations/wrap-route.ts
packages/hono/src/shared/patchAppRequest.ts
27LHighMiddlewarerouter.express / router.koa / router.hapirouter (conventions addition tracked in the first table)router is currently missingBackend router layers should share one framework-neutral operation. They are semantically distinct from generic middleware.code.namespace or framework; router.name; route attributespackages/core/src/integrations/express/patch-layer.ts
packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
packages/server-utils/src/integrations/tracing-channel/koa.ts
packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
28LMediumUIui.angular.routing / ui.sveltekit.routing / ui.ember.transitionrouter (conventions addition tracked in the first table)router must be added to conventionsAll three measure router execution. Collapse framework identity while keeping router work distinct from the broader navigation root.ui.framework; navigation.phasepackages/angular/src/tracing.ts
packages/sveltekit/src/client/svelte4BrowserTracing.ts
packages/sveltekit/src/client/svelte5BrowserTracing.ts
packages/ember/addon/utils/instrumentEmberAppInstanceForPerformance.ts
29LMediumUIui.react.* / ui.vue.* / ui.svelte.* lifecycle opsui.mount / ui.render / ui.update / ui.unmount (missing generic leaves tracked in the first table)React leaves exist; generic leaves are incompletePreferred cleanup: normalize equivalent lifecycle work across frameworks. Current values include React mount/render/update; Vue render/activate/create/unmount/destroy/mount/update; Svelte init/update. Keeping React-specific leaves while collapsing other frameworks would preserve an arbitrary asymmetry.ui.framework; ui.component_name; ui.lifecycle_phasepackages/react/src/profiler.tsx
packages/vue/src/tracing.ts
packages/svelte/src/performance.ts
30XLHighFramework functionsfunction.<framework>(.<phase>) and loader.remix / action.remixfunctionfunction exists; function.nextjs/remix are legacy leavesCollapse all framework and phase suffixes. This also resolves Remix's three competing loader/action taxonomies. Includes Next.js, Remix, React Router client/server, SvelteKit client/server, SolidStart, TanStack Start, and Cloudflare workflow steps.code.function.name; code.namespace; framework-specific phase/type attributespackages/nextjs/src/common/utils/tracingUtils.ts
packages/nextjs/src/common/withServerActionInstrumentation.ts
packages/remix/src/server/instrumentServer.ts
packages/remix/src/server/integrations/tracing-channel.ts
packages/remix/src/server/integrations/opentelemetry.ts
packages/react-router/src/server/createServerInstrumentation.ts
packages/react-router/src/server/wrapServerLoader.ts
packages/react-router/src/server/wrapServerAction.ts
packages/react-router/src/server/instrumentation/reactRouter.ts
packages/react-router/src/server/instrumentation/util.ts
packages/react-router/src/client/createClientInstrumentation.ts
packages/react-router/src/client/hydratedRouter.ts
packages/sveltekit/src/client/load.ts
packages/sveltekit/src/server-common/load.ts
packages/sveltekit/src/server-common/serverRoute.ts
packages/sveltekit/src/server-common/integrations/svelteKitSpans.ts
packages/solidstart/src/server/withServerActionInstrumentation.ts
packages/tanstackstart-react/src/server/wrapFetchWithSentry.ts
packages/cloudflare/src/workflows.ts
31XLHighGen AIgen_ai.chat / gen_ai.execute_tool / gen_ai.invoke_agentchat / execute_tool / invoke_agentRegistry values are unprefixedThe SDK and source-of-truth registry disagree. Migrate to the exact convention values, or explicitly change the registry—but do not leave both. Before migration, replace SDK internals which identify AI spans via op.startsWith('gen_ai.') with gen_ai.operation.type/name.gen_ai.operation.name and gen_ai.operation.typepackages/core/src/tracing/langchain/index.ts
packages/core/src/tracing/langgraph/index.ts
packages/core/src/tracing/langgraph/utils.ts
packages/core/src/tracing/openai/index.ts
packages/core/src/tracing/anthropic-ai/index.ts
packages/core/src/tracing/google-genai/index.ts
packages/core/src/tracing/workers-ai/index.ts
packages/core/src/tracing/vercel-ai/index.ts
packages/server-utils/src/integrations/tracing-channel/openai.ts
packages/server-utils/src/integrations/tracing-channel/anthropic.ts
packages/server-utils/src/integrations/tracing-channel/google-genai.ts
packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts
32XLHighMiddlewaremiddleware.<library> / hook.fastify / http.server.middlewaremiddlewaremiddleware existsCollapse framework identity for middleware and request-pipeline hooks. Router layers are handled separately as router.code.namespace or framework; middleware.type; middleware.namepackages/core/src/integrations/express/patch-layer.ts
packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
packages/node/src/integrations/tracing/connect/vendored/instrumentation.ts
packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
packages/server-utils/src/integrations/tracing-channel/koa.ts
packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts
packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts
packages/node/src/integrations/tracing/hono/index.ts
packages/hono/src/shared/wrapMiddlewareSpan.ts
packages/elysia/src/withElysia.ts
packages/nestjs/src/integrations/helpers.ts
packages/nuxt/src/runtime/hooks/wrapMiddlewareHandler.ts
packages/nitro/src/runtime/hooks/captureTracingEvents.ts
packages/tanstackstart-react/src/server/utils.ts
packages/nextjs/src/common/wrapMiddlewareWithSentry.ts
packages/nextjs/src/common/enhanceMiddlewareRootSpan.ts
packages/nextjs/src/server/enhanceHandleRequestRootSpan.ts
packages/nextjs/src/edge/index.ts

Activity

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

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
     blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
    }
    } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
    })();
    (function(){
    try {
    var __m = "github.com";
    var __re = new RegExp('^' + "github\\.com" + '
    
    Skip to content

    Clean up span operations #22446

    Description

    @Lms24

    Description

    Currently, many of our instrumentations send span ops that are not defined in conventions. This has two reasons:

    1. The span op is simply still missing in conventions and needs to be added
    2. SDKs sent suboptimal, maybe, too fragmented ops. For example, ops that include the framework or library name (e.g. middleware.express or function.sveltekit). Ops should be a bit more general than that.

    I (okay, mostly my clanker, followed by a manual review) audited our instrumentations and these are the places we should make changes to:

    Add to conventions

    EffortPriorityCategoryCurrent op(s)Replacement or conventions actionRegistry statusRationale / other findingsPreserve detail inProduction locations
    XSHighRoutingrouterAdd generic router to conventionsMissingThis is the common framework-neutral replacement target for frontend and backend router spans. Router work is distinct from both navigation roots and generic middleware.ui.framework; navigation.phase; code.namespace or framework; router.name; route attributespackages/angular/src/tracing.ts
    packages/sveltekit/src/client/svelte4BrowserTracing.ts
    packages/sveltekit/src/client/svelte5BrowserTracing.ts
    packages/ember/addon/utils/instrumentEmberAppInstanceForPerformance.ts
    packages/core/src/integrations/express/patch-layer.ts
    packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
    packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
    packages/server-utils/src/integrations/tracing-channel/koa.ts
    packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
    packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
    XSHighUIui.interaction.click|hover|drag|pressKeep ui.interaction.* and add all four leaves to conventionsMissingEvent Timing and INP interaction spans remain distinct from ui.action roots. Register click, hover, drag, and press as the finite interaction taxonomy.Keep DOM event type and INP metric identity as attributespackages/browser-utils/src/metrics/browserMetrics.ts
    packages/browser-utils/src/metrics/inp.ts
    packages/browser-utils/src/metrics/webVitalSpans.ts
    packages/browser/src/tracing/browserTracingIntegration.ts
    XSHighUIui.long-task / ui.long-animation-frameKeep both operations and add them to conventionsMissing; ui.task is not equivalentLong Task and Long Animation Frame are distinct browser performance APIs. The generic ui.task operation is not a semantic replacement.browser.performance.entry_type=long-task|long-animation-framepackages/browser-utils/src/metrics/browserMetrics.ts
    XSMediumBrowserbrowser.${timingPhase}Keep the browser timing-phase ops and add them to conventionsOnly browser is currently registeredCurrent finite values include browser.unloadEvent, redirect, domContentLoadedEvent, loadEvent, connect, TLS/SSL, cache, DNS, request, and response. These phases remain useful as distinct operations.Keep browser.performance.phase as complementary detailpackages/browser-utils/src/metrics/browserMetrics.ts
    XSMediumBrowsermeasureKeep measure and add it to conventionsMissingPerformanceMeasure is a distinct, fixed, useful category.Keep the PerformanceEntry name in the span namepackages/browser-utils/src/metrics/browserMetrics.ts
    XSMediumBrowserresource.${initiatorType}Keep initiator-type leaves, add them to conventions, and retain resource.other as fallbackPartially registeredRegister the browser-standard initiator types, including currently undocumented values such as worker, icon, frame, object, ping, or track. Values outside the recognized browser set must still map to resource.other.resource.initiator_typepackages/browser-utils/src/metrics/browserMetrics.ts
    XSMediumHTTPnavigation.redirectKeep navigation.redirect and add it to conventionsMissingRedirect timing is a stable navigation category worth retaining as its own operation.navigation.type=redirectpackages/browser/src/tracing/browserTracingIntegration.ts
    XSMediumStorageobject.get|head|put|delete|list|upload_part|multipart_upload.abort|create|completeKeep object.* and add an object-storage category to conventionsMissingUnlike framework suffixes, these are a finite, provider-neutral API taxonomy for a domain not represented by current conventions. If a smaller taxonomy is preferred, normalize to object.read/write/delete before registration.cloud provider and bucket/object identity remain attributespackages/cloudflare/src/instrumentations/worker/instrumentR2.ts
    XSMediumUIui.mount / ui.update / ui.unmountAdd ui.mount, ui.update, and ui.unmount to conventions; ui.render already existsGeneric lifecycle leaves are incompleteThese are framework-neutral replacement targets for equivalent React, Vue, and Svelte lifecycle work.ui.framework; ui.component_name; ui.lifecycle_phasepackages/react/src/profiler.tsx
    packages/vue/src/tracing.ts
    packages/svelte/src/performance.ts
    XSMediumUIui.webvital.lcp / ui.webvital.clsKeep and add both to conventionsMissingThese are fixed, cross-framework browser concepts. They are better convention candidates than framework-specific lifecycle leaves.web_vital.name and measurement value remain authoritativepackages/browser-utils/src/metrics/lcp.ts
    packages/browser-utils/src/metrics/cls.ts
    packages/browser-utils/src/metrics/webVitalSpans.ts
    XLHighGen AIgen_ai.embeddings / gen_ai.generate_content / gen_ai.rerankembeddings / generate_content / rerankMissingThese are fixed, provider-neutral, semantically distinct model operations. Add their unprefixed forms to conventions, then migrate SDK emission consistently.gen_ai.operation.name and gen_ai.operation.typepackages/core/src/tracing/langchain/embeddings.ts
    packages/core/src/tracing/openai/index.ts
    packages/core/src/tracing/google-genai/index.ts
    packages/core/src/tracing/workers-ai/index.ts
    packages/core/src/tracing/vercel-ai/index.ts
    packages/server-utils/src/integrations/tracing-channel/openai.ts
    packages/server-utils/src/integrations/tracing-channel/google-genai.ts
    packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts

    Replace with another op

    Note: The additive "gap" rows — adding a sentry.op to spans that currently emit none, which is not breaking — were split out into #23138 (rate-limit, DO WebSocket, DataLoader prime/clear/clearAll, GraphQL, generic-pool, Effect). The row numbering below therefore skips 21–23.

    Row #EffortPriorityCategoryCurrent op(s)Replacement or conventions actionRegistry statusRationale / other findingsPreserve detail inProduction locations
    1SHighFaaShttp.request (Firebase Functions)function.gcphttp.request missingThe wrapper instruments all Firebase function trigger types, not only HTTP. A fixed http.request op is semantically wrong.faas.trigger already exists; keep faas.provider=firebasepackages/node/src/integrations/tracing/firebase/otel/patches/functions.ts
    2SHighHTTPhttp.client.${serviceIdentifier}http.clientDynamic suffix missingService identity belongs in attributes; endpoint-derived suffixes fragment grouping and can be high-cardinality.rpc.service or server.address / cloud.service.namepackages/google-cloud-serverless/src/integrations/google-cloud-http.ts
    3SHighHTTPhttp.client.prefetch / http.server.prefetchhttp.client / http.serverMissing; base ops existOTel inference fabricates unregistered suffixes. Preserve direction and move prefetch to data.sentry.http.prefetch=truepackages/opentelemetry/src/utils/parseSpanDescription.ts
    4SHighMessagingfaas.queue plus sentry.op=queue.process on one spanqueue.process onlyqueue.process exact; faas.queue missingCloudflare passes conflicting values. The sentry.op attribute wins, so faas.queue is effectively dead and should be removed.packages/cloudflare/src/instrumentations/worker/instrumentQueue.ts
    5SHighRPCgrpc.${serviceIdentifier}grpcDynamic suffix missingService identity can be high-cardinality and already has standard RPC attributes.rpc.service; rpc.methodpackages/google-cloud-serverless/src/integrations/google-cloud-grpc.ts
    6SHighUIui.angular.init / ui.angular.${methodKey}ui.mount for init; function for TraceMethodParent ui.angular existsThe method-key suffix is user-controlled and unbounded. Component initialization is a mount; arbitrary decorated methods are functions.ui.framework=angular; code.function.namepackages/angular/src/tracing.ts
    7SHighUIui.ember.route.before_model|model|after_model|setup_controllerfunctionMissingThese are route-hook functions. The hook name is already available and should not be encoded in sentry.op.code.function.name; ember.route.hookpackages/ember/addon/index.ts
    8SHighUIui.ember.runloop.${queue}ui.taskMissing; ui.task existsQueue values are phase details and Ember can be configured with custom queues.ui.framework=ember; ember.runloop.queuepackages/ember/addon/utils/instrumentEmberGlobals.ts
    9SMediumBrowserpaintbrowser.paintbrowser.paint existsRename the raw paint operation to the registered browser-specific operation.Keep the PerformanceEntry name in the span namepackages/browser-utils/src/metrics/browserMetrics.ts
    10SMediumFaaSfunction.aws.lambdafunction.awsfunction.aws existsLambda is already implied by provider/runtime attributes; use the registered provider-level operation.faas.name; cloud.provider=aws; cloud.platform=aws_lambdapackages/aws-serverless/src/requestSpanOptions.ts
    11SMediumHTTPhttp.client.streamhttp.clientMissing; parent existsStreaming changes response behavior but not the HTTP operation category.http.response.body.streaming=truepackages/browser/src/integrations/fetchStreamPerformance.ts
    12SMediumUIui.ember.component.render / component.definition / initui.render / function / ui.mountOnly parent ui.ember existsMap render and initialization to cross-framework lifecycle ops. Component definition lookup is generic function work.ui.framework=ember; ui.component_name; code.function.namepackages/ember/addon/utils/instrumentEmberGlobals.ts
    13MHighCachecache.has_item|get_item|get_item_raw|get_items|get_keys|set_item|set_item_raw|set_items|remove_item|clearcache.get / cache.put / cache.removeOnly target ops existThis is the exact over-granularity the cache conventions avoid. Map has/get/list to get; set variants to put; remove/clear to remove.db.operation.name already preserves the unstorage methodpackages/nuxt/src/runtime/utils/instrumentStorage.ts
    packages/nitro/src/runtime/hooks/captureStorageEvents.ts
    14MHighDatabasedb.redis / db.redis.connectdb.query for commands; db for connectMissing; db and db.query existThe datastore belongs in db.system.name. Library/system-specific op leaves are redundant.db.system.name=redis; db.operation.namepackages/server-utils/src/redis/redis-dc-subscriber.ts
    packages/server-utils/src/integrations/tracing-channel/redis.ts
    15MHighFaaSfaas.cron / faas.email / function.step.dofunctionMissingCloudflare trigger/workflow phase belongs in attributes. Do not add a new op per trigger.faas.trigger=timer|email; code.function.name; workflow.step.namepackages/cloudflare/src/instrumentations/worker/instrumentScheduled.ts
    packages/cloudflare/src/instrumentations/worker/instrumentEmail.ts
    packages/cloudflare/src/workflows.ts
    16MHighFaaSfaas.trigger.toString() inferred as opInfer function.<provider>, http.server, or queue.process from semantic evidenceArbitrary valuesOTel inference currently promotes an attribute value directly into sentry.op. Custom trigger strings can create unbounded ops.Retain faas.trigger as data; never use it verbatim as oppackages/opentelemetry/src/utils/parseSpanDescription.ts
    17MHighGen AIrpc on AWS Bedrock inference spanschat or generate_contentrpc exists but is semantically wrong hereBedrock adds GenAI attributes but inherits the generic AWS SDK rpc op. Select the GenAI operation from the Bedrock request type.packages/server-utils/src/integrations/tracing-channel/aws-sdk/index.ts
    packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/bedrock-runtime.ts
    18MHighMiddlewareapp_creation.nestjs / request_context.nestjs / event.nestjs / plugin.hapifunctionMissingThese represent executable functions or setup work. Keep lifecycle/event/plugin identity in attributes.code.function.name; nestjs.type; hapi.type; event.namepackages/nestjs/src/integrations/wrap-route.ts
    packages/nestjs/src/integrations/helpers.ts
    packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
    packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
    19MHighRPCrpc.server / mcp.server / mcp.notification.client_to_server|server_to_clientrpcOnly rpc existsMCP is JSON-RPC and tRPC is RPC. Direction, method, notification kind, and protocol belong in attributes rather than op suffixes.rpc.system=mcp|trpc; rpc.method; jsonrpc.*; messaging directionpackages/core/src/trpc.ts
    packages/core/src/integrations/mcp-server/spans.ts
    packages/core/src/integrations/mcp-server/attributes.ts
    20MMediumFaaSfunction.gcp.http / event / cloud_eventfunction.gcpfunction.gcp existsTrigger type belongs in faas.trigger. The existing suffixes split one provider category.faas.triggerpackages/google-cloud-serverless/src/gcpfunction/http.ts
    packages/google-cloud-serverless/src/gcpfunction/events.ts
    packages/google-cloud-serverless/src/gcpfunction/cloud_events.ts
    24LHighGen AIgen_ai.create_agent / gen_ai.models / gen_ai.unknown / ai.runfunction for create/models/unknown fallback; map ai.run to a known AI op when evidence existsMissingAgent compilation and model metadata calls are not inference operations. Unknown strings should not become conventions. Vercel AI's fallback should use an explicit mapping or a generic function op.gen_ai.operation.name; code.function.name; retain provider SDK methodpackages/core/src/tracing/langgraph/index.ts
    packages/core/src/tracing/anthropic-ai/index.ts
    packages/core/src/tracing/openai/index.ts
    packages/core/src/tracing/vercel-ai/index.ts
    25LHighMessagingmessage / message.produce / message.consumequeue.publish / queue.receive / queue.processmessage* missing; queue.* existsKafka, AMQP, and Deno use a parallel non-convention taxonomy. Use messaging.operation.type to distinguish publish, receive, and process. Deno must not infer all ops from SpanKind alone.messaging.system; messaging.operation.typepackages/server-utils/src/integrations/tracing-channel/kafkajs/spans.ts
    packages/server-utils/src/integrations/tracing-channel/amqplib.ts
    packages/opentelemetry/src/utils/parseSpanDescription.ts
    packages/deno/src/opentelemetry/tracer.ts
    26LHighMiddlewarerequest_handler.<library> / handler.nestjs / hono.requestfunction; use http.server only for a true inbound/internal HTTP boundaryMissingTerminal framework handlers are functions, not new op categories. Hono app.request() is an in-process HTTP dispatch and should use http.server with HTTP attributes.code.function.name; framework handler type; HTTP attributes for Hono dispatchpackages/core/src/integrations/express/patch-layer.ts
    packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
    packages/node/src/integrations/tracing/connect/vendored/instrumentation.ts
    packages/node/src/integrations/tracing/hono/index.ts
    packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts
    packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts
    packages/elysia/src/withElysia.ts
    packages/nestjs/src/integrations/wrap-route.ts
    packages/hono/src/shared/patchAppRequest.ts
    27LHighMiddlewarerouter.express / router.koa / router.hapirouter (conventions addition tracked in the first table)router is currently missingBackend router layers should share one framework-neutral operation. They are semantically distinct from generic middleware.code.namespace or framework; router.name; route attributespackages/core/src/integrations/express/patch-layer.ts
    packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
    packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
    packages/server-utils/src/integrations/tracing-channel/koa.ts
    packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
    packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
    28LMediumUIui.angular.routing / ui.sveltekit.routing / ui.ember.transitionrouter (conventions addition tracked in the first table)router must be added to conventionsAll three measure router execution. Collapse framework identity while keeping router work distinct from the broader navigation root.ui.framework; navigation.phasepackages/angular/src/tracing.ts
    packages/sveltekit/src/client/svelte4BrowserTracing.ts
    packages/sveltekit/src/client/svelte5BrowserTracing.ts
    packages/ember/addon/utils/instrumentEmberAppInstanceForPerformance.ts
    29LMediumUIui.react.* / ui.vue.* / ui.svelte.* lifecycle opsui.mount / ui.render / ui.update / ui.unmount (missing generic leaves tracked in the first table)React leaves exist; generic leaves are incompletePreferred cleanup: normalize equivalent lifecycle work across frameworks. Current values include React mount/render/update; Vue render/activate/create/unmount/destroy/mount/update; Svelte init/update. Keeping React-specific leaves while collapsing other frameworks would preserve an arbitrary asymmetry.ui.framework; ui.component_name; ui.lifecycle_phasepackages/react/src/profiler.tsx
    packages/vue/src/tracing.ts
    packages/svelte/src/performance.ts
    30XLHighFramework functionsfunction.<framework>(.<phase>) and loader.remix / action.remixfunctionfunction exists; function.nextjs/remix are legacy leavesCollapse all framework and phase suffixes. This also resolves Remix's three competing loader/action taxonomies. Includes Next.js, Remix, React Router client/server, SvelteKit client/server, SolidStart, TanStack Start, and Cloudflare workflow steps.code.function.name; code.namespace; framework-specific phase/type attributespackages/nextjs/src/common/utils/tracingUtils.ts
    packages/nextjs/src/common/withServerActionInstrumentation.ts
    packages/remix/src/server/instrumentServer.ts
    packages/remix/src/server/integrations/tracing-channel.ts
    packages/remix/src/server/integrations/opentelemetry.ts
    packages/react-router/src/server/createServerInstrumentation.ts
    packages/react-router/src/server/wrapServerLoader.ts
    packages/react-router/src/server/wrapServerAction.ts
    packages/react-router/src/server/instrumentation/reactRouter.ts
    packages/react-router/src/server/instrumentation/util.ts
    packages/react-router/src/client/createClientInstrumentation.ts
    packages/react-router/src/client/hydratedRouter.ts
    packages/sveltekit/src/client/load.ts
    packages/sveltekit/src/server-common/load.ts
    packages/sveltekit/src/server-common/serverRoute.ts
    packages/sveltekit/src/server-common/integrations/svelteKitSpans.ts
    packages/solidstart/src/server/withServerActionInstrumentation.ts
    packages/tanstackstart-react/src/server/wrapFetchWithSentry.ts
    packages/cloudflare/src/workflows.ts
    31XLHighGen AIgen_ai.chat / gen_ai.execute_tool / gen_ai.invoke_agentchat / execute_tool / invoke_agentRegistry values are unprefixedThe SDK and source-of-truth registry disagree. Migrate to the exact convention values, or explicitly change the registry—but do not leave both. Before migration, replace SDK internals which identify AI spans via op.startsWith('gen_ai.') with gen_ai.operation.type/name.gen_ai.operation.name and gen_ai.operation.typepackages/core/src/tracing/langchain/index.ts
    packages/core/src/tracing/langgraph/index.ts
    packages/core/src/tracing/langgraph/utils.ts
    packages/core/src/tracing/openai/index.ts
    packages/core/src/tracing/anthropic-ai/index.ts
    packages/core/src/tracing/google-genai/index.ts
    packages/core/src/tracing/workers-ai/index.ts
    packages/core/src/tracing/vercel-ai/index.ts
    packages/server-utils/src/integrations/tracing-channel/openai.ts
    packages/server-utils/src/integrations/tracing-channel/anthropic.ts
    packages/server-utils/src/integrations/tracing-channel/google-genai.ts
    packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts
    32XLHighMiddlewaremiddleware.<library> / hook.fastify / http.server.middlewaremiddlewaremiddleware existsCollapse framework identity for middleware and request-pipeline hooks. Router layers are handled separately as router.code.namespace or framework; middleware.type; middleware.namepackages/core/src/integrations/express/patch-layer.ts
    packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
    packages/node/src/integrations/tracing/connect/vendored/instrumentation.ts
    packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
    packages/server-utils/src/integrations/tracing-channel/koa.ts
    packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
    packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
    packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts
    packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts
    packages/node/src/integrations/tracing/hono/index.ts
    packages/hono/src/shared/wrapMiddlewareSpan.ts
    packages/elysia/src/withElysia.ts
    packages/nestjs/src/integrations/helpers.ts
    packages/nuxt/src/runtime/hooks/wrapMiddlewareHandler.ts
    packages/nitro/src/runtime/hooks/captureTracingEvents.ts
    packages/tanstackstart-react/src/server/utils.ts
    packages/nextjs/src/common/wrapMiddlewareWithSentry.ts
    packages/nextjs/src/common/enhanceMiddlewareRootSpan.ts
    packages/nextjs/src/server/enhanceHandleRequestRootSpan.ts
    packages/nextjs/src/edge/index.ts

    Activity

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

    Metadata

    Metadata

    Assignees

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
      Skip to content

      Clean up span operations #22446

      Description

      @Lms24

      Description

      Currently, many of our instrumentations send span ops that are not defined in conventions. This has two reasons:

      1. The span op is simply still missing in conventions and needs to be added
      2. SDKs sent suboptimal, maybe, too fragmented ops. For example, ops that include the framework or library name (e.g. middleware.express or function.sveltekit). Ops should be a bit more general than that.

      I (okay, mostly my clanker, followed by a manual review) audited our instrumentations and these are the places we should make changes to:

      Add to conventions

      EffortPriorityCategoryCurrent op(s)Replacement or conventions actionRegistry statusRationale / other findingsPreserve detail inProduction locations
      XSHighRoutingrouterAdd generic router to conventionsMissingThis is the common framework-neutral replacement target for frontend and backend router spans. Router work is distinct from both navigation roots and generic middleware.ui.framework; navigation.phase; code.namespace or framework; router.name; route attributespackages/angular/src/tracing.ts
      packages/sveltekit/src/client/svelte4BrowserTracing.ts
      packages/sveltekit/src/client/svelte5BrowserTracing.ts
      packages/ember/addon/utils/instrumentEmberAppInstanceForPerformance.ts
      packages/core/src/integrations/express/patch-layer.ts
      packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
      packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
      packages/server-utils/src/integrations/tracing-channel/koa.ts
      packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
      packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
      XSHighUIui.interaction.click|hover|drag|pressKeep ui.interaction.* and add all four leaves to conventionsMissingEvent Timing and INP interaction spans remain distinct from ui.action roots. Register click, hover, drag, and press as the finite interaction taxonomy.Keep DOM event type and INP metric identity as attributespackages/browser-utils/src/metrics/browserMetrics.ts
      packages/browser-utils/src/metrics/inp.ts
      packages/browser-utils/src/metrics/webVitalSpans.ts
      packages/browser/src/tracing/browserTracingIntegration.ts
      XSHighUIui.long-task / ui.long-animation-frameKeep both operations and add them to conventionsMissing; ui.task is not equivalentLong Task and Long Animation Frame are distinct browser performance APIs. The generic ui.task operation is not a semantic replacement.browser.performance.entry_type=long-task|long-animation-framepackages/browser-utils/src/metrics/browserMetrics.ts
      XSMediumBrowserbrowser.${timingPhase}Keep the browser timing-phase ops and add them to conventionsOnly browser is currently registeredCurrent finite values include browser.unloadEvent, redirect, domContentLoadedEvent, loadEvent, connect, TLS/SSL, cache, DNS, request, and response. These phases remain useful as distinct operations.Keep browser.performance.phase as complementary detailpackages/browser-utils/src/metrics/browserMetrics.ts
      XSMediumBrowsermeasureKeep measure and add it to conventionsMissingPerformanceMeasure is a distinct, fixed, useful category.Keep the PerformanceEntry name in the span namepackages/browser-utils/src/metrics/browserMetrics.ts
      XSMediumBrowserresource.${initiatorType}Keep initiator-type leaves, add them to conventions, and retain resource.other as fallbackPartially registeredRegister the browser-standard initiator types, including currently undocumented values such as worker, icon, frame, object, ping, or track. Values outside the recognized browser set must still map to resource.other.resource.initiator_typepackages/browser-utils/src/metrics/browserMetrics.ts
      XSMediumHTTPnavigation.redirectKeep navigation.redirect and add it to conventionsMissingRedirect timing is a stable navigation category worth retaining as its own operation.navigation.type=redirectpackages/browser/src/tracing/browserTracingIntegration.ts
      XSMediumStorageobject.get|head|put|delete|list|upload_part|multipart_upload.abort|create|completeKeep object.* and add an object-storage category to conventionsMissingUnlike framework suffixes, these are a finite, provider-neutral API taxonomy for a domain not represented by current conventions. If a smaller taxonomy is preferred, normalize to object.read/write/delete before registration.cloud provider and bucket/object identity remain attributespackages/cloudflare/src/instrumentations/worker/instrumentR2.ts
      XSMediumUIui.mount / ui.update / ui.unmountAdd ui.mount, ui.update, and ui.unmount to conventions; ui.render already existsGeneric lifecycle leaves are incompleteThese are framework-neutral replacement targets for equivalent React, Vue, and Svelte lifecycle work.ui.framework; ui.component_name; ui.lifecycle_phasepackages/react/src/profiler.tsx
      packages/vue/src/tracing.ts
      packages/svelte/src/performance.ts
      XSMediumUIui.webvital.lcp / ui.webvital.clsKeep and add both to conventionsMissingThese are fixed, cross-framework browser concepts. They are better convention candidates than framework-specific lifecycle leaves.web_vital.name and measurement value remain authoritativepackages/browser-utils/src/metrics/lcp.ts
      packages/browser-utils/src/metrics/cls.ts
      packages/browser-utils/src/metrics/webVitalSpans.ts
      XLHighGen AIgen_ai.embeddings / gen_ai.generate_content / gen_ai.rerankembeddings / generate_content / rerankMissingThese are fixed, provider-neutral, semantically distinct model operations. Add their unprefixed forms to conventions, then migrate SDK emission consistently.gen_ai.operation.name and gen_ai.operation.typepackages/core/src/tracing/langchain/embeddings.ts
      packages/core/src/tracing/openai/index.ts
      packages/core/src/tracing/google-genai/index.ts
      packages/core/src/tracing/workers-ai/index.ts
      packages/core/src/tracing/vercel-ai/index.ts
      packages/server-utils/src/integrations/tracing-channel/openai.ts
      packages/server-utils/src/integrations/tracing-channel/google-genai.ts
      packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts

      Replace with another op

      Note: The additive "gap" rows — adding a sentry.op to spans that currently emit none, which is not breaking — were split out into #23138 (rate-limit, DO WebSocket, DataLoader prime/clear/clearAll, GraphQL, generic-pool, Effect). The row numbering below therefore skips 21–23.

      Row #EffortPriorityCategoryCurrent op(s)Replacement or conventions actionRegistry statusRationale / other findingsPreserve detail inProduction locations
      1SHighFaaShttp.request (Firebase Functions)function.gcphttp.request missingThe wrapper instruments all Firebase function trigger types, not only HTTP. A fixed http.request op is semantically wrong.faas.trigger already exists; keep faas.provider=firebasepackages/node/src/integrations/tracing/firebase/otel/patches/functions.ts
      2SHighHTTPhttp.client.${serviceIdentifier}http.clientDynamic suffix missingService identity belongs in attributes; endpoint-derived suffixes fragment grouping and can be high-cardinality.rpc.service or server.address / cloud.service.namepackages/google-cloud-serverless/src/integrations/google-cloud-http.ts
      3SHighHTTPhttp.client.prefetch / http.server.prefetchhttp.client / http.serverMissing; base ops existOTel inference fabricates unregistered suffixes. Preserve direction and move prefetch to data.sentry.http.prefetch=truepackages/opentelemetry/src/utils/parseSpanDescription.ts
      4SHighMessagingfaas.queue plus sentry.op=queue.process on one spanqueue.process onlyqueue.process exact; faas.queue missingCloudflare passes conflicting values. The sentry.op attribute wins, so faas.queue is effectively dead and should be removed.packages/cloudflare/src/instrumentations/worker/instrumentQueue.ts
      5SHighRPCgrpc.${serviceIdentifier}grpcDynamic suffix missingService identity can be high-cardinality and already has standard RPC attributes.rpc.service; rpc.methodpackages/google-cloud-serverless/src/integrations/google-cloud-grpc.ts
      6SHighUIui.angular.init / ui.angular.${methodKey}ui.mount for init; function for TraceMethodParent ui.angular existsThe method-key suffix is user-controlled and unbounded. Component initialization is a mount; arbitrary decorated methods are functions.ui.framework=angular; code.function.namepackages/angular/src/tracing.ts
      7SHighUIui.ember.route.before_model|model|after_model|setup_controllerfunctionMissingThese are route-hook functions. The hook name is already available and should not be encoded in sentry.op.code.function.name; ember.route.hookpackages/ember/addon/index.ts
      8SHighUIui.ember.runloop.${queue}ui.taskMissing; ui.task existsQueue values are phase details and Ember can be configured with custom queues.ui.framework=ember; ember.runloop.queuepackages/ember/addon/utils/instrumentEmberGlobals.ts
      9SMediumBrowserpaintbrowser.paintbrowser.paint existsRename the raw paint operation to the registered browser-specific operation.Keep the PerformanceEntry name in the span namepackages/browser-utils/src/metrics/browserMetrics.ts
      10SMediumFaaSfunction.aws.lambdafunction.awsfunction.aws existsLambda is already implied by provider/runtime attributes; use the registered provider-level operation.faas.name; cloud.provider=aws; cloud.platform=aws_lambdapackages/aws-serverless/src/requestSpanOptions.ts
      11SMediumHTTPhttp.client.streamhttp.clientMissing; parent existsStreaming changes response behavior but not the HTTP operation category.http.response.body.streaming=truepackages/browser/src/integrations/fetchStreamPerformance.ts
      12SMediumUIui.ember.component.render / component.definition / initui.render / function / ui.mountOnly parent ui.ember existsMap render and initialization to cross-framework lifecycle ops. Component definition lookup is generic function work.ui.framework=ember; ui.component_name; code.function.namepackages/ember/addon/utils/instrumentEmberGlobals.ts
      13MHighCachecache.has_item|get_item|get_item_raw|get_items|get_keys|set_item|set_item_raw|set_items|remove_item|clearcache.get / cache.put / cache.removeOnly target ops existThis is the exact over-granularity the cache conventions avoid. Map has/get/list to get; set variants to put; remove/clear to remove.db.operation.name already preserves the unstorage methodpackages/nuxt/src/runtime/utils/instrumentStorage.ts
      packages/nitro/src/runtime/hooks/captureStorageEvents.ts
      14MHighDatabasedb.redis / db.redis.connectdb.query for commands; db for connectMissing; db and db.query existThe datastore belongs in db.system.name. Library/system-specific op leaves are redundant.db.system.name=redis; db.operation.namepackages/server-utils/src/redis/redis-dc-subscriber.ts
      packages/server-utils/src/integrations/tracing-channel/redis.ts
      15MHighFaaSfaas.cron / faas.email / function.step.dofunctionMissingCloudflare trigger/workflow phase belongs in attributes. Do not add a new op per trigger.faas.trigger=timer|email; code.function.name; workflow.step.namepackages/cloudflare/src/instrumentations/worker/instrumentScheduled.ts
      packages/cloudflare/src/instrumentations/worker/instrumentEmail.ts
      packages/cloudflare/src/workflows.ts
      16MHighFaaSfaas.trigger.toString() inferred as opInfer function.<provider>, http.server, or queue.process from semantic evidenceArbitrary valuesOTel inference currently promotes an attribute value directly into sentry.op. Custom trigger strings can create unbounded ops.Retain faas.trigger as data; never use it verbatim as oppackages/opentelemetry/src/utils/parseSpanDescription.ts
      17MHighGen AIrpc on AWS Bedrock inference spanschat or generate_contentrpc exists but is semantically wrong hereBedrock adds GenAI attributes but inherits the generic AWS SDK rpc op. Select the GenAI operation from the Bedrock request type.packages/server-utils/src/integrations/tracing-channel/aws-sdk/index.ts
      packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/bedrock-runtime.ts
      18MHighMiddlewareapp_creation.nestjs / request_context.nestjs / event.nestjs / plugin.hapifunctionMissingThese represent executable functions or setup work. Keep lifecycle/event/plugin identity in attributes.code.function.name; nestjs.type; hapi.type; event.namepackages/nestjs/src/integrations/wrap-route.ts
      packages/nestjs/src/integrations/helpers.ts
      packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
      packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
      19MHighRPCrpc.server / mcp.server / mcp.notification.client_to_server|server_to_clientrpcOnly rpc existsMCP is JSON-RPC and tRPC is RPC. Direction, method, notification kind, and protocol belong in attributes rather than op suffixes.rpc.system=mcp|trpc; rpc.method; jsonrpc.*; messaging directionpackages/core/src/trpc.ts
      packages/core/src/integrations/mcp-server/spans.ts
      packages/core/src/integrations/mcp-server/attributes.ts
      20MMediumFaaSfunction.gcp.http / event / cloud_eventfunction.gcpfunction.gcp existsTrigger type belongs in faas.trigger. The existing suffixes split one provider category.faas.triggerpackages/google-cloud-serverless/src/gcpfunction/http.ts
      packages/google-cloud-serverless/src/gcpfunction/events.ts
      packages/google-cloud-serverless/src/gcpfunction/cloud_events.ts
      24LHighGen AIgen_ai.create_agent / gen_ai.models / gen_ai.unknown / ai.runfunction for create/models/unknown fallback; map ai.run to a known AI op when evidence existsMissingAgent compilation and model metadata calls are not inference operations. Unknown strings should not become conventions. Vercel AI's fallback should use an explicit mapping or a generic function op.gen_ai.operation.name; code.function.name; retain provider SDK methodpackages/core/src/tracing/langgraph/index.ts
      packages/core/src/tracing/anthropic-ai/index.ts
      packages/core/src/tracing/openai/index.ts
      packages/core/src/tracing/vercel-ai/index.ts
      25LHighMessagingmessage / message.produce / message.consumequeue.publish / queue.receive / queue.processmessage* missing; queue.* existsKafka, AMQP, and Deno use a parallel non-convention taxonomy. Use messaging.operation.type to distinguish publish, receive, and process. Deno must not infer all ops from SpanKind alone.messaging.system; messaging.operation.typepackages/server-utils/src/integrations/tracing-channel/kafkajs/spans.ts
      packages/server-utils/src/integrations/tracing-channel/amqplib.ts
      packages/opentelemetry/src/utils/parseSpanDescription.ts
      packages/deno/src/opentelemetry/tracer.ts
      26LHighMiddlewarerequest_handler.<library> / handler.nestjs / hono.requestfunction; use http.server only for a true inbound/internal HTTP boundaryMissingTerminal framework handlers are functions, not new op categories. Hono app.request() is an in-process HTTP dispatch and should use http.server with HTTP attributes.code.function.name; framework handler type; HTTP attributes for Hono dispatchpackages/core/src/integrations/express/patch-layer.ts
      packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
      packages/node/src/integrations/tracing/connect/vendored/instrumentation.ts
      packages/node/src/integrations/tracing/hono/index.ts
      packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts
      packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts
      packages/elysia/src/withElysia.ts
      packages/nestjs/src/integrations/wrap-route.ts
      packages/hono/src/shared/patchAppRequest.ts
      27LHighMiddlewarerouter.express / router.koa / router.hapirouter (conventions addition tracked in the first table)router is currently missingBackend router layers should share one framework-neutral operation. They are semantically distinct from generic middleware.code.namespace or framework; router.name; route attributespackages/core/src/integrations/express/patch-layer.ts
      packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
      packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
      packages/server-utils/src/integrations/tracing-channel/koa.ts
      packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
      packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
      28LMediumUIui.angular.routing / ui.sveltekit.routing / ui.ember.transitionrouter (conventions addition tracked in the first table)router must be added to conventionsAll three measure router execution. Collapse framework identity while keeping router work distinct from the broader navigation root.ui.framework; navigation.phasepackages/angular/src/tracing.ts
      packages/sveltekit/src/client/svelte4BrowserTracing.ts
      packages/sveltekit/src/client/svelte5BrowserTracing.ts
      packages/ember/addon/utils/instrumentEmberAppInstanceForPerformance.ts
      29LMediumUIui.react.* / ui.vue.* / ui.svelte.* lifecycle opsui.mount / ui.render / ui.update / ui.unmount (missing generic leaves tracked in the first table)React leaves exist; generic leaves are incompletePreferred cleanup: normalize equivalent lifecycle work across frameworks. Current values include React mount/render/update; Vue render/activate/create/unmount/destroy/mount/update; Svelte init/update. Keeping React-specific leaves while collapsing other frameworks would preserve an arbitrary asymmetry.ui.framework; ui.component_name; ui.lifecycle_phasepackages/react/src/profiler.tsx
      packages/vue/src/tracing.ts
      packages/svelte/src/performance.ts
      30XLHighFramework functionsfunction.<framework>(.<phase>) and loader.remix / action.remixfunctionfunction exists; function.nextjs/remix are legacy leavesCollapse all framework and phase suffixes. This also resolves Remix's three competing loader/action taxonomies. Includes Next.js, Remix, React Router client/server, SvelteKit client/server, SolidStart, TanStack Start, and Cloudflare workflow steps.code.function.name; code.namespace; framework-specific phase/type attributespackages/nextjs/src/common/utils/tracingUtils.ts
      packages/nextjs/src/common/withServerActionInstrumentation.ts
      packages/remix/src/server/instrumentServer.ts
      packages/remix/src/server/integrations/tracing-channel.ts
      packages/remix/src/server/integrations/opentelemetry.ts
      packages/react-router/src/server/createServerInstrumentation.ts
      packages/react-router/src/server/wrapServerLoader.ts
      packages/react-router/src/server/wrapServerAction.ts
      packages/react-router/src/server/instrumentation/reactRouter.ts
      packages/react-router/src/server/instrumentation/util.ts
      packages/react-router/src/client/createClientInstrumentation.ts
      packages/react-router/src/client/hydratedRouter.ts
      packages/sveltekit/src/client/load.ts
      packages/sveltekit/src/server-common/load.ts
      packages/sveltekit/src/server-common/serverRoute.ts
      packages/sveltekit/src/server-common/integrations/svelteKitSpans.ts
      packages/solidstart/src/server/withServerActionInstrumentation.ts
      packages/tanstackstart-react/src/server/wrapFetchWithSentry.ts
      packages/cloudflare/src/workflows.ts
      31XLHighGen AIgen_ai.chat / gen_ai.execute_tool / gen_ai.invoke_agentchat / execute_tool / invoke_agentRegistry values are unprefixedThe SDK and source-of-truth registry disagree. Migrate to the exact convention values, or explicitly change the registry—but do not leave both. Before migration, replace SDK internals which identify AI spans via op.startsWith('gen_ai.') with gen_ai.operation.type/name.gen_ai.operation.name and gen_ai.operation.typepackages/core/src/tracing/langchain/index.ts
      packages/core/src/tracing/langgraph/index.ts
      packages/core/src/tracing/langgraph/utils.ts
      packages/core/src/tracing/openai/index.ts
      packages/core/src/tracing/anthropic-ai/index.ts
      packages/core/src/tracing/google-genai/index.ts
      packages/core/src/tracing/workers-ai/index.ts
      packages/core/src/tracing/vercel-ai/index.ts
      packages/server-utils/src/integrations/tracing-channel/openai.ts
      packages/server-utils/src/integrations/tracing-channel/anthropic.ts
      packages/server-utils/src/integrations/tracing-channel/google-genai.ts
      packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts
      32XLHighMiddlewaremiddleware.<library> / hook.fastify / http.server.middlewaremiddlewaremiddleware existsCollapse framework identity for middleware and request-pipeline hooks. Router layers are handled separately as router.code.namespace or framework; middleware.type; middleware.namepackages/core/src/integrations/express/patch-layer.ts
      packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
      packages/node/src/integrations/tracing/connect/vendored/instrumentation.ts
      packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
      packages/server-utils/src/integrations/tracing-channel/koa.ts
      packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
      packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
      packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts
      packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts
      packages/node/src/integrations/tracing/hono/index.ts
      packages/hono/src/shared/wrapMiddlewareSpan.ts
      packages/elysia/src/withElysia.ts
      packages/nestjs/src/integrations/helpers.ts
      packages/nuxt/src/runtime/hooks/wrapMiddlewareHandler.ts
      packages/nitro/src/runtime/hooks/captureTracingEvents.ts
      packages/tanstackstart-react/src/server/utils.ts
      packages/nextjs/src/common/wrapMiddlewareWithSentry.ts
      packages/nextjs/src/common/enhanceMiddlewareRootSpan.ts
      packages/nextjs/src/server/enhanceHandleRequestRootSpan.ts
      packages/nextjs/src/edge/index.ts

      Activity

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

      Metadata

      Metadata

      Assignees

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

        , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
        Skip to content

        Clean up span operations #22446

        Description

        @Lms24

        Description

        Currently, many of our instrumentations send span ops that are not defined in conventions. This has two reasons:

        1. The span op is simply still missing in conventions and needs to be added
        2. SDKs sent suboptimal, maybe, too fragmented ops. For example, ops that include the framework or library name (e.g. middleware.express or function.sveltekit). Ops should be a bit more general than that.

        I (okay, mostly my clanker, followed by a manual review) audited our instrumentations and these are the places we should make changes to:

        Add to conventions

        EffortPriorityCategoryCurrent op(s)Replacement or conventions actionRegistry statusRationale / other findingsPreserve detail inProduction locations
        XSHighRoutingrouterAdd generic router to conventionsMissingThis is the common framework-neutral replacement target for frontend and backend router spans. Router work is distinct from both navigation roots and generic middleware.ui.framework; navigation.phase; code.namespace or framework; router.name; route attributespackages/angular/src/tracing.ts
        packages/sveltekit/src/client/svelte4BrowserTracing.ts
        packages/sveltekit/src/client/svelte5BrowserTracing.ts
        packages/ember/addon/utils/instrumentEmberAppInstanceForPerformance.ts
        packages/core/src/integrations/express/patch-layer.ts
        packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
        packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
        packages/server-utils/src/integrations/tracing-channel/koa.ts
        packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
        packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
        XSHighUIui.interaction.click|hover|drag|pressKeep ui.interaction.* and add all four leaves to conventionsMissingEvent Timing and INP interaction spans remain distinct from ui.action roots. Register click, hover, drag, and press as the finite interaction taxonomy.Keep DOM event type and INP metric identity as attributespackages/browser-utils/src/metrics/browserMetrics.ts
        packages/browser-utils/src/metrics/inp.ts
        packages/browser-utils/src/metrics/webVitalSpans.ts
        packages/browser/src/tracing/browserTracingIntegration.ts
        XSHighUIui.long-task / ui.long-animation-frameKeep both operations and add them to conventionsMissing; ui.task is not equivalentLong Task and Long Animation Frame are distinct browser performance APIs. The generic ui.task operation is not a semantic replacement.browser.performance.entry_type=long-task|long-animation-framepackages/browser-utils/src/metrics/browserMetrics.ts
        XSMediumBrowserbrowser.${timingPhase}Keep the browser timing-phase ops and add them to conventionsOnly browser is currently registeredCurrent finite values include browser.unloadEvent, redirect, domContentLoadedEvent, loadEvent, connect, TLS/SSL, cache, DNS, request, and response. These phases remain useful as distinct operations.Keep browser.performance.phase as complementary detailpackages/browser-utils/src/metrics/browserMetrics.ts
        XSMediumBrowsermeasureKeep measure and add it to conventionsMissingPerformanceMeasure is a distinct, fixed, useful category.Keep the PerformanceEntry name in the span namepackages/browser-utils/src/metrics/browserMetrics.ts
        XSMediumBrowserresource.${initiatorType}Keep initiator-type leaves, add them to conventions, and retain resource.other as fallbackPartially registeredRegister the browser-standard initiator types, including currently undocumented values such as worker, icon, frame, object, ping, or track. Values outside the recognized browser set must still map to resource.other.resource.initiator_typepackages/browser-utils/src/metrics/browserMetrics.ts
        XSMediumHTTPnavigation.redirectKeep navigation.redirect and add it to conventionsMissingRedirect timing is a stable navigation category worth retaining as its own operation.navigation.type=redirectpackages/browser/src/tracing/browserTracingIntegration.ts
        XSMediumStorageobject.get|head|put|delete|list|upload_part|multipart_upload.abort|create|completeKeep object.* and add an object-storage category to conventionsMissingUnlike framework suffixes, these are a finite, provider-neutral API taxonomy for a domain not represented by current conventions. If a smaller taxonomy is preferred, normalize to object.read/write/delete before registration.cloud provider and bucket/object identity remain attributespackages/cloudflare/src/instrumentations/worker/instrumentR2.ts
        XSMediumUIui.mount / ui.update / ui.unmountAdd ui.mount, ui.update, and ui.unmount to conventions; ui.render already existsGeneric lifecycle leaves are incompleteThese are framework-neutral replacement targets for equivalent React, Vue, and Svelte lifecycle work.ui.framework; ui.component_name; ui.lifecycle_phasepackages/react/src/profiler.tsx
        packages/vue/src/tracing.ts
        packages/svelte/src/performance.ts
        XSMediumUIui.webvital.lcp / ui.webvital.clsKeep and add both to conventionsMissingThese are fixed, cross-framework browser concepts. They are better convention candidates than framework-specific lifecycle leaves.web_vital.name and measurement value remain authoritativepackages/browser-utils/src/metrics/lcp.ts
        packages/browser-utils/src/metrics/cls.ts
        packages/browser-utils/src/metrics/webVitalSpans.ts
        XLHighGen AIgen_ai.embeddings / gen_ai.generate_content / gen_ai.rerankembeddings / generate_content / rerankMissingThese are fixed, provider-neutral, semantically distinct model operations. Add their unprefixed forms to conventions, then migrate SDK emission consistently.gen_ai.operation.name and gen_ai.operation.typepackages/core/src/tracing/langchain/embeddings.ts
        packages/core/src/tracing/openai/index.ts
        packages/core/src/tracing/google-genai/index.ts
        packages/core/src/tracing/workers-ai/index.ts
        packages/core/src/tracing/vercel-ai/index.ts
        packages/server-utils/src/integrations/tracing-channel/openai.ts
        packages/server-utils/src/integrations/tracing-channel/google-genai.ts
        packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts

        Replace with another op

        Note: The additive "gap" rows — adding a sentry.op to spans that currently emit none, which is not breaking — were split out into #23138 (rate-limit, DO WebSocket, DataLoader prime/clear/clearAll, GraphQL, generic-pool, Effect). The row numbering below therefore skips 21–23.

        Row #EffortPriorityCategoryCurrent op(s)Replacement or conventions actionRegistry statusRationale / other findingsPreserve detail inProduction locations
        1SHighFaaShttp.request (Firebase Functions)function.gcphttp.request missingThe wrapper instruments all Firebase function trigger types, not only HTTP. A fixed http.request op is semantically wrong.faas.trigger already exists; keep faas.provider=firebasepackages/node/src/integrations/tracing/firebase/otel/patches/functions.ts
        2SHighHTTPhttp.client.${serviceIdentifier}http.clientDynamic suffix missingService identity belongs in attributes; endpoint-derived suffixes fragment grouping and can be high-cardinality.rpc.service or server.address / cloud.service.namepackages/google-cloud-serverless/src/integrations/google-cloud-http.ts
        3SHighHTTPhttp.client.prefetch / http.server.prefetchhttp.client / http.serverMissing; base ops existOTel inference fabricates unregistered suffixes. Preserve direction and move prefetch to data.sentry.http.prefetch=truepackages/opentelemetry/src/utils/parseSpanDescription.ts
        4SHighMessagingfaas.queue plus sentry.op=queue.process on one spanqueue.process onlyqueue.process exact; faas.queue missingCloudflare passes conflicting values. The sentry.op attribute wins, so faas.queue is effectively dead and should be removed.packages/cloudflare/src/instrumentations/worker/instrumentQueue.ts
        5SHighRPCgrpc.${serviceIdentifier}grpcDynamic suffix missingService identity can be high-cardinality and already has standard RPC attributes.rpc.service; rpc.methodpackages/google-cloud-serverless/src/integrations/google-cloud-grpc.ts
        6SHighUIui.angular.init / ui.angular.${methodKey}ui.mount for init; function for TraceMethodParent ui.angular existsThe method-key suffix is user-controlled and unbounded. Component initialization is a mount; arbitrary decorated methods are functions.ui.framework=angular; code.function.namepackages/angular/src/tracing.ts
        7SHighUIui.ember.route.before_model|model|after_model|setup_controllerfunctionMissingThese are route-hook functions. The hook name is already available and should not be encoded in sentry.op.code.function.name; ember.route.hookpackages/ember/addon/index.ts
        8SHighUIui.ember.runloop.${queue}ui.taskMissing; ui.task existsQueue values are phase details and Ember can be configured with custom queues.ui.framework=ember; ember.runloop.queuepackages/ember/addon/utils/instrumentEmberGlobals.ts
        9SMediumBrowserpaintbrowser.paintbrowser.paint existsRename the raw paint operation to the registered browser-specific operation.Keep the PerformanceEntry name in the span namepackages/browser-utils/src/metrics/browserMetrics.ts
        10SMediumFaaSfunction.aws.lambdafunction.awsfunction.aws existsLambda is already implied by provider/runtime attributes; use the registered provider-level operation.faas.name; cloud.provider=aws; cloud.platform=aws_lambdapackages/aws-serverless/src/requestSpanOptions.ts
        11SMediumHTTPhttp.client.streamhttp.clientMissing; parent existsStreaming changes response behavior but not the HTTP operation category.http.response.body.streaming=truepackages/browser/src/integrations/fetchStreamPerformance.ts
        12SMediumUIui.ember.component.render / component.definition / initui.render / function / ui.mountOnly parent ui.ember existsMap render and initialization to cross-framework lifecycle ops. Component definition lookup is generic function work.ui.framework=ember; ui.component_name; code.function.namepackages/ember/addon/utils/instrumentEmberGlobals.ts
        13MHighCachecache.has_item|get_item|get_item_raw|get_items|get_keys|set_item|set_item_raw|set_items|remove_item|clearcache.get / cache.put / cache.removeOnly target ops existThis is the exact over-granularity the cache conventions avoid. Map has/get/list to get; set variants to put; remove/clear to remove.db.operation.name already preserves the unstorage methodpackages/nuxt/src/runtime/utils/instrumentStorage.ts
        packages/nitro/src/runtime/hooks/captureStorageEvents.ts
        14MHighDatabasedb.redis / db.redis.connectdb.query for commands; db for connectMissing; db and db.query existThe datastore belongs in db.system.name. Library/system-specific op leaves are redundant.db.system.name=redis; db.operation.namepackages/server-utils/src/redis/redis-dc-subscriber.ts
        packages/server-utils/src/integrations/tracing-channel/redis.ts
        15MHighFaaSfaas.cron / faas.email / function.step.dofunctionMissingCloudflare trigger/workflow phase belongs in attributes. Do not add a new op per trigger.faas.trigger=timer|email; code.function.name; workflow.step.namepackages/cloudflare/src/instrumentations/worker/instrumentScheduled.ts
        packages/cloudflare/src/instrumentations/worker/instrumentEmail.ts
        packages/cloudflare/src/workflows.ts
        16MHighFaaSfaas.trigger.toString() inferred as opInfer function.<provider>, http.server, or queue.process from semantic evidenceArbitrary valuesOTel inference currently promotes an attribute value directly into sentry.op. Custom trigger strings can create unbounded ops.Retain faas.trigger as data; never use it verbatim as oppackages/opentelemetry/src/utils/parseSpanDescription.ts
        17MHighGen AIrpc on AWS Bedrock inference spanschat or generate_contentrpc exists but is semantically wrong hereBedrock adds GenAI attributes but inherits the generic AWS SDK rpc op. Select the GenAI operation from the Bedrock request type.packages/server-utils/src/integrations/tracing-channel/aws-sdk/index.ts
        packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/bedrock-runtime.ts
        18MHighMiddlewareapp_creation.nestjs / request_context.nestjs / event.nestjs / plugin.hapifunctionMissingThese represent executable functions or setup work. Keep lifecycle/event/plugin identity in attributes.code.function.name; nestjs.type; hapi.type; event.namepackages/nestjs/src/integrations/wrap-route.ts
        packages/nestjs/src/integrations/helpers.ts
        packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
        packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
        19MHighRPCrpc.server / mcp.server / mcp.notification.client_to_server|server_to_clientrpcOnly rpc existsMCP is JSON-RPC and tRPC is RPC. Direction, method, notification kind, and protocol belong in attributes rather than op suffixes.rpc.system=mcp|trpc; rpc.method; jsonrpc.*; messaging directionpackages/core/src/trpc.ts
        packages/core/src/integrations/mcp-server/spans.ts
        packages/core/src/integrations/mcp-server/attributes.ts
        20MMediumFaaSfunction.gcp.http / event / cloud_eventfunction.gcpfunction.gcp existsTrigger type belongs in faas.trigger. The existing suffixes split one provider category.faas.triggerpackages/google-cloud-serverless/src/gcpfunction/http.ts
        packages/google-cloud-serverless/src/gcpfunction/events.ts
        packages/google-cloud-serverless/src/gcpfunction/cloud_events.ts
        24LHighGen AIgen_ai.create_agent / gen_ai.models / gen_ai.unknown / ai.runfunction for create/models/unknown fallback; map ai.run to a known AI op when evidence existsMissingAgent compilation and model metadata calls are not inference operations. Unknown strings should not become conventions. Vercel AI's fallback should use an explicit mapping or a generic function op.gen_ai.operation.name; code.function.name; retain provider SDK methodpackages/core/src/tracing/langgraph/index.ts
        packages/core/src/tracing/anthropic-ai/index.ts
        packages/core/src/tracing/openai/index.ts
        packages/core/src/tracing/vercel-ai/index.ts
        25LHighMessagingmessage / message.produce / message.consumequeue.publish / queue.receive / queue.processmessage* missing; queue.* existsKafka, AMQP, and Deno use a parallel non-convention taxonomy. Use messaging.operation.type to distinguish publish, receive, and process. Deno must not infer all ops from SpanKind alone.messaging.system; messaging.operation.typepackages/server-utils/src/integrations/tracing-channel/kafkajs/spans.ts
        packages/server-utils/src/integrations/tracing-channel/amqplib.ts
        packages/opentelemetry/src/utils/parseSpanDescription.ts
        packages/deno/src/opentelemetry/tracer.ts
        26LHighMiddlewarerequest_handler.<library> / handler.nestjs / hono.requestfunction; use http.server only for a true inbound/internal HTTP boundaryMissingTerminal framework handlers are functions, not new op categories. Hono app.request() is an in-process HTTP dispatch and should use http.server with HTTP attributes.code.function.name; framework handler type; HTTP attributes for Hono dispatchpackages/core/src/integrations/express/patch-layer.ts
        packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
        packages/node/src/integrations/tracing/connect/vendored/instrumentation.ts
        packages/node/src/integrations/tracing/hono/index.ts
        packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts
        packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts
        packages/elysia/src/withElysia.ts
        packages/nestjs/src/integrations/wrap-route.ts
        packages/hono/src/shared/patchAppRequest.ts
        27LHighMiddlewarerouter.express / router.koa / router.hapirouter (conventions addition tracked in the first table)router is currently missingBackend router layers should share one framework-neutral operation. They are semantically distinct from generic middleware.code.namespace or framework; router.name; route attributespackages/core/src/integrations/express/patch-layer.ts
        packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
        packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
        packages/server-utils/src/integrations/tracing-channel/koa.ts
        packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
        packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
        28LMediumUIui.angular.routing / ui.sveltekit.routing / ui.ember.transitionrouter (conventions addition tracked in the first table)router must be added to conventionsAll three measure router execution. Collapse framework identity while keeping router work distinct from the broader navigation root.ui.framework; navigation.phasepackages/angular/src/tracing.ts
        packages/sveltekit/src/client/svelte4BrowserTracing.ts
        packages/sveltekit/src/client/svelte5BrowserTracing.ts
        packages/ember/addon/utils/instrumentEmberAppInstanceForPerformance.ts
        29LMediumUIui.react.* / ui.vue.* / ui.svelte.* lifecycle opsui.mount / ui.render / ui.update / ui.unmount (missing generic leaves tracked in the first table)React leaves exist; generic leaves are incompletePreferred cleanup: normalize equivalent lifecycle work across frameworks. Current values include React mount/render/update; Vue render/activate/create/unmount/destroy/mount/update; Svelte init/update. Keeping React-specific leaves while collapsing other frameworks would preserve an arbitrary asymmetry.ui.framework; ui.component_name; ui.lifecycle_phasepackages/react/src/profiler.tsx
        packages/vue/src/tracing.ts
        packages/svelte/src/performance.ts
        30XLHighFramework functionsfunction.<framework>(.<phase>) and loader.remix / action.remixfunctionfunction exists; function.nextjs/remix are legacy leavesCollapse all framework and phase suffixes. This also resolves Remix's three competing loader/action taxonomies. Includes Next.js, Remix, React Router client/server, SvelteKit client/server, SolidStart, TanStack Start, and Cloudflare workflow steps.code.function.name; code.namespace; framework-specific phase/type attributespackages/nextjs/src/common/utils/tracingUtils.ts
        packages/nextjs/src/common/withServerActionInstrumentation.ts
        packages/remix/src/server/instrumentServer.ts
        packages/remix/src/server/integrations/tracing-channel.ts
        packages/remix/src/server/integrations/opentelemetry.ts
        packages/react-router/src/server/createServerInstrumentation.ts
        packages/react-router/src/server/wrapServerLoader.ts
        packages/react-router/src/server/wrapServerAction.ts
        packages/react-router/src/server/instrumentation/reactRouter.ts
        packages/react-router/src/server/instrumentation/util.ts
        packages/react-router/src/client/createClientInstrumentation.ts
        packages/react-router/src/client/hydratedRouter.ts
        packages/sveltekit/src/client/load.ts
        packages/sveltekit/src/server-common/load.ts
        packages/sveltekit/src/server-common/serverRoute.ts
        packages/sveltekit/src/server-common/integrations/svelteKitSpans.ts
        packages/solidstart/src/server/withServerActionInstrumentation.ts
        packages/tanstackstart-react/src/server/wrapFetchWithSentry.ts
        packages/cloudflare/src/workflows.ts
        31XLHighGen AIgen_ai.chat / gen_ai.execute_tool / gen_ai.invoke_agentchat / execute_tool / invoke_agentRegistry values are unprefixedThe SDK and source-of-truth registry disagree. Migrate to the exact convention values, or explicitly change the registry—but do not leave both. Before migration, replace SDK internals which identify AI spans via op.startsWith('gen_ai.') with gen_ai.operation.type/name.gen_ai.operation.name and gen_ai.operation.typepackages/core/src/tracing/langchain/index.ts
        packages/core/src/tracing/langgraph/index.ts
        packages/core/src/tracing/langgraph/utils.ts
        packages/core/src/tracing/openai/index.ts
        packages/core/src/tracing/anthropic-ai/index.ts
        packages/core/src/tracing/google-genai/index.ts
        packages/core/src/tracing/workers-ai/index.ts
        packages/core/src/tracing/vercel-ai/index.ts
        packages/server-utils/src/integrations/tracing-channel/openai.ts
        packages/server-utils/src/integrations/tracing-channel/anthropic.ts
        packages/server-utils/src/integrations/tracing-channel/google-genai.ts
        packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts
        32XLHighMiddlewaremiddleware.<library> / hook.fastify / http.server.middlewaremiddlewaremiddleware existsCollapse framework identity for middleware and request-pipeline hooks. Router layers are handled separately as router.code.namespace or framework; middleware.type; middleware.namepackages/core/src/integrations/express/patch-layer.ts
        packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
        packages/node/src/integrations/tracing/connect/vendored/instrumentation.ts
        packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
        packages/server-utils/src/integrations/tracing-channel/koa.ts
        packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
        packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
        packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts
        packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts
        packages/node/src/integrations/tracing/hono/index.ts
        packages/hono/src/shared/wrapMiddlewareSpan.ts
        packages/elysia/src/withElysia.ts
        packages/nestjs/src/integrations/helpers.ts
        packages/nuxt/src/runtime/hooks/wrapMiddlewareHandler.ts
        packages/nitro/src/runtime/hooks/captureTracingEvents.ts
        packages/tanstackstart-react/src/server/utils.ts
        packages/nextjs/src/common/wrapMiddlewareWithSentry.ts
        packages/nextjs/src/common/enhanceMiddlewareRootSpan.ts
        packages/nextjs/src/server/enhanceHandleRequestRootSpan.ts
        packages/nextjs/src/edge/index.ts

        Activity

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

        Metadata

        Metadata

        Assignees

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
          Skip to content

          Clean up span operations #22446

          Description

          @Lms24

          Description

          Currently, many of our instrumentations send span ops that are not defined in conventions. This has two reasons:

          1. The span op is simply still missing in conventions and needs to be added
          2. SDKs sent suboptimal, maybe, too fragmented ops. For example, ops that include the framework or library name (e.g. middleware.express or function.sveltekit). Ops should be a bit more general than that.

          I (okay, mostly my clanker, followed by a manual review) audited our instrumentations and these are the places we should make changes to:

          Add to conventions

          EffortPriorityCategoryCurrent op(s)Replacement or conventions actionRegistry statusRationale / other findingsPreserve detail inProduction locations
          XSHighRoutingrouterAdd generic router to conventionsMissingThis is the common framework-neutral replacement target for frontend and backend router spans. Router work is distinct from both navigation roots and generic middleware.ui.framework; navigation.phase; code.namespace or framework; router.name; route attributespackages/angular/src/tracing.ts
          packages/sveltekit/src/client/svelte4BrowserTracing.ts
          packages/sveltekit/src/client/svelte5BrowserTracing.ts
          packages/ember/addon/utils/instrumentEmberAppInstanceForPerformance.ts
          packages/core/src/integrations/express/patch-layer.ts
          packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
          packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
          packages/server-utils/src/integrations/tracing-channel/koa.ts
          packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
          packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
          XSHighUIui.interaction.click|hover|drag|pressKeep ui.interaction.* and add all four leaves to conventionsMissingEvent Timing and INP interaction spans remain distinct from ui.action roots. Register click, hover, drag, and press as the finite interaction taxonomy.Keep DOM event type and INP metric identity as attributespackages/browser-utils/src/metrics/browserMetrics.ts
          packages/browser-utils/src/metrics/inp.ts
          packages/browser-utils/src/metrics/webVitalSpans.ts
          packages/browser/src/tracing/browserTracingIntegration.ts
          XSHighUIui.long-task / ui.long-animation-frameKeep both operations and add them to conventionsMissing; ui.task is not equivalentLong Task and Long Animation Frame are distinct browser performance APIs. The generic ui.task operation is not a semantic replacement.browser.performance.entry_type=long-task|long-animation-framepackages/browser-utils/src/metrics/browserMetrics.ts
          XSMediumBrowserbrowser.${timingPhase}Keep the browser timing-phase ops and add them to conventionsOnly browser is currently registeredCurrent finite values include browser.unloadEvent, redirect, domContentLoadedEvent, loadEvent, connect, TLS/SSL, cache, DNS, request, and response. These phases remain useful as distinct operations.Keep browser.performance.phase as complementary detailpackages/browser-utils/src/metrics/browserMetrics.ts
          XSMediumBrowsermeasureKeep measure and add it to conventionsMissingPerformanceMeasure is a distinct, fixed, useful category.Keep the PerformanceEntry name in the span namepackages/browser-utils/src/metrics/browserMetrics.ts
          XSMediumBrowserresource.${initiatorType}Keep initiator-type leaves, add them to conventions, and retain resource.other as fallbackPartially registeredRegister the browser-standard initiator types, including currently undocumented values such as worker, icon, frame, object, ping, or track. Values outside the recognized browser set must still map to resource.other.resource.initiator_typepackages/browser-utils/src/metrics/browserMetrics.ts
          XSMediumHTTPnavigation.redirectKeep navigation.redirect and add it to conventionsMissingRedirect timing is a stable navigation category worth retaining as its own operation.navigation.type=redirectpackages/browser/src/tracing/browserTracingIntegration.ts
          XSMediumStorageobject.get|head|put|delete|list|upload_part|multipart_upload.abort|create|completeKeep object.* and add an object-storage category to conventionsMissingUnlike framework suffixes, these are a finite, provider-neutral API taxonomy for a domain not represented by current conventions. If a smaller taxonomy is preferred, normalize to object.read/write/delete before registration.cloud provider and bucket/object identity remain attributespackages/cloudflare/src/instrumentations/worker/instrumentR2.ts
          XSMediumUIui.mount / ui.update / ui.unmountAdd ui.mount, ui.update, and ui.unmount to conventions; ui.render already existsGeneric lifecycle leaves are incompleteThese are framework-neutral replacement targets for equivalent React, Vue, and Svelte lifecycle work.ui.framework; ui.component_name; ui.lifecycle_phasepackages/react/src/profiler.tsx
          packages/vue/src/tracing.ts
          packages/svelte/src/performance.ts
          XSMediumUIui.webvital.lcp / ui.webvital.clsKeep and add both to conventionsMissingThese are fixed, cross-framework browser concepts. They are better convention candidates than framework-specific lifecycle leaves.web_vital.name and measurement value remain authoritativepackages/browser-utils/src/metrics/lcp.ts
          packages/browser-utils/src/metrics/cls.ts
          packages/browser-utils/src/metrics/webVitalSpans.ts
          XLHighGen AIgen_ai.embeddings / gen_ai.generate_content / gen_ai.rerankembeddings / generate_content / rerankMissingThese are fixed, provider-neutral, semantically distinct model operations. Add their unprefixed forms to conventions, then migrate SDK emission consistently.gen_ai.operation.name and gen_ai.operation.typepackages/core/src/tracing/langchain/embeddings.ts
          packages/core/src/tracing/openai/index.ts
          packages/core/src/tracing/google-genai/index.ts
          packages/core/src/tracing/workers-ai/index.ts
          packages/core/src/tracing/vercel-ai/index.ts
          packages/server-utils/src/integrations/tracing-channel/openai.ts
          packages/server-utils/src/integrations/tracing-channel/google-genai.ts
          packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts

          Replace with another op

          Note: The additive "gap" rows — adding a sentry.op to spans that currently emit none, which is not breaking — were split out into #23138 (rate-limit, DO WebSocket, DataLoader prime/clear/clearAll, GraphQL, generic-pool, Effect). The row numbering below therefore skips 21–23.

          Row #EffortPriorityCategoryCurrent op(s)Replacement or conventions actionRegistry statusRationale / other findingsPreserve detail inProduction locations
          1SHighFaaShttp.request (Firebase Functions)function.gcphttp.request missingThe wrapper instruments all Firebase function trigger types, not only HTTP. A fixed http.request op is semantically wrong.faas.trigger already exists; keep faas.provider=firebasepackages/node/src/integrations/tracing/firebase/otel/patches/functions.ts
          2SHighHTTPhttp.client.${serviceIdentifier}http.clientDynamic suffix missingService identity belongs in attributes; endpoint-derived suffixes fragment grouping and can be high-cardinality.rpc.service or server.address / cloud.service.namepackages/google-cloud-serverless/src/integrations/google-cloud-http.ts
          3SHighHTTPhttp.client.prefetch / http.server.prefetchhttp.client / http.serverMissing; base ops existOTel inference fabricates unregistered suffixes. Preserve direction and move prefetch to data.sentry.http.prefetch=truepackages/opentelemetry/src/utils/parseSpanDescription.ts
          4SHighMessagingfaas.queue plus sentry.op=queue.process on one spanqueue.process onlyqueue.process exact; faas.queue missingCloudflare passes conflicting values. The sentry.op attribute wins, so faas.queue is effectively dead and should be removed.packages/cloudflare/src/instrumentations/worker/instrumentQueue.ts
          5SHighRPCgrpc.${serviceIdentifier}grpcDynamic suffix missingService identity can be high-cardinality and already has standard RPC attributes.rpc.service; rpc.methodpackages/google-cloud-serverless/src/integrations/google-cloud-grpc.ts
          6SHighUIui.angular.init / ui.angular.${methodKey}ui.mount for init; function for TraceMethodParent ui.angular existsThe method-key suffix is user-controlled and unbounded. Component initialization is a mount; arbitrary decorated methods are functions.ui.framework=angular; code.function.namepackages/angular/src/tracing.ts
          7SHighUIui.ember.route.before_model|model|after_model|setup_controllerfunctionMissingThese are route-hook functions. The hook name is already available and should not be encoded in sentry.op.code.function.name; ember.route.hookpackages/ember/addon/index.ts
          8SHighUIui.ember.runloop.${queue}ui.taskMissing; ui.task existsQueue values are phase details and Ember can be configured with custom queues.ui.framework=ember; ember.runloop.queuepackages/ember/addon/utils/instrumentEmberGlobals.ts
          9SMediumBrowserpaintbrowser.paintbrowser.paint existsRename the raw paint operation to the registered browser-specific operation.Keep the PerformanceEntry name in the span namepackages/browser-utils/src/metrics/browserMetrics.ts
          10SMediumFaaSfunction.aws.lambdafunction.awsfunction.aws existsLambda is already implied by provider/runtime attributes; use the registered provider-level operation.faas.name; cloud.provider=aws; cloud.platform=aws_lambdapackages/aws-serverless/src/requestSpanOptions.ts
          11SMediumHTTPhttp.client.streamhttp.clientMissing; parent existsStreaming changes response behavior but not the HTTP operation category.http.response.body.streaming=truepackages/browser/src/integrations/fetchStreamPerformance.ts
          12SMediumUIui.ember.component.render / component.definition / initui.render / function / ui.mountOnly parent ui.ember existsMap render and initialization to cross-framework lifecycle ops. Component definition lookup is generic function work.ui.framework=ember; ui.component_name; code.function.namepackages/ember/addon/utils/instrumentEmberGlobals.ts
          13MHighCachecache.has_item|get_item|get_item_raw|get_items|get_keys|set_item|set_item_raw|set_items|remove_item|clearcache.get / cache.put / cache.removeOnly target ops existThis is the exact over-granularity the cache conventions avoid. Map has/get/list to get; set variants to put; remove/clear to remove.db.operation.name already preserves the unstorage methodpackages/nuxt/src/runtime/utils/instrumentStorage.ts
          packages/nitro/src/runtime/hooks/captureStorageEvents.ts
          14MHighDatabasedb.redis / db.redis.connectdb.query for commands; db for connectMissing; db and db.query existThe datastore belongs in db.system.name. Library/system-specific op leaves are redundant.db.system.name=redis; db.operation.namepackages/server-utils/src/redis/redis-dc-subscriber.ts
          packages/server-utils/src/integrations/tracing-channel/redis.ts
          15MHighFaaSfaas.cron / faas.email / function.step.dofunctionMissingCloudflare trigger/workflow phase belongs in attributes. Do not add a new op per trigger.faas.trigger=timer|email; code.function.name; workflow.step.namepackages/cloudflare/src/instrumentations/worker/instrumentScheduled.ts
          packages/cloudflare/src/instrumentations/worker/instrumentEmail.ts
          packages/cloudflare/src/workflows.ts
          16MHighFaaSfaas.trigger.toString() inferred as opInfer function.<provider>, http.server, or queue.process from semantic evidenceArbitrary valuesOTel inference currently promotes an attribute value directly into sentry.op. Custom trigger strings can create unbounded ops.Retain faas.trigger as data; never use it verbatim as oppackages/opentelemetry/src/utils/parseSpanDescription.ts
          17MHighGen AIrpc on AWS Bedrock inference spanschat or generate_contentrpc exists but is semantically wrong hereBedrock adds GenAI attributes but inherits the generic AWS SDK rpc op. Select the GenAI operation from the Bedrock request type.packages/server-utils/src/integrations/tracing-channel/aws-sdk/index.ts
          packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/bedrock-runtime.ts
          18MHighMiddlewareapp_creation.nestjs / request_context.nestjs / event.nestjs / plugin.hapifunctionMissingThese represent executable functions or setup work. Keep lifecycle/event/plugin identity in attributes.code.function.name; nestjs.type; hapi.type; event.namepackages/nestjs/src/integrations/wrap-route.ts
          packages/nestjs/src/integrations/helpers.ts
          packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
          packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
          19MHighRPCrpc.server / mcp.server / mcp.notification.client_to_server|server_to_clientrpcOnly rpc existsMCP is JSON-RPC and tRPC is RPC. Direction, method, notification kind, and protocol belong in attributes rather than op suffixes.rpc.system=mcp|trpc; rpc.method; jsonrpc.*; messaging directionpackages/core/src/trpc.ts
          packages/core/src/integrations/mcp-server/spans.ts
          packages/core/src/integrations/mcp-server/attributes.ts
          20MMediumFaaSfunction.gcp.http / event / cloud_eventfunction.gcpfunction.gcp existsTrigger type belongs in faas.trigger. The existing suffixes split one provider category.faas.triggerpackages/google-cloud-serverless/src/gcpfunction/http.ts
          packages/google-cloud-serverless/src/gcpfunction/events.ts
          packages/google-cloud-serverless/src/gcpfunction/cloud_events.ts
          24LHighGen AIgen_ai.create_agent / gen_ai.models / gen_ai.unknown / ai.runfunction for create/models/unknown fallback; map ai.run to a known AI op when evidence existsMissingAgent compilation and model metadata calls are not inference operations. Unknown strings should not become conventions. Vercel AI's fallback should use an explicit mapping or a generic function op.gen_ai.operation.name; code.function.name; retain provider SDK methodpackages/core/src/tracing/langgraph/index.ts
          packages/core/src/tracing/anthropic-ai/index.ts
          packages/core/src/tracing/openai/index.ts
          packages/core/src/tracing/vercel-ai/index.ts
          25LHighMessagingmessage / message.produce / message.consumequeue.publish / queue.receive / queue.processmessage* missing; queue.* existsKafka, AMQP, and Deno use a parallel non-convention taxonomy. Use messaging.operation.type to distinguish publish, receive, and process. Deno must not infer all ops from SpanKind alone.messaging.system; messaging.operation.typepackages/server-utils/src/integrations/tracing-channel/kafkajs/spans.ts
          packages/server-utils/src/integrations/tracing-channel/amqplib.ts
          packages/opentelemetry/src/utils/parseSpanDescription.ts
          packages/deno/src/opentelemetry/tracer.ts
          26LHighMiddlewarerequest_handler.<library> / handler.nestjs / hono.requestfunction; use http.server only for a true inbound/internal HTTP boundaryMissingTerminal framework handlers are functions, not new op categories. Hono app.request() is an in-process HTTP dispatch and should use http.server with HTTP attributes.code.function.name; framework handler type; HTTP attributes for Hono dispatchpackages/core/src/integrations/express/patch-layer.ts
          packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
          packages/node/src/integrations/tracing/connect/vendored/instrumentation.ts
          packages/node/src/integrations/tracing/hono/index.ts
          packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts
          packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts
          packages/elysia/src/withElysia.ts
          packages/nestjs/src/integrations/wrap-route.ts
          packages/hono/src/shared/patchAppRequest.ts
          27LHighMiddlewarerouter.express / router.koa / router.hapirouter (conventions addition tracked in the first table)router is currently missingBackend router layers should share one framework-neutral operation. They are semantically distinct from generic middleware.code.namespace or framework; router.name; route attributespackages/core/src/integrations/express/patch-layer.ts
          packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
          packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
          packages/server-utils/src/integrations/tracing-channel/koa.ts
          packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
          packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
          28LMediumUIui.angular.routing / ui.sveltekit.routing / ui.ember.transitionrouter (conventions addition tracked in the first table)router must be added to conventionsAll three measure router execution. Collapse framework identity while keeping router work distinct from the broader navigation root.ui.framework; navigation.phasepackages/angular/src/tracing.ts
          packages/sveltekit/src/client/svelte4BrowserTracing.ts
          packages/sveltekit/src/client/svelte5BrowserTracing.ts
          packages/ember/addon/utils/instrumentEmberAppInstanceForPerformance.ts
          29LMediumUIui.react.* / ui.vue.* / ui.svelte.* lifecycle opsui.mount / ui.render / ui.update / ui.unmount (missing generic leaves tracked in the first table)React leaves exist; generic leaves are incompletePreferred cleanup: normalize equivalent lifecycle work across frameworks. Current values include React mount/render/update; Vue render/activate/create/unmount/destroy/mount/update; Svelte init/update. Keeping React-specific leaves while collapsing other frameworks would preserve an arbitrary asymmetry.ui.framework; ui.component_name; ui.lifecycle_phasepackages/react/src/profiler.tsx
          packages/vue/src/tracing.ts
          packages/svelte/src/performance.ts
          30XLHighFramework functionsfunction.<framework>(.<phase>) and loader.remix / action.remixfunctionfunction exists; function.nextjs/remix are legacy leavesCollapse all framework and phase suffixes. This also resolves Remix's three competing loader/action taxonomies. Includes Next.js, Remix, React Router client/server, SvelteKit client/server, SolidStart, TanStack Start, and Cloudflare workflow steps.code.function.name; code.namespace; framework-specific phase/type attributespackages/nextjs/src/common/utils/tracingUtils.ts
          packages/nextjs/src/common/withServerActionInstrumentation.ts
          packages/remix/src/server/instrumentServer.ts
          packages/remix/src/server/integrations/tracing-channel.ts
          packages/remix/src/server/integrations/opentelemetry.ts
          packages/react-router/src/server/createServerInstrumentation.ts
          packages/react-router/src/server/wrapServerLoader.ts
          packages/react-router/src/server/wrapServerAction.ts
          packages/react-router/src/server/instrumentation/reactRouter.ts
          packages/react-router/src/server/instrumentation/util.ts
          packages/react-router/src/client/createClientInstrumentation.ts
          packages/react-router/src/client/hydratedRouter.ts
          packages/sveltekit/src/client/load.ts
          packages/sveltekit/src/server-common/load.ts
          packages/sveltekit/src/server-common/serverRoute.ts
          packages/sveltekit/src/server-common/integrations/svelteKitSpans.ts
          packages/solidstart/src/server/withServerActionInstrumentation.ts
          packages/tanstackstart-react/src/server/wrapFetchWithSentry.ts
          packages/cloudflare/src/workflows.ts
          31XLHighGen AIgen_ai.chat / gen_ai.execute_tool / gen_ai.invoke_agentchat / execute_tool / invoke_agentRegistry values are unprefixedThe SDK and source-of-truth registry disagree. Migrate to the exact convention values, or explicitly change the registry—but do not leave both. Before migration, replace SDK internals which identify AI spans via op.startsWith('gen_ai.') with gen_ai.operation.type/name.gen_ai.operation.name and gen_ai.operation.typepackages/core/src/tracing/langchain/index.ts
          packages/core/src/tracing/langgraph/index.ts
          packages/core/src/tracing/langgraph/utils.ts
          packages/core/src/tracing/openai/index.ts
          packages/core/src/tracing/anthropic-ai/index.ts
          packages/core/src/tracing/google-genai/index.ts
          packages/core/src/tracing/workers-ai/index.ts
          packages/core/src/tracing/vercel-ai/index.ts
          packages/server-utils/src/integrations/tracing-channel/openai.ts
          packages/server-utils/src/integrations/tracing-channel/anthropic.ts
          packages/server-utils/src/integrations/tracing-channel/google-genai.ts
          packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts
          32XLHighMiddlewaremiddleware.<library> / hook.fastify / http.server.middlewaremiddlewaremiddleware existsCollapse framework identity for middleware and request-pipeline hooks. Router layers are handled separately as router.code.namespace or framework; middleware.type; middleware.namepackages/core/src/integrations/express/patch-layer.ts
          packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
          packages/node/src/integrations/tracing/connect/vendored/instrumentation.ts
          packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
          packages/server-utils/src/integrations/tracing-channel/koa.ts
          packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
          packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
          packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts
          packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts
          packages/node/src/integrations/tracing/hono/index.ts
          packages/hono/src/shared/wrapMiddlewareSpan.ts
          packages/elysia/src/withElysia.ts
          packages/nestjs/src/integrations/helpers.ts
          packages/nuxt/src/runtime/hooks/wrapMiddlewareHandler.ts
          packages/nitro/src/runtime/hooks/captureTracingEvents.ts
          packages/tanstackstart-react/src/server/utils.ts
          packages/nextjs/src/common/wrapMiddlewareWithSentry.ts
          packages/nextjs/src/common/enhanceMiddlewareRootSpan.ts
          packages/nextjs/src/server/enhanceHandleRequestRootSpan.ts
          packages/nextjs/src/edge/index.ts

          Activity

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

          Metadata

          Metadata

          Assignees

          Projects

          No projects

            Milestone

            No milestone

            Relationships

            None yet

            Development

            No branches or pull requests

            Issue actions

            , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
            Skip to content

            Clean up span operations #22446

            Description

            @Lms24

            Description

            Currently, many of our instrumentations send span ops that are not defined in conventions. This has two reasons:

            1. The span op is simply still missing in conventions and needs to be added
            2. SDKs sent suboptimal, maybe, too fragmented ops. For example, ops that include the framework or library name (e.g. middleware.express or function.sveltekit). Ops should be a bit more general than that.

            I (okay, mostly my clanker, followed by a manual review) audited our instrumentations and these are the places we should make changes to:

            Add to conventions

            EffortPriorityCategoryCurrent op(s)Replacement or conventions actionRegistry statusRationale / other findingsPreserve detail inProduction locations
            XSHighRoutingrouterAdd generic router to conventionsMissingThis is the common framework-neutral replacement target for frontend and backend router spans. Router work is distinct from both navigation roots and generic middleware.ui.framework; navigation.phase; code.namespace or framework; router.name; route attributespackages/angular/src/tracing.ts
            packages/sveltekit/src/client/svelte4BrowserTracing.ts
            packages/sveltekit/src/client/svelte5BrowserTracing.ts
            packages/ember/addon/utils/instrumentEmberAppInstanceForPerformance.ts
            packages/core/src/integrations/express/patch-layer.ts
            packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
            packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
            packages/server-utils/src/integrations/tracing-channel/koa.ts
            packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
            packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
            XSHighUIui.interaction.click|hover|drag|pressKeep ui.interaction.* and add all four leaves to conventionsMissingEvent Timing and INP interaction spans remain distinct from ui.action roots. Register click, hover, drag, and press as the finite interaction taxonomy.Keep DOM event type and INP metric identity as attributespackages/browser-utils/src/metrics/browserMetrics.ts
            packages/browser-utils/src/metrics/inp.ts
            packages/browser-utils/src/metrics/webVitalSpans.ts
            packages/browser/src/tracing/browserTracingIntegration.ts
            XSHighUIui.long-task / ui.long-animation-frameKeep both operations and add them to conventionsMissing; ui.task is not equivalentLong Task and Long Animation Frame are distinct browser performance APIs. The generic ui.task operation is not a semantic replacement.browser.performance.entry_type=long-task|long-animation-framepackages/browser-utils/src/metrics/browserMetrics.ts
            XSMediumBrowserbrowser.${timingPhase}Keep the browser timing-phase ops and add them to conventionsOnly browser is currently registeredCurrent finite values include browser.unloadEvent, redirect, domContentLoadedEvent, loadEvent, connect, TLS/SSL, cache, DNS, request, and response. These phases remain useful as distinct operations.Keep browser.performance.phase as complementary detailpackages/browser-utils/src/metrics/browserMetrics.ts
            XSMediumBrowsermeasureKeep measure and add it to conventionsMissingPerformanceMeasure is a distinct, fixed, useful category.Keep the PerformanceEntry name in the span namepackages/browser-utils/src/metrics/browserMetrics.ts
            XSMediumBrowserresource.${initiatorType}Keep initiator-type leaves, add them to conventions, and retain resource.other as fallbackPartially registeredRegister the browser-standard initiator types, including currently undocumented values such as worker, icon, frame, object, ping, or track. Values outside the recognized browser set must still map to resource.other.resource.initiator_typepackages/browser-utils/src/metrics/browserMetrics.ts
            XSMediumHTTPnavigation.redirectKeep navigation.redirect and add it to conventionsMissingRedirect timing is a stable navigation category worth retaining as its own operation.navigation.type=redirectpackages/browser/src/tracing/browserTracingIntegration.ts
            XSMediumStorageobject.get|head|put|delete|list|upload_part|multipart_upload.abort|create|completeKeep object.* and add an object-storage category to conventionsMissingUnlike framework suffixes, these are a finite, provider-neutral API taxonomy for a domain not represented by current conventions. If a smaller taxonomy is preferred, normalize to object.read/write/delete before registration.cloud provider and bucket/object identity remain attributespackages/cloudflare/src/instrumentations/worker/instrumentR2.ts
            XSMediumUIui.mount / ui.update / ui.unmountAdd ui.mount, ui.update, and ui.unmount to conventions; ui.render already existsGeneric lifecycle leaves are incompleteThese are framework-neutral replacement targets for equivalent React, Vue, and Svelte lifecycle work.ui.framework; ui.component_name; ui.lifecycle_phasepackages/react/src/profiler.tsx
            packages/vue/src/tracing.ts
            packages/svelte/src/performance.ts
            XSMediumUIui.webvital.lcp / ui.webvital.clsKeep and add both to conventionsMissingThese are fixed, cross-framework browser concepts. They are better convention candidates than framework-specific lifecycle leaves.web_vital.name and measurement value remain authoritativepackages/browser-utils/src/metrics/lcp.ts
            packages/browser-utils/src/metrics/cls.ts
            packages/browser-utils/src/metrics/webVitalSpans.ts
            XLHighGen AIgen_ai.embeddings / gen_ai.generate_content / gen_ai.rerankembeddings / generate_content / rerankMissingThese are fixed, provider-neutral, semantically distinct model operations. Add their unprefixed forms to conventions, then migrate SDK emission consistently.gen_ai.operation.name and gen_ai.operation.typepackages/core/src/tracing/langchain/embeddings.ts
            packages/core/src/tracing/openai/index.ts
            packages/core/src/tracing/google-genai/index.ts
            packages/core/src/tracing/workers-ai/index.ts
            packages/core/src/tracing/vercel-ai/index.ts
            packages/server-utils/src/integrations/tracing-channel/openai.ts
            packages/server-utils/src/integrations/tracing-channel/google-genai.ts
            packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts

            Replace with another op

            Note: The additive "gap" rows — adding a sentry.op to spans that currently emit none, which is not breaking — were split out into #23138 (rate-limit, DO WebSocket, DataLoader prime/clear/clearAll, GraphQL, generic-pool, Effect). The row numbering below therefore skips 21–23.

            Row #EffortPriorityCategoryCurrent op(s)Replacement or conventions actionRegistry statusRationale / other findingsPreserve detail inProduction locations
            1SHighFaaShttp.request (Firebase Functions)function.gcphttp.request missingThe wrapper instruments all Firebase function trigger types, not only HTTP. A fixed http.request op is semantically wrong.faas.trigger already exists; keep faas.provider=firebasepackages/node/src/integrations/tracing/firebase/otel/patches/functions.ts
            2SHighHTTPhttp.client.${serviceIdentifier}http.clientDynamic suffix missingService identity belongs in attributes; endpoint-derived suffixes fragment grouping and can be high-cardinality.rpc.service or server.address / cloud.service.namepackages/google-cloud-serverless/src/integrations/google-cloud-http.ts
            3SHighHTTPhttp.client.prefetch / http.server.prefetchhttp.client / http.serverMissing; base ops existOTel inference fabricates unregistered suffixes. Preserve direction and move prefetch to data.sentry.http.prefetch=truepackages/opentelemetry/src/utils/parseSpanDescription.ts
            4SHighMessagingfaas.queue plus sentry.op=queue.process on one spanqueue.process onlyqueue.process exact; faas.queue missingCloudflare passes conflicting values. The sentry.op attribute wins, so faas.queue is effectively dead and should be removed.packages/cloudflare/src/instrumentations/worker/instrumentQueue.ts
            5SHighRPCgrpc.${serviceIdentifier}grpcDynamic suffix missingService identity can be high-cardinality and already has standard RPC attributes.rpc.service; rpc.methodpackages/google-cloud-serverless/src/integrations/google-cloud-grpc.ts
            6SHighUIui.angular.init / ui.angular.${methodKey}ui.mount for init; function for TraceMethodParent ui.angular existsThe method-key suffix is user-controlled and unbounded. Component initialization is a mount; arbitrary decorated methods are functions.ui.framework=angular; code.function.namepackages/angular/src/tracing.ts
            7SHighUIui.ember.route.before_model|model|after_model|setup_controllerfunctionMissingThese are route-hook functions. The hook name is already available and should not be encoded in sentry.op.code.function.name; ember.route.hookpackages/ember/addon/index.ts
            8SHighUIui.ember.runloop.${queue}ui.taskMissing; ui.task existsQueue values are phase details and Ember can be configured with custom queues.ui.framework=ember; ember.runloop.queuepackages/ember/addon/utils/instrumentEmberGlobals.ts
            9SMediumBrowserpaintbrowser.paintbrowser.paint existsRename the raw paint operation to the registered browser-specific operation.Keep the PerformanceEntry name in the span namepackages/browser-utils/src/metrics/browserMetrics.ts
            10SMediumFaaSfunction.aws.lambdafunction.awsfunction.aws existsLambda is already implied by provider/runtime attributes; use the registered provider-level operation.faas.name; cloud.provider=aws; cloud.platform=aws_lambdapackages/aws-serverless/src/requestSpanOptions.ts
            11SMediumHTTPhttp.client.streamhttp.clientMissing; parent existsStreaming changes response behavior but not the HTTP operation category.http.response.body.streaming=truepackages/browser/src/integrations/fetchStreamPerformance.ts
            12SMediumUIui.ember.component.render / component.definition / initui.render / function / ui.mountOnly parent ui.ember existsMap render and initialization to cross-framework lifecycle ops. Component definition lookup is generic function work.ui.framework=ember; ui.component_name; code.function.namepackages/ember/addon/utils/instrumentEmberGlobals.ts
            13MHighCachecache.has_item|get_item|get_item_raw|get_items|get_keys|set_item|set_item_raw|set_items|remove_item|clearcache.get / cache.put / cache.removeOnly target ops existThis is the exact over-granularity the cache conventions avoid. Map has/get/list to get; set variants to put; remove/clear to remove.db.operation.name already preserves the unstorage methodpackages/nuxt/src/runtime/utils/instrumentStorage.ts
            packages/nitro/src/runtime/hooks/captureStorageEvents.ts
            14MHighDatabasedb.redis / db.redis.connectdb.query for commands; db for connectMissing; db and db.query existThe datastore belongs in db.system.name. Library/system-specific op leaves are redundant.db.system.name=redis; db.operation.namepackages/server-utils/src/redis/redis-dc-subscriber.ts
            packages/server-utils/src/integrations/tracing-channel/redis.ts
            15MHighFaaSfaas.cron / faas.email / function.step.dofunctionMissingCloudflare trigger/workflow phase belongs in attributes. Do not add a new op per trigger.faas.trigger=timer|email; code.function.name; workflow.step.namepackages/cloudflare/src/instrumentations/worker/instrumentScheduled.ts
            packages/cloudflare/src/instrumentations/worker/instrumentEmail.ts
            packages/cloudflare/src/workflows.ts
            16MHighFaaSfaas.trigger.toString() inferred as opInfer function.<provider>, http.server, or queue.process from semantic evidenceArbitrary valuesOTel inference currently promotes an attribute value directly into sentry.op. Custom trigger strings can create unbounded ops.Retain faas.trigger as data; never use it verbatim as oppackages/opentelemetry/src/utils/parseSpanDescription.ts
            17MHighGen AIrpc on AWS Bedrock inference spanschat or generate_contentrpc exists but is semantically wrong hereBedrock adds GenAI attributes but inherits the generic AWS SDK rpc op. Select the GenAI operation from the Bedrock request type.packages/server-utils/src/integrations/tracing-channel/aws-sdk/index.ts
            packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/bedrock-runtime.ts
            18MHighMiddlewareapp_creation.nestjs / request_context.nestjs / event.nestjs / plugin.hapifunctionMissingThese represent executable functions or setup work. Keep lifecycle/event/plugin identity in attributes.code.function.name; nestjs.type; hapi.type; event.namepackages/nestjs/src/integrations/wrap-route.ts
            packages/nestjs/src/integrations/helpers.ts
            packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
            packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
            19MHighRPCrpc.server / mcp.server / mcp.notification.client_to_server|server_to_clientrpcOnly rpc existsMCP is JSON-RPC and tRPC is RPC. Direction, method, notification kind, and protocol belong in attributes rather than op suffixes.rpc.system=mcp|trpc; rpc.method; jsonrpc.*; messaging directionpackages/core/src/trpc.ts
            packages/core/src/integrations/mcp-server/spans.ts
            packages/core/src/integrations/mcp-server/attributes.ts
            20MMediumFaaSfunction.gcp.http / event / cloud_eventfunction.gcpfunction.gcp existsTrigger type belongs in faas.trigger. The existing suffixes split one provider category.faas.triggerpackages/google-cloud-serverless/src/gcpfunction/http.ts
            packages/google-cloud-serverless/src/gcpfunction/events.ts
            packages/google-cloud-serverless/src/gcpfunction/cloud_events.ts
            24LHighGen AIgen_ai.create_agent / gen_ai.models / gen_ai.unknown / ai.runfunction for create/models/unknown fallback; map ai.run to a known AI op when evidence existsMissingAgent compilation and model metadata calls are not inference operations. Unknown strings should not become conventions. Vercel AI's fallback should use an explicit mapping or a generic function op.gen_ai.operation.name; code.function.name; retain provider SDK methodpackages/core/src/tracing/langgraph/index.ts
            packages/core/src/tracing/anthropic-ai/index.ts
            packages/core/src/tracing/openai/index.ts
            packages/core/src/tracing/vercel-ai/index.ts
            25LHighMessagingmessage / message.produce / message.consumequeue.publish / queue.receive / queue.processmessage* missing; queue.* existsKafka, AMQP, and Deno use a parallel non-convention taxonomy. Use messaging.operation.type to distinguish publish, receive, and process. Deno must not infer all ops from SpanKind alone.messaging.system; messaging.operation.typepackages/server-utils/src/integrations/tracing-channel/kafkajs/spans.ts
            packages/server-utils/src/integrations/tracing-channel/amqplib.ts
            packages/opentelemetry/src/utils/parseSpanDescription.ts
            packages/deno/src/opentelemetry/tracer.ts
            26LHighMiddlewarerequest_handler.<library> / handler.nestjs / hono.requestfunction; use http.server only for a true inbound/internal HTTP boundaryMissingTerminal framework handlers are functions, not new op categories. Hono app.request() is an in-process HTTP dispatch and should use http.server with HTTP attributes.code.function.name; framework handler type; HTTP attributes for Hono dispatchpackages/core/src/integrations/express/patch-layer.ts
            packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
            packages/node/src/integrations/tracing/connect/vendored/instrumentation.ts
            packages/node/src/integrations/tracing/hono/index.ts
            packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts
            packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts
            packages/elysia/src/withElysia.ts
            packages/nestjs/src/integrations/wrap-route.ts
            packages/hono/src/shared/patchAppRequest.ts
            27LHighMiddlewarerouter.express / router.koa / router.hapirouter (conventions addition tracked in the first table)router is currently missingBackend router layers should share one framework-neutral operation. They are semantically distinct from generic middleware.code.namespace or framework; router.name; route attributespackages/core/src/integrations/express/patch-layer.ts
            packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
            packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
            packages/server-utils/src/integrations/tracing-channel/koa.ts
            packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
            packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
            28LMediumUIui.angular.routing / ui.sveltekit.routing / ui.ember.transitionrouter (conventions addition tracked in the first table)router must be added to conventionsAll three measure router execution. Collapse framework identity while keeping router work distinct from the broader navigation root.ui.framework; navigation.phasepackages/angular/src/tracing.ts
            packages/sveltekit/src/client/svelte4BrowserTracing.ts
            packages/sveltekit/src/client/svelte5BrowserTracing.ts
            packages/ember/addon/utils/instrumentEmberAppInstanceForPerformance.ts
            29LMediumUIui.react.* / ui.vue.* / ui.svelte.* lifecycle opsui.mount / ui.render / ui.update / ui.unmount (missing generic leaves tracked in the first table)React leaves exist; generic leaves are incompletePreferred cleanup: normalize equivalent lifecycle work across frameworks. Current values include React mount/render/update; Vue render/activate/create/unmount/destroy/mount/update; Svelte init/update. Keeping React-specific leaves while collapsing other frameworks would preserve an arbitrary asymmetry.ui.framework; ui.component_name; ui.lifecycle_phasepackages/react/src/profiler.tsx
            packages/vue/src/tracing.ts
            packages/svelte/src/performance.ts
            30XLHighFramework functionsfunction.<framework>(.<phase>) and loader.remix / action.remixfunctionfunction exists; function.nextjs/remix are legacy leavesCollapse all framework and phase suffixes. This also resolves Remix's three competing loader/action taxonomies. Includes Next.js, Remix, React Router client/server, SvelteKit client/server, SolidStart, TanStack Start, and Cloudflare workflow steps.code.function.name; code.namespace; framework-specific phase/type attributespackages/nextjs/src/common/utils/tracingUtils.ts
            packages/nextjs/src/common/withServerActionInstrumentation.ts
            packages/remix/src/server/instrumentServer.ts
            packages/remix/src/server/integrations/tracing-channel.ts
            packages/remix/src/server/integrations/opentelemetry.ts
            packages/react-router/src/server/createServerInstrumentation.ts
            packages/react-router/src/server/wrapServerLoader.ts
            packages/react-router/src/server/wrapServerAction.ts
            packages/react-router/src/server/instrumentation/reactRouter.ts
            packages/react-router/src/server/instrumentation/util.ts
            packages/react-router/src/client/createClientInstrumentation.ts
            packages/react-router/src/client/hydratedRouter.ts
            packages/sveltekit/src/client/load.ts
            packages/sveltekit/src/server-common/load.ts
            packages/sveltekit/src/server-common/serverRoute.ts
            packages/sveltekit/src/server-common/integrations/svelteKitSpans.ts
            packages/solidstart/src/server/withServerActionInstrumentation.ts
            packages/tanstackstart-react/src/server/wrapFetchWithSentry.ts
            packages/cloudflare/src/workflows.ts
            31XLHighGen AIgen_ai.chat / gen_ai.execute_tool / gen_ai.invoke_agentchat / execute_tool / invoke_agentRegistry values are unprefixedThe SDK and source-of-truth registry disagree. Migrate to the exact convention values, or explicitly change the registry—but do not leave both. Before migration, replace SDK internals which identify AI spans via op.startsWith('gen_ai.') with gen_ai.operation.type/name.gen_ai.operation.name and gen_ai.operation.typepackages/core/src/tracing/langchain/index.ts
            packages/core/src/tracing/langgraph/index.ts
            packages/core/src/tracing/langgraph/utils.ts
            packages/core/src/tracing/openai/index.ts
            packages/core/src/tracing/anthropic-ai/index.ts
            packages/core/src/tracing/google-genai/index.ts
            packages/core/src/tracing/workers-ai/index.ts
            packages/core/src/tracing/vercel-ai/index.ts
            packages/server-utils/src/integrations/tracing-channel/openai.ts
            packages/server-utils/src/integrations/tracing-channel/anthropic.ts
            packages/server-utils/src/integrations/tracing-channel/google-genai.ts
            packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts
            32XLHighMiddlewaremiddleware.<library> / hook.fastify / http.server.middlewaremiddlewaremiddleware existsCollapse framework identity for middleware and request-pipeline hooks. Router layers are handled separately as router.code.namespace or framework; middleware.type; middleware.namepackages/core/src/integrations/express/patch-layer.ts
            packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
            packages/node/src/integrations/tracing/connect/vendored/instrumentation.ts
            packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
            packages/server-utils/src/integrations/tracing-channel/koa.ts
            packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
            packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
            packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts
            packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts
            packages/node/src/integrations/tracing/hono/index.ts
            packages/hono/src/shared/wrapMiddlewareSpan.ts
            packages/elysia/src/withElysia.ts
            packages/nestjs/src/integrations/helpers.ts
            packages/nuxt/src/runtime/hooks/wrapMiddlewareHandler.ts
            packages/nitro/src/runtime/hooks/captureTracingEvents.ts
            packages/tanstackstart-react/src/server/utils.ts
            packages/nextjs/src/common/wrapMiddlewareWithSentry.ts
            packages/nextjs/src/common/enhanceMiddlewareRootSpan.ts
            packages/nextjs/src/server/enhanceHandleRequestRootSpan.ts
            packages/nextjs/src/edge/index.ts

            Activity

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

            Metadata

            Metadata

            Assignees

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
              Skip to content

              Clean up span operations #22446

              Description

              @Lms24

              Description

              Currently, many of our instrumentations send span ops that are not defined in conventions. This has two reasons:

              1. The span op is simply still missing in conventions and needs to be added
              2. SDKs sent suboptimal, maybe, too fragmented ops. For example, ops that include the framework or library name (e.g. middleware.express or function.sveltekit). Ops should be a bit more general than that.

              I (okay, mostly my clanker, followed by a manual review) audited our instrumentations and these are the places we should make changes to:

              Add to conventions

              EffortPriorityCategoryCurrent op(s)Replacement or conventions actionRegistry statusRationale / other findingsPreserve detail inProduction locations
              XSHighRoutingrouterAdd generic router to conventionsMissingThis is the common framework-neutral replacement target for frontend and backend router spans. Router work is distinct from both navigation roots and generic middleware.ui.framework; navigation.phase; code.namespace or framework; router.name; route attributespackages/angular/src/tracing.ts
              packages/sveltekit/src/client/svelte4BrowserTracing.ts
              packages/sveltekit/src/client/svelte5BrowserTracing.ts
              packages/ember/addon/utils/instrumentEmberAppInstanceForPerformance.ts
              packages/core/src/integrations/express/patch-layer.ts
              packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
              packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
              packages/server-utils/src/integrations/tracing-channel/koa.ts
              packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
              packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
              XSHighUIui.interaction.click|hover|drag|pressKeep ui.interaction.* and add all four leaves to conventionsMissingEvent Timing and INP interaction spans remain distinct from ui.action roots. Register click, hover, drag, and press as the finite interaction taxonomy.Keep DOM event type and INP metric identity as attributespackages/browser-utils/src/metrics/browserMetrics.ts
              packages/browser-utils/src/metrics/inp.ts
              packages/browser-utils/src/metrics/webVitalSpans.ts
              packages/browser/src/tracing/browserTracingIntegration.ts
              XSHighUIui.long-task / ui.long-animation-frameKeep both operations and add them to conventionsMissing; ui.task is not equivalentLong Task and Long Animation Frame are distinct browser performance APIs. The generic ui.task operation is not a semantic replacement.browser.performance.entry_type=long-task|long-animation-framepackages/browser-utils/src/metrics/browserMetrics.ts
              XSMediumBrowserbrowser.${timingPhase}Keep the browser timing-phase ops and add them to conventionsOnly browser is currently registeredCurrent finite values include browser.unloadEvent, redirect, domContentLoadedEvent, loadEvent, connect, TLS/SSL, cache, DNS, request, and response. These phases remain useful as distinct operations.Keep browser.performance.phase as complementary detailpackages/browser-utils/src/metrics/browserMetrics.ts
              XSMediumBrowsermeasureKeep measure and add it to conventionsMissingPerformanceMeasure is a distinct, fixed, useful category.Keep the PerformanceEntry name in the span namepackages/browser-utils/src/metrics/browserMetrics.ts
              XSMediumBrowserresource.${initiatorType}Keep initiator-type leaves, add them to conventions, and retain resource.other as fallbackPartially registeredRegister the browser-standard initiator types, including currently undocumented values such as worker, icon, frame, object, ping, or track. Values outside the recognized browser set must still map to resource.other.resource.initiator_typepackages/browser-utils/src/metrics/browserMetrics.ts
              XSMediumHTTPnavigation.redirectKeep navigation.redirect and add it to conventionsMissingRedirect timing is a stable navigation category worth retaining as its own operation.navigation.type=redirectpackages/browser/src/tracing/browserTracingIntegration.ts
              XSMediumStorageobject.get|head|put|delete|list|upload_part|multipart_upload.abort|create|completeKeep object.* and add an object-storage category to conventionsMissingUnlike framework suffixes, these are a finite, provider-neutral API taxonomy for a domain not represented by current conventions. If a smaller taxonomy is preferred, normalize to object.read/write/delete before registration.cloud provider and bucket/object identity remain attributespackages/cloudflare/src/instrumentations/worker/instrumentR2.ts
              XSMediumUIui.mount / ui.update / ui.unmountAdd ui.mount, ui.update, and ui.unmount to conventions; ui.render already existsGeneric lifecycle leaves are incompleteThese are framework-neutral replacement targets for equivalent React, Vue, and Svelte lifecycle work.ui.framework; ui.component_name; ui.lifecycle_phasepackages/react/src/profiler.tsx
              packages/vue/src/tracing.ts
              packages/svelte/src/performance.ts
              XSMediumUIui.webvital.lcp / ui.webvital.clsKeep and add both to conventionsMissingThese are fixed, cross-framework browser concepts. They are better convention candidates than framework-specific lifecycle leaves.web_vital.name and measurement value remain authoritativepackages/browser-utils/src/metrics/lcp.ts
              packages/browser-utils/src/metrics/cls.ts
              packages/browser-utils/src/metrics/webVitalSpans.ts
              XLHighGen AIgen_ai.embeddings / gen_ai.generate_content / gen_ai.rerankembeddings / generate_content / rerankMissingThese are fixed, provider-neutral, semantically distinct model operations. Add their unprefixed forms to conventions, then migrate SDK emission consistently.gen_ai.operation.name and gen_ai.operation.typepackages/core/src/tracing/langchain/embeddings.ts
              packages/core/src/tracing/openai/index.ts
              packages/core/src/tracing/google-genai/index.ts
              packages/core/src/tracing/workers-ai/index.ts
              packages/core/src/tracing/vercel-ai/index.ts
              packages/server-utils/src/integrations/tracing-channel/openai.ts
              packages/server-utils/src/integrations/tracing-channel/google-genai.ts
              packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts

              Replace with another op

              Note: The additive "gap" rows — adding a sentry.op to spans that currently emit none, which is not breaking — were split out into #23138 (rate-limit, DO WebSocket, DataLoader prime/clear/clearAll, GraphQL, generic-pool, Effect). The row numbering below therefore skips 21–23.

              Row #EffortPriorityCategoryCurrent op(s)Replacement or conventions actionRegistry statusRationale / other findingsPreserve detail inProduction locations
              1SHighFaaShttp.request (Firebase Functions)function.gcphttp.request missingThe wrapper instruments all Firebase function trigger types, not only HTTP. A fixed http.request op is semantically wrong.faas.trigger already exists; keep faas.provider=firebasepackages/node/src/integrations/tracing/firebase/otel/patches/functions.ts
              2SHighHTTPhttp.client.${serviceIdentifier}http.clientDynamic suffix missingService identity belongs in attributes; endpoint-derived suffixes fragment grouping and can be high-cardinality.rpc.service or server.address / cloud.service.namepackages/google-cloud-serverless/src/integrations/google-cloud-http.ts
              3SHighHTTPhttp.client.prefetch / http.server.prefetchhttp.client / http.serverMissing; base ops existOTel inference fabricates unregistered suffixes. Preserve direction and move prefetch to data.sentry.http.prefetch=truepackages/opentelemetry/src/utils/parseSpanDescription.ts
              4SHighMessagingfaas.queue plus sentry.op=queue.process on one spanqueue.process onlyqueue.process exact; faas.queue missingCloudflare passes conflicting values. The sentry.op attribute wins, so faas.queue is effectively dead and should be removed.packages/cloudflare/src/instrumentations/worker/instrumentQueue.ts
              5SHighRPCgrpc.${serviceIdentifier}grpcDynamic suffix missingService identity can be high-cardinality and already has standard RPC attributes.rpc.service; rpc.methodpackages/google-cloud-serverless/src/integrations/google-cloud-grpc.ts
              6SHighUIui.angular.init / ui.angular.${methodKey}ui.mount for init; function for TraceMethodParent ui.angular existsThe method-key suffix is user-controlled and unbounded. Component initialization is a mount; arbitrary decorated methods are functions.ui.framework=angular; code.function.namepackages/angular/src/tracing.ts
              7SHighUIui.ember.route.before_model|model|after_model|setup_controllerfunctionMissingThese are route-hook functions. The hook name is already available and should not be encoded in sentry.op.code.function.name; ember.route.hookpackages/ember/addon/index.ts
              8SHighUIui.ember.runloop.${queue}ui.taskMissing; ui.task existsQueue values are phase details and Ember can be configured with custom queues.ui.framework=ember; ember.runloop.queuepackages/ember/addon/utils/instrumentEmberGlobals.ts
              9SMediumBrowserpaintbrowser.paintbrowser.paint existsRename the raw paint operation to the registered browser-specific operation.Keep the PerformanceEntry name in the span namepackages/browser-utils/src/metrics/browserMetrics.ts
              10SMediumFaaSfunction.aws.lambdafunction.awsfunction.aws existsLambda is already implied by provider/runtime attributes; use the registered provider-level operation.faas.name; cloud.provider=aws; cloud.platform=aws_lambdapackages/aws-serverless/src/requestSpanOptions.ts
              11SMediumHTTPhttp.client.streamhttp.clientMissing; parent existsStreaming changes response behavior but not the HTTP operation category.http.response.body.streaming=truepackages/browser/src/integrations/fetchStreamPerformance.ts
              12SMediumUIui.ember.component.render / component.definition / initui.render / function / ui.mountOnly parent ui.ember existsMap render and initialization to cross-framework lifecycle ops. Component definition lookup is generic function work.ui.framework=ember; ui.component_name; code.function.namepackages/ember/addon/utils/instrumentEmberGlobals.ts
              13MHighCachecache.has_item|get_item|get_item_raw|get_items|get_keys|set_item|set_item_raw|set_items|remove_item|clearcache.get / cache.put / cache.removeOnly target ops existThis is the exact over-granularity the cache conventions avoid. Map has/get/list to get; set variants to put; remove/clear to remove.db.operation.name already preserves the unstorage methodpackages/nuxt/src/runtime/utils/instrumentStorage.ts
              packages/nitro/src/runtime/hooks/captureStorageEvents.ts
              14MHighDatabasedb.redis / db.redis.connectdb.query for commands; db for connectMissing; db and db.query existThe datastore belongs in db.system.name. Library/system-specific op leaves are redundant.db.system.name=redis; db.operation.namepackages/server-utils/src/redis/redis-dc-subscriber.ts
              packages/server-utils/src/integrations/tracing-channel/redis.ts
              15MHighFaaSfaas.cron / faas.email / function.step.dofunctionMissingCloudflare trigger/workflow phase belongs in attributes. Do not add a new op per trigger.faas.trigger=timer|email; code.function.name; workflow.step.namepackages/cloudflare/src/instrumentations/worker/instrumentScheduled.ts
              packages/cloudflare/src/instrumentations/worker/instrumentEmail.ts
              packages/cloudflare/src/workflows.ts
              16MHighFaaSfaas.trigger.toString() inferred as opInfer function.<provider>, http.server, or queue.process from semantic evidenceArbitrary valuesOTel inference currently promotes an attribute value directly into sentry.op. Custom trigger strings can create unbounded ops.Retain faas.trigger as data; never use it verbatim as oppackages/opentelemetry/src/utils/parseSpanDescription.ts
              17MHighGen AIrpc on AWS Bedrock inference spanschat or generate_contentrpc exists but is semantically wrong hereBedrock adds GenAI attributes but inherits the generic AWS SDK rpc op. Select the GenAI operation from the Bedrock request type.packages/server-utils/src/integrations/tracing-channel/aws-sdk/index.ts
              packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/bedrock-runtime.ts
              18MHighMiddlewareapp_creation.nestjs / request_context.nestjs / event.nestjs / plugin.hapifunctionMissingThese represent executable functions or setup work. Keep lifecycle/event/plugin identity in attributes.code.function.name; nestjs.type; hapi.type; event.namepackages/nestjs/src/integrations/wrap-route.ts
              packages/nestjs/src/integrations/helpers.ts
              packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
              packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
              19MHighRPCrpc.server / mcp.server / mcp.notification.client_to_server|server_to_clientrpcOnly rpc existsMCP is JSON-RPC and tRPC is RPC. Direction, method, notification kind, and protocol belong in attributes rather than op suffixes.rpc.system=mcp|trpc; rpc.method; jsonrpc.*; messaging directionpackages/core/src/trpc.ts
              packages/core/src/integrations/mcp-server/spans.ts
              packages/core/src/integrations/mcp-server/attributes.ts
              20MMediumFaaSfunction.gcp.http / event / cloud_eventfunction.gcpfunction.gcp existsTrigger type belongs in faas.trigger. The existing suffixes split one provider category.faas.triggerpackages/google-cloud-serverless/src/gcpfunction/http.ts
              packages/google-cloud-serverless/src/gcpfunction/events.ts
              packages/google-cloud-serverless/src/gcpfunction/cloud_events.ts
              24LHighGen AIgen_ai.create_agent / gen_ai.models / gen_ai.unknown / ai.runfunction for create/models/unknown fallback; map ai.run to a known AI op when evidence existsMissingAgent compilation and model metadata calls are not inference operations. Unknown strings should not become conventions. Vercel AI's fallback should use an explicit mapping or a generic function op.gen_ai.operation.name; code.function.name; retain provider SDK methodpackages/core/src/tracing/langgraph/index.ts
              packages/core/src/tracing/anthropic-ai/index.ts
              packages/core/src/tracing/openai/index.ts
              packages/core/src/tracing/vercel-ai/index.ts
              25LHighMessagingmessage / message.produce / message.consumequeue.publish / queue.receive / queue.processmessage* missing; queue.* existsKafka, AMQP, and Deno use a parallel non-convention taxonomy. Use messaging.operation.type to distinguish publish, receive, and process. Deno must not infer all ops from SpanKind alone.messaging.system; messaging.operation.typepackages/server-utils/src/integrations/tracing-channel/kafkajs/spans.ts
              packages/server-utils/src/integrations/tracing-channel/amqplib.ts
              packages/opentelemetry/src/utils/parseSpanDescription.ts
              packages/deno/src/opentelemetry/tracer.ts
              26LHighMiddlewarerequest_handler.<library> / handler.nestjs / hono.requestfunction; use http.server only for a true inbound/internal HTTP boundaryMissingTerminal framework handlers are functions, not new op categories. Hono app.request() is an in-process HTTP dispatch and should use http.server with HTTP attributes.code.function.name; framework handler type; HTTP attributes for Hono dispatchpackages/core/src/integrations/express/patch-layer.ts
              packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
              packages/node/src/integrations/tracing/connect/vendored/instrumentation.ts
              packages/node/src/integrations/tracing/hono/index.ts
              packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts
              packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts
              packages/elysia/src/withElysia.ts
              packages/nestjs/src/integrations/wrap-route.ts
              packages/hono/src/shared/patchAppRequest.ts
              27LHighMiddlewarerouter.express / router.koa / router.hapirouter (conventions addition tracked in the first table)router is currently missingBackend router layers should share one framework-neutral operation. They are semantically distinct from generic middleware.code.namespace or framework; router.name; route attributespackages/core/src/integrations/express/patch-layer.ts
              packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
              packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
              packages/server-utils/src/integrations/tracing-channel/koa.ts
              packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
              packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
              28LMediumUIui.angular.routing / ui.sveltekit.routing / ui.ember.transitionrouter (conventions addition tracked in the first table)router must be added to conventionsAll three measure router execution. Collapse framework identity while keeping router work distinct from the broader navigation root.ui.framework; navigation.phasepackages/angular/src/tracing.ts
              packages/sveltekit/src/client/svelte4BrowserTracing.ts
              packages/sveltekit/src/client/svelte5BrowserTracing.ts
              packages/ember/addon/utils/instrumentEmberAppInstanceForPerformance.ts
              29LMediumUIui.react.* / ui.vue.* / ui.svelte.* lifecycle opsui.mount / ui.render / ui.update / ui.unmount (missing generic leaves tracked in the first table)React leaves exist; generic leaves are incompletePreferred cleanup: normalize equivalent lifecycle work across frameworks. Current values include React mount/render/update; Vue render/activate/create/unmount/destroy/mount/update; Svelte init/update. Keeping React-specific leaves while collapsing other frameworks would preserve an arbitrary asymmetry.ui.framework; ui.component_name; ui.lifecycle_phasepackages/react/src/profiler.tsx
              packages/vue/src/tracing.ts
              packages/svelte/src/performance.ts
              30XLHighFramework functionsfunction.<framework>(.<phase>) and loader.remix / action.remixfunctionfunction exists; function.nextjs/remix are legacy leavesCollapse all framework and phase suffixes. This also resolves Remix's three competing loader/action taxonomies. Includes Next.js, Remix, React Router client/server, SvelteKit client/server, SolidStart, TanStack Start, and Cloudflare workflow steps.code.function.name; code.namespace; framework-specific phase/type attributespackages/nextjs/src/common/utils/tracingUtils.ts
              packages/nextjs/src/common/withServerActionInstrumentation.ts
              packages/remix/src/server/instrumentServer.ts
              packages/remix/src/server/integrations/tracing-channel.ts
              packages/remix/src/server/integrations/opentelemetry.ts
              packages/react-router/src/server/createServerInstrumentation.ts
              packages/react-router/src/server/wrapServerLoader.ts
              packages/react-router/src/server/wrapServerAction.ts
              packages/react-router/src/server/instrumentation/reactRouter.ts
              packages/react-router/src/server/instrumentation/util.ts
              packages/react-router/src/client/createClientInstrumentation.ts
              packages/react-router/src/client/hydratedRouter.ts
              packages/sveltekit/src/client/load.ts
              packages/sveltekit/src/server-common/load.ts
              packages/sveltekit/src/server-common/serverRoute.ts
              packages/sveltekit/src/server-common/integrations/svelteKitSpans.ts
              packages/solidstart/src/server/withServerActionInstrumentation.ts
              packages/tanstackstart-react/src/server/wrapFetchWithSentry.ts
              packages/cloudflare/src/workflows.ts
              31XLHighGen AIgen_ai.chat / gen_ai.execute_tool / gen_ai.invoke_agentchat / execute_tool / invoke_agentRegistry values are unprefixedThe SDK and source-of-truth registry disagree. Migrate to the exact convention values, or explicitly change the registry—but do not leave both. Before migration, replace SDK internals which identify AI spans via op.startsWith('gen_ai.') with gen_ai.operation.type/name.gen_ai.operation.name and gen_ai.operation.typepackages/core/src/tracing/langchain/index.ts
              packages/core/src/tracing/langgraph/index.ts
              packages/core/src/tracing/langgraph/utils.ts
              packages/core/src/tracing/openai/index.ts
              packages/core/src/tracing/anthropic-ai/index.ts
              packages/core/src/tracing/google-genai/index.ts
              packages/core/src/tracing/workers-ai/index.ts
              packages/core/src/tracing/vercel-ai/index.ts
              packages/server-utils/src/integrations/tracing-channel/openai.ts
              packages/server-utils/src/integrations/tracing-channel/anthropic.ts
              packages/server-utils/src/integrations/tracing-channel/google-genai.ts
              packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts
              32XLHighMiddlewaremiddleware.<library> / hook.fastify / http.server.middlewaremiddlewaremiddleware existsCollapse framework identity for middleware and request-pipeline hooks. Router layers are handled separately as router.code.namespace or framework; middleware.type; middleware.namepackages/core/src/integrations/express/patch-layer.ts
              packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
              packages/node/src/integrations/tracing/connect/vendored/instrumentation.ts
              packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
              packages/server-utils/src/integrations/tracing-channel/koa.ts
              packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
              packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
              packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts
              packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts
              packages/node/src/integrations/tracing/hono/index.ts
              packages/hono/src/shared/wrapMiddlewareSpan.ts
              packages/elysia/src/withElysia.ts
              packages/nestjs/src/integrations/helpers.ts
              packages/nuxt/src/runtime/hooks/wrapMiddlewareHandler.ts
              packages/nitro/src/runtime/hooks/captureTracingEvents.ts
              packages/tanstackstart-react/src/server/utils.ts
              packages/nextjs/src/common/wrapMiddlewareWithSentry.ts
              packages/nextjs/src/common/enhanceMiddlewareRootSpan.ts
              packages/nextjs/src/server/enhanceHandleRequestRootSpan.ts
              packages/nextjs/src/edge/index.ts

              Activity

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

              Metadata

              Metadata

              Assignees

              Projects

              No projects

                Milestone

                No milestone

                Relationships

                None yet

                Development

                No branches or pull requests

                Issue actions

                , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
                Skip to content

                Clean up span operations #22446

                Description

                @Lms24

                Description

                Currently, many of our instrumentations send span ops that are not defined in conventions. This has two reasons:

                1. The span op is simply still missing in conventions and needs to be added
                2. SDKs sent suboptimal, maybe, too fragmented ops. For example, ops that include the framework or library name (e.g. middleware.express or function.sveltekit). Ops should be a bit more general than that.

                I (okay, mostly my clanker, followed by a manual review) audited our instrumentations and these are the places we should make changes to:

                Add to conventions

                EffortPriorityCategoryCurrent op(s)Replacement or conventions actionRegistry statusRationale / other findingsPreserve detail inProduction locations
                XSHighRoutingrouterAdd generic router to conventionsMissingThis is the common framework-neutral replacement target for frontend and backend router spans. Router work is distinct from both navigation roots and generic middleware.ui.framework; navigation.phase; code.namespace or framework; router.name; route attributespackages/angular/src/tracing.ts
                packages/sveltekit/src/client/svelte4BrowserTracing.ts
                packages/sveltekit/src/client/svelte5BrowserTracing.ts
                packages/ember/addon/utils/instrumentEmberAppInstanceForPerformance.ts
                packages/core/src/integrations/express/patch-layer.ts
                packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
                packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
                packages/server-utils/src/integrations/tracing-channel/koa.ts
                packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
                packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
                XSHighUIui.interaction.click|hover|drag|pressKeep ui.interaction.* and add all four leaves to conventionsMissingEvent Timing and INP interaction spans remain distinct from ui.action roots. Register click, hover, drag, and press as the finite interaction taxonomy.Keep DOM event type and INP metric identity as attributespackages/browser-utils/src/metrics/browserMetrics.ts
                packages/browser-utils/src/metrics/inp.ts
                packages/browser-utils/src/metrics/webVitalSpans.ts
                packages/browser/src/tracing/browserTracingIntegration.ts
                XSHighUIui.long-task / ui.long-animation-frameKeep both operations and add them to conventionsMissing; ui.task is not equivalentLong Task and Long Animation Frame are distinct browser performance APIs. The generic ui.task operation is not a semantic replacement.browser.performance.entry_type=long-task|long-animation-framepackages/browser-utils/src/metrics/browserMetrics.ts
                XSMediumBrowserbrowser.${timingPhase}Keep the browser timing-phase ops and add them to conventionsOnly browser is currently registeredCurrent finite values include browser.unloadEvent, redirect, domContentLoadedEvent, loadEvent, connect, TLS/SSL, cache, DNS, request, and response. These phases remain useful as distinct operations.Keep browser.performance.phase as complementary detailpackages/browser-utils/src/metrics/browserMetrics.ts
                XSMediumBrowsermeasureKeep measure and add it to conventionsMissingPerformanceMeasure is a distinct, fixed, useful category.Keep the PerformanceEntry name in the span namepackages/browser-utils/src/metrics/browserMetrics.ts
                XSMediumBrowserresource.${initiatorType}Keep initiator-type leaves, add them to conventions, and retain resource.other as fallbackPartially registeredRegister the browser-standard initiator types, including currently undocumented values such as worker, icon, frame, object, ping, or track. Values outside the recognized browser set must still map to resource.other.resource.initiator_typepackages/browser-utils/src/metrics/browserMetrics.ts
                XSMediumHTTPnavigation.redirectKeep navigation.redirect and add it to conventionsMissingRedirect timing is a stable navigation category worth retaining as its own operation.navigation.type=redirectpackages/browser/src/tracing/browserTracingIntegration.ts
                XSMediumStorageobject.get|head|put|delete|list|upload_part|multipart_upload.abort|create|completeKeep object.* and add an object-storage category to conventionsMissingUnlike framework suffixes, these are a finite, provider-neutral API taxonomy for a domain not represented by current conventions. If a smaller taxonomy is preferred, normalize to object.read/write/delete before registration.cloud provider and bucket/object identity remain attributespackages/cloudflare/src/instrumentations/worker/instrumentR2.ts
                XSMediumUIui.mount / ui.update / ui.unmountAdd ui.mount, ui.update, and ui.unmount to conventions; ui.render already existsGeneric lifecycle leaves are incompleteThese are framework-neutral replacement targets for equivalent React, Vue, and Svelte lifecycle work.ui.framework; ui.component_name; ui.lifecycle_phasepackages/react/src/profiler.tsx
                packages/vue/src/tracing.ts
                packages/svelte/src/performance.ts
                XSMediumUIui.webvital.lcp / ui.webvital.clsKeep and add both to conventionsMissingThese are fixed, cross-framework browser concepts. They are better convention candidates than framework-specific lifecycle leaves.web_vital.name and measurement value remain authoritativepackages/browser-utils/src/metrics/lcp.ts
                packages/browser-utils/src/metrics/cls.ts
                packages/browser-utils/src/metrics/webVitalSpans.ts
                XLHighGen AIgen_ai.embeddings / gen_ai.generate_content / gen_ai.rerankembeddings / generate_content / rerankMissingThese are fixed, provider-neutral, semantically distinct model operations. Add their unprefixed forms to conventions, then migrate SDK emission consistently.gen_ai.operation.name and gen_ai.operation.typepackages/core/src/tracing/langchain/embeddings.ts
                packages/core/src/tracing/openai/index.ts
                packages/core/src/tracing/google-genai/index.ts
                packages/core/src/tracing/workers-ai/index.ts
                packages/core/src/tracing/vercel-ai/index.ts
                packages/server-utils/src/integrations/tracing-channel/openai.ts
                packages/server-utils/src/integrations/tracing-channel/google-genai.ts
                packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts

                Replace with another op

                Note: The additive "gap" rows — adding a sentry.op to spans that currently emit none, which is not breaking — were split out into #23138 (rate-limit, DO WebSocket, DataLoader prime/clear/clearAll, GraphQL, generic-pool, Effect). The row numbering below therefore skips 21–23.

                Row #EffortPriorityCategoryCurrent op(s)Replacement or conventions actionRegistry statusRationale / other findingsPreserve detail inProduction locations
                1SHighFaaShttp.request (Firebase Functions)function.gcphttp.request missingThe wrapper instruments all Firebase function trigger types, not only HTTP. A fixed http.request op is semantically wrong.faas.trigger already exists; keep faas.provider=firebasepackages/node/src/integrations/tracing/firebase/otel/patches/functions.ts
                2SHighHTTPhttp.client.${serviceIdentifier}http.clientDynamic suffix missingService identity belongs in attributes; endpoint-derived suffixes fragment grouping and can be high-cardinality.rpc.service or server.address / cloud.service.namepackages/google-cloud-serverless/src/integrations/google-cloud-http.ts
                3SHighHTTPhttp.client.prefetch / http.server.prefetchhttp.client / http.serverMissing; base ops existOTel inference fabricates unregistered suffixes. Preserve direction and move prefetch to data.sentry.http.prefetch=truepackages/opentelemetry/src/utils/parseSpanDescription.ts
                4SHighMessagingfaas.queue plus sentry.op=queue.process on one spanqueue.process onlyqueue.process exact; faas.queue missingCloudflare passes conflicting values. The sentry.op attribute wins, so faas.queue is effectively dead and should be removed.packages/cloudflare/src/instrumentations/worker/instrumentQueue.ts
                5SHighRPCgrpc.${serviceIdentifier}grpcDynamic suffix missingService identity can be high-cardinality and already has standard RPC attributes.rpc.service; rpc.methodpackages/google-cloud-serverless/src/integrations/google-cloud-grpc.ts
                6SHighUIui.angular.init / ui.angular.${methodKey}ui.mount for init; function for TraceMethodParent ui.angular existsThe method-key suffix is user-controlled and unbounded. Component initialization is a mount; arbitrary decorated methods are functions.ui.framework=angular; code.function.namepackages/angular/src/tracing.ts
                7SHighUIui.ember.route.before_model|model|after_model|setup_controllerfunctionMissingThese are route-hook functions. The hook name is already available and should not be encoded in sentry.op.code.function.name; ember.route.hookpackages/ember/addon/index.ts
                8SHighUIui.ember.runloop.${queue}ui.taskMissing; ui.task existsQueue values are phase details and Ember can be configured with custom queues.ui.framework=ember; ember.runloop.queuepackages/ember/addon/utils/instrumentEmberGlobals.ts
                9SMediumBrowserpaintbrowser.paintbrowser.paint existsRename the raw paint operation to the registered browser-specific operation.Keep the PerformanceEntry name in the span namepackages/browser-utils/src/metrics/browserMetrics.ts
                10SMediumFaaSfunction.aws.lambdafunction.awsfunction.aws existsLambda is already implied by provider/runtime attributes; use the registered provider-level operation.faas.name; cloud.provider=aws; cloud.platform=aws_lambdapackages/aws-serverless/src/requestSpanOptions.ts
                11SMediumHTTPhttp.client.streamhttp.clientMissing; parent existsStreaming changes response behavior but not the HTTP operation category.http.response.body.streaming=truepackages/browser/src/integrations/fetchStreamPerformance.ts
                12SMediumUIui.ember.component.render / component.definition / initui.render / function / ui.mountOnly parent ui.ember existsMap render and initialization to cross-framework lifecycle ops. Component definition lookup is generic function work.ui.framework=ember; ui.component_name; code.function.namepackages/ember/addon/utils/instrumentEmberGlobals.ts
                13MHighCachecache.has_item|get_item|get_item_raw|get_items|get_keys|set_item|set_item_raw|set_items|remove_item|clearcache.get / cache.put / cache.removeOnly target ops existThis is the exact over-granularity the cache conventions avoid. Map has/get/list to get; set variants to put; remove/clear to remove.db.operation.name already preserves the unstorage methodpackages/nuxt/src/runtime/utils/instrumentStorage.ts
                packages/nitro/src/runtime/hooks/captureStorageEvents.ts
                14MHighDatabasedb.redis / db.redis.connectdb.query for commands; db for connectMissing; db and db.query existThe datastore belongs in db.system.name. Library/system-specific op leaves are redundant.db.system.name=redis; db.operation.namepackages/server-utils/src/redis/redis-dc-subscriber.ts
                packages/server-utils/src/integrations/tracing-channel/redis.ts
                15MHighFaaSfaas.cron / faas.email / function.step.dofunctionMissingCloudflare trigger/workflow phase belongs in attributes. Do not add a new op per trigger.faas.trigger=timer|email; code.function.name; workflow.step.namepackages/cloudflare/src/instrumentations/worker/instrumentScheduled.ts
                packages/cloudflare/src/instrumentations/worker/instrumentEmail.ts
                packages/cloudflare/src/workflows.ts
                16MHighFaaSfaas.trigger.toString() inferred as opInfer function.<provider>, http.server, or queue.process from semantic evidenceArbitrary valuesOTel inference currently promotes an attribute value directly into sentry.op. Custom trigger strings can create unbounded ops.Retain faas.trigger as data; never use it verbatim as oppackages/opentelemetry/src/utils/parseSpanDescription.ts
                17MHighGen AIrpc on AWS Bedrock inference spanschat or generate_contentrpc exists but is semantically wrong hereBedrock adds GenAI attributes but inherits the generic AWS SDK rpc op. Select the GenAI operation from the Bedrock request type.packages/server-utils/src/integrations/tracing-channel/aws-sdk/index.ts
                packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/bedrock-runtime.ts
                18MHighMiddlewareapp_creation.nestjs / request_context.nestjs / event.nestjs / plugin.hapifunctionMissingThese represent executable functions or setup work. Keep lifecycle/event/plugin identity in attributes.code.function.name; nestjs.type; hapi.type; event.namepackages/nestjs/src/integrations/wrap-route.ts
                packages/nestjs/src/integrations/helpers.ts
                packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
                packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
                19MHighRPCrpc.server / mcp.server / mcp.notification.client_to_server|server_to_clientrpcOnly rpc existsMCP is JSON-RPC and tRPC is RPC. Direction, method, notification kind, and protocol belong in attributes rather than op suffixes.rpc.system=mcp|trpc; rpc.method; jsonrpc.*; messaging directionpackages/core/src/trpc.ts
                packages/core/src/integrations/mcp-server/spans.ts
                packages/core/src/integrations/mcp-server/attributes.ts
                20MMediumFaaSfunction.gcp.http / event / cloud_eventfunction.gcpfunction.gcp existsTrigger type belongs in faas.trigger. The existing suffixes split one provider category.faas.triggerpackages/google-cloud-serverless/src/gcpfunction/http.ts
                packages/google-cloud-serverless/src/gcpfunction/events.ts
                packages/google-cloud-serverless/src/gcpfunction/cloud_events.ts
                24LHighGen AIgen_ai.create_agent / gen_ai.models / gen_ai.unknown / ai.runfunction for create/models/unknown fallback; map ai.run to a known AI op when evidence existsMissingAgent compilation and model metadata calls are not inference operations. Unknown strings should not become conventions. Vercel AI's fallback should use an explicit mapping or a generic function op.gen_ai.operation.name; code.function.name; retain provider SDK methodpackages/core/src/tracing/langgraph/index.ts
                packages/core/src/tracing/anthropic-ai/index.ts
                packages/core/src/tracing/openai/index.ts
                packages/core/src/tracing/vercel-ai/index.ts
                25LHighMessagingmessage / message.produce / message.consumequeue.publish / queue.receive / queue.processmessage* missing; queue.* existsKafka, AMQP, and Deno use a parallel non-convention taxonomy. Use messaging.operation.type to distinguish publish, receive, and process. Deno must not infer all ops from SpanKind alone.messaging.system; messaging.operation.typepackages/server-utils/src/integrations/tracing-channel/kafkajs/spans.ts
                packages/server-utils/src/integrations/tracing-channel/amqplib.ts
                packages/opentelemetry/src/utils/parseSpanDescription.ts
                packages/deno/src/opentelemetry/tracer.ts
                26LHighMiddlewarerequest_handler.<library> / handler.nestjs / hono.requestfunction; use http.server only for a true inbound/internal HTTP boundaryMissingTerminal framework handlers are functions, not new op categories. Hono app.request() is an in-process HTTP dispatch and should use http.server with HTTP attributes.code.function.name; framework handler type; HTTP attributes for Hono dispatchpackages/core/src/integrations/express/patch-layer.ts
                packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
                packages/node/src/integrations/tracing/connect/vendored/instrumentation.ts
                packages/node/src/integrations/tracing/hono/index.ts
                packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts
                packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts
                packages/elysia/src/withElysia.ts
                packages/nestjs/src/integrations/wrap-route.ts
                packages/hono/src/shared/patchAppRequest.ts
                27LHighMiddlewarerouter.express / router.koa / router.hapirouter (conventions addition tracked in the first table)router is currently missingBackend router layers should share one framework-neutral operation. They are semantically distinct from generic middleware.code.namespace or framework; router.name; route attributespackages/core/src/integrations/express/patch-layer.ts
                packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
                packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
                packages/server-utils/src/integrations/tracing-channel/koa.ts
                packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
                packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
                28LMediumUIui.angular.routing / ui.sveltekit.routing / ui.ember.transitionrouter (conventions addition tracked in the first table)router must be added to conventionsAll three measure router execution. Collapse framework identity while keeping router work distinct from the broader navigation root.ui.framework; navigation.phasepackages/angular/src/tracing.ts
                packages/sveltekit/src/client/svelte4BrowserTracing.ts
                packages/sveltekit/src/client/svelte5BrowserTracing.ts
                packages/ember/addon/utils/instrumentEmberAppInstanceForPerformance.ts
                29LMediumUIui.react.* / ui.vue.* / ui.svelte.* lifecycle opsui.mount / ui.render / ui.update / ui.unmount (missing generic leaves tracked in the first table)React leaves exist; generic leaves are incompletePreferred cleanup: normalize equivalent lifecycle work across frameworks. Current values include React mount/render/update; Vue render/activate/create/unmount/destroy/mount/update; Svelte init/update. Keeping React-specific leaves while collapsing other frameworks would preserve an arbitrary asymmetry.ui.framework; ui.component_name; ui.lifecycle_phasepackages/react/src/profiler.tsx
                packages/vue/src/tracing.ts
                packages/svelte/src/performance.ts
                30XLHighFramework functionsfunction.<framework>(.<phase>) and loader.remix / action.remixfunctionfunction exists; function.nextjs/remix are legacy leavesCollapse all framework and phase suffixes. This also resolves Remix's three competing loader/action taxonomies. Includes Next.js, Remix, React Router client/server, SvelteKit client/server, SolidStart, TanStack Start, and Cloudflare workflow steps.code.function.name; code.namespace; framework-specific phase/type attributespackages/nextjs/src/common/utils/tracingUtils.ts
                packages/nextjs/src/common/withServerActionInstrumentation.ts
                packages/remix/src/server/instrumentServer.ts
                packages/remix/src/server/integrations/tracing-channel.ts
                packages/remix/src/server/integrations/opentelemetry.ts
                packages/react-router/src/server/createServerInstrumentation.ts
                packages/react-router/src/server/wrapServerLoader.ts
                packages/react-router/src/server/wrapServerAction.ts
                packages/react-router/src/server/instrumentation/reactRouter.ts
                packages/react-router/src/server/instrumentation/util.ts
                packages/react-router/src/client/createClientInstrumentation.ts
                packages/react-router/src/client/hydratedRouter.ts
                packages/sveltekit/src/client/load.ts
                packages/sveltekit/src/server-common/load.ts
                packages/sveltekit/src/server-common/serverRoute.ts
                packages/sveltekit/src/server-common/integrations/svelteKitSpans.ts
                packages/solidstart/src/server/withServerActionInstrumentation.ts
                packages/tanstackstart-react/src/server/wrapFetchWithSentry.ts
                packages/cloudflare/src/workflows.ts
                31XLHighGen AIgen_ai.chat / gen_ai.execute_tool / gen_ai.invoke_agentchat / execute_tool / invoke_agentRegistry values are unprefixedThe SDK and source-of-truth registry disagree. Migrate to the exact convention values, or explicitly change the registry—but do not leave both. Before migration, replace SDK internals which identify AI spans via op.startsWith('gen_ai.') with gen_ai.operation.type/name.gen_ai.operation.name and gen_ai.operation.typepackages/core/src/tracing/langchain/index.ts
                packages/core/src/tracing/langgraph/index.ts
                packages/core/src/tracing/langgraph/utils.ts
                packages/core/src/tracing/openai/index.ts
                packages/core/src/tracing/anthropic-ai/index.ts
                packages/core/src/tracing/google-genai/index.ts
                packages/core/src/tracing/workers-ai/index.ts
                packages/core/src/tracing/vercel-ai/index.ts
                packages/server-utils/src/integrations/tracing-channel/openai.ts
                packages/server-utils/src/integrations/tracing-channel/anthropic.ts
                packages/server-utils/src/integrations/tracing-channel/google-genai.ts
                packages/server-utils/src/vercel-ai/vercel-ai-dc-subscriber.ts
                32XLHighMiddlewaremiddleware.<library> / hook.fastify / http.server.middlewaremiddlewaremiddleware existsCollapse framework identity for middleware and request-pipeline hooks. Router layers are handled separately as router.code.namespace or framework; middleware.type; middleware.namepackages/core/src/integrations/express/patch-layer.ts
                packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts
                packages/node/src/integrations/tracing/connect/vendored/instrumentation.ts
                packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts
                packages/server-utils/src/integrations/tracing-channel/koa.ts
                packages/node/src/integrations/tracing/hapi/vendored/instrumentation.ts
                packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts
                packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts
                packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts
                packages/node/src/integrations/tracing/hono/index.ts
                packages/hono/src/shared/wrapMiddlewareSpan.ts
                packages/elysia/src/withElysia.ts
                packages/nestjs/src/integrations/helpers.ts
                packages/nuxt/src/runtime/hooks/wrapMiddlewareHandler.ts
                packages/nitro/src/runtime/hooks/captureTracingEvents.ts
                packages/tanstackstart-react/src/server/utils.ts
                packages/nextjs/src/common/wrapMiddlewareWithSentry.ts
                packages/nextjs/src/common/enhanceMiddlewareRootSpan.ts
                packages/nextjs/src/server/enhanceHandleRequestRootSpan.ts
                packages/nextjs/src/edge/index.ts

                Activity

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

                Metadata

                Metadata

                Assignees

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions