diff --git a/packages/cloudflare/src/instrumentations/instrumentDurableObjectStorage.ts b/packages/cloudflare/src/instrumentations/instrumentDurableObjectStorage.ts index eabad9dee209..a684a42d7028 100644 --- a/packages/cloudflare/src/instrumentations/instrumentDurableObjectStorage.ts +++ b/packages/cloudflare/src/instrumentations/instrumentDurableObjectStorage.ts @@ -73,6 +73,7 @@ export function instrumentDurableObjectStorage( { // Use underscore naming to match Cloudflare's native instrumentation (e.g., "durable_object_storage_get") name: `durable_object_storage_${methodName}`, + onlyIfParent: true, attributes: { [SENTRY_OP]: DB, [SENTRY_ORIGIN]: 'auto.db.cloudflare.durable_object', diff --git a/packages/cloudflare/src/instrumentations/instrumentDurableObjectSyncKvStorage.ts b/packages/cloudflare/src/instrumentations/instrumentDurableObjectSyncKvStorage.ts index 2ab1d58d69f0..414c46bed632 100644 --- a/packages/cloudflare/src/instrumentations/instrumentDurableObjectSyncKvStorage.ts +++ b/packages/cloudflare/src/instrumentations/instrumentDurableObjectSyncKvStorage.ts @@ -26,6 +26,7 @@ export function instrumentDurableObjectSyncKvStorage(syncKv: SyncKvStorage): Syn return startSpan( { name: `durable_object_storage_kv_${methodName}`, + onlyIfParent: true, attributes: { [SENTRY_OP]: DB, [SENTRY_ORIGIN]: 'auto.db.cloudflare.durable_object', diff --git a/packages/cloudflare/src/instrumentations/instrumentSqlStorage.ts b/packages/cloudflare/src/instrumentations/instrumentSqlStorage.ts index 61dfed37366b..7687c5dcf80b 100644 --- a/packages/cloudflare/src/instrumentations/instrumentSqlStorage.ts +++ b/packages/cloudflare/src/instrumentations/instrumentSqlStorage.ts @@ -47,7 +47,7 @@ export function instrumentSqlStorage(sql: SqlStorage): SqlStorage { // steps. We still start the span so it records its dropped span // outcome. A query that may target a `cf_` or `pi_` table takes the full path, // because an internal query must start no span. - return startSpan({ name: 'exec', attributes: SPAN_ATTRIBUTES }, callOriginal); + return startSpan({ name: 'exec', onlyIfParent: true, attributes: SPAN_ATTRIBUTES }, callOriginal); } const sanitizedQuery = sanitizeSqlQuery(query); @@ -64,6 +64,7 @@ export function instrumentSqlStorage(sql: SqlStorage): SqlStorage { return startSpan( { name: querySummary || sanitizedQuery, + onlyIfParent: true, attributes: { ...SPAN_ATTRIBUTES, [DB_QUERY_TEXT]: sanitizedQuery, diff --git a/packages/cloudflare/src/instrumentations/worker/instrumentD1.ts b/packages/cloudflare/src/instrumentations/worker/instrumentD1.ts index f76426956138..e42db0488010 100644 --- a/packages/cloudflare/src/instrumentations/worker/instrumentD1.ts +++ b/packages/cloudflare/src/instrumentations/worker/instrumentD1.ts @@ -146,6 +146,7 @@ function createStartSpanOptions(queryText: string | undefined, type: D1QueryType return { name, + onlyIfParent: true, attributes: { [SENTRY_OP]: DB_QUERY, [DB_SYSTEM_NAME]: 'cloudflare-d1', @@ -185,6 +186,7 @@ function instrumentBatch( return startSpan( { name: 'D1 batch', + onlyIfParent: true, attributes: { [SENTRY_OP]: DB_QUERY, [DB_SYSTEM_NAME]: 'cloudflare-d1', diff --git a/packages/cloudflare/src/instrumentations/worker/instrumentKV.ts b/packages/cloudflare/src/instrumentations/worker/instrumentKV.ts index 685b9fc46726..5a19cedb84ff 100644 --- a/packages/cloudflare/src/instrumentations/worker/instrumentKV.ts +++ b/packages/cloudflare/src/instrumentations/worker/instrumentKV.ts @@ -44,6 +44,7 @@ function createSpanOptions(bindingName: string, operation: KVOperation, args: un const keys = getCacheKeys(operation, args); return { name: cacheOperation, + onlyIfParent: true, attributes: { [SENTRY_OP]: cacheOperation, [CACHE_OPERATION]: cacheOperationName, diff --git a/packages/cloudflare/test/instrumentDurableObjectStorage.test.ts b/packages/cloudflare/test/instrumentDurableObjectStorage.test.ts index a2295ceff624..0ca6a6c7dd20 100644 --- a/packages/cloudflare/test/instrumentDurableObjectStorage.test.ts +++ b/packages/cloudflare/test/instrumentDurableObjectStorage.test.ts @@ -29,6 +29,7 @@ describe('instrumentDurableObjectStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'durable_object_storage_get', attributes: { 'sentry.op': 'db', @@ -50,6 +51,7 @@ describe('instrumentDurableObjectStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'durable_object_storage_get', attributes: { 'sentry.op': 'db', @@ -73,6 +75,7 @@ describe('instrumentDurableObjectStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'durable_object_storage_put', attributes: { 'sentry.op': 'db', @@ -94,6 +97,7 @@ describe('instrumentDurableObjectStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'durable_object_storage_put', attributes: { 'sentry.op': 'db', @@ -117,6 +121,7 @@ describe('instrumentDurableObjectStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'durable_object_storage_delete', attributes: { 'sentry.op': 'db', @@ -138,6 +143,7 @@ describe('instrumentDurableObjectStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'durable_object_storage_delete', attributes: { 'sentry.op': 'db', @@ -161,6 +167,7 @@ describe('instrumentDurableObjectStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'durable_object_storage_list', attributes: { 'sentry.op': 'db', @@ -184,6 +191,7 @@ describe('instrumentDurableObjectStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'durable_object_storage_setAlarm', attributes: { 'sentry.op': 'db', @@ -268,6 +276,7 @@ describe('instrumentDurableObjectStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'durable_object_storage_getAlarm', attributes: { 'sentry.op': 'db', @@ -289,6 +298,7 @@ describe('instrumentDurableObjectStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'durable_object_storage_deleteAlarm', attributes: { 'sentry.op': 'db', @@ -312,6 +322,7 @@ describe('instrumentDurableObjectStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'SELECT', attributes: { 'sentry.op': 'db.query', @@ -436,6 +447,7 @@ describe('instrumentDurableObjectStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'durable_object_storage_kv_get', attributes: { 'sentry.op': 'db', diff --git a/packages/cloudflare/test/instrumentDurableObjectSyncKvStorage.test.ts b/packages/cloudflare/test/instrumentDurableObjectSyncKvStorage.test.ts index b75cc0e0e245..8c6a5f8b59e1 100644 --- a/packages/cloudflare/test/instrumentDurableObjectSyncKvStorage.test.ts +++ b/packages/cloudflare/test/instrumentDurableObjectSyncKvStorage.test.ts @@ -18,6 +18,7 @@ describe('instrumentDurableObjectSyncKvStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'durable_object_storage_kv_get', attributes: { 'sentry.op': 'db', @@ -61,6 +62,7 @@ describe('instrumentDurableObjectSyncKvStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'durable_object_storage_kv_put', attributes: { 'sentry.op': 'db', @@ -93,6 +95,7 @@ describe('instrumentDurableObjectSyncKvStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'durable_object_storage_kv_delete', attributes: { 'sentry.op': 'db', @@ -126,6 +129,7 @@ describe('instrumentDurableObjectSyncKvStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'durable_object_storage_kv_list', attributes: { 'sentry.op': 'db', diff --git a/packages/cloudflare/test/instrumentSqlStorage.test.ts b/packages/cloudflare/test/instrumentSqlStorage.test.ts index af9cff36cfec..77ee3ad1a51a 100644 --- a/packages/cloudflare/test/instrumentSqlStorage.test.ts +++ b/packages/cloudflare/test/instrumentSqlStorage.test.ts @@ -24,6 +24,7 @@ describe('instrumentSqlStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'SELECT users', attributes: { 'sentry.op': 'db.query', @@ -48,6 +49,7 @@ describe('instrumentSqlStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'SELECT users', attributes: { 'sentry.op': 'db.query', @@ -81,6 +83,7 @@ describe('instrumentSqlStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'INSERT users', attributes: { 'sentry.op': 'db.query', @@ -301,6 +304,7 @@ describe('instrumentSqlStorage', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: 'exec', attributes: { 'sentry.op': 'db.query', diff --git a/packages/cloudflare/test/instrumentations/worker/instrumentD1.test.ts b/packages/cloudflare/test/instrumentations/worker/instrumentD1.test.ts index 7c6a6478853e..059c20fc6fd0 100644 --- a/packages/cloudflare/test/instrumentations/worker/instrumentD1.test.ts +++ b/packages/cloudflare/test/instrumentations/worker/instrumentD1.test.ts @@ -74,6 +74,7 @@ describe('instrumentD1', () => { expect(startSpanSpy).toHaveBeenCalledTimes(1); expect(startSpanSpy).toHaveBeenLastCalledWith( { + onlyIfParent: true, attributes: { 'sentry.op': 'db.query', 'db.system.name': 'cloudflare-d1', @@ -176,6 +177,7 @@ describe('instrumentD1', () => { expect(startSpanSpy).toHaveBeenCalledTimes(1); expect(startSpanSpy).toHaveBeenLastCalledWith( { + onlyIfParent: true, attributes: { 'sentry.op': 'db.query', 'db.system.name': 'cloudflare-d1', @@ -230,6 +232,7 @@ describe('instrumentD1', () => { expect(startSpanSpy).toHaveBeenCalledTimes(1); expect(startSpanSpy).toHaveBeenLastCalledWith( { + onlyIfParent: true, attributes: { 'sentry.op': 'db.query', 'db.system.name': 'cloudflare-d1', @@ -284,6 +287,7 @@ describe('instrumentD1', () => { expect(startSpanSpy).toHaveBeenCalledTimes(1); expect(startSpanSpy).toHaveBeenLastCalledWith( { + onlyIfParent: true, attributes: { 'sentry.op': 'db.query', 'db.system.name': 'cloudflare-d1', @@ -335,6 +339,7 @@ describe('instrumentD1', () => { expect(startSpanSpy).toHaveBeenCalledTimes(1); expect(startSpanSpy).toHaveBeenLastCalledWith( { + onlyIfParent: true, attributes: { 'sentry.op': 'db.query', 'db.system.name': 'cloudflare-d1', @@ -374,6 +379,7 @@ describe('instrumentD1', () => { expect(startSpanSpy).toHaveBeenCalledTimes(1); expect(startSpanSpy).toHaveBeenLastCalledWith( { + onlyIfParent: true, attributes: { 'sentry.op': 'db.query', 'db.system.name': 'cloudflare-d1', @@ -403,6 +409,7 @@ describe('instrumentD1', () => { expect(startSpanSpy).toHaveBeenCalledTimes(1); expect(startSpanSpy).toHaveBeenLastCalledWith( { + onlyIfParent: true, attributes: { 'sentry.op': 'db.query', 'db.system.name': 'cloudflare-d1', @@ -441,6 +448,7 @@ describe('instrumentD1', () => { expect(startSpanSpy).toHaveBeenCalledTimes(1); expect(startSpanSpy).toHaveBeenLastCalledWith( { + onlyIfParent: true, attributes: { 'sentry.op': 'db.query', 'db.system.name': 'cloudflare-d1', @@ -478,6 +486,7 @@ describe('instrumentD1', () => { expect(startSpanSpy).toHaveBeenCalledTimes(1); expect(startSpanSpy).toHaveBeenLastCalledWith( { + onlyIfParent: true, attributes: { 'sentry.op': 'db.query', 'db.system.name': 'cloudflare-d1', diff --git a/packages/cloudflare/test/instrumentations/worker/instrumentKV.test.ts b/packages/cloudflare/test/instrumentations/worker/instrumentKV.test.ts index 50e08dc1b69b..a5203a01e9e9 100644 --- a/packages/cloudflare/test/instrumentations/worker/instrumentKV.test.ts +++ b/packages/cloudflare/test/instrumentations/worker/instrumentKV.test.ts @@ -48,6 +48,7 @@ describe('instrumentKV', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: CACHE_GET, attributes: { [SENTRY_OP]: CACHE_GET, @@ -81,6 +82,7 @@ describe('instrumentKV', () => { expect(get).toHaveBeenCalledWith(keys, 'text'); expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: CACHE_GET, attributes: { [SENTRY_OP]: CACHE_GET, @@ -105,6 +107,7 @@ describe('instrumentKV', () => { expect(kv.getWithMetadata).toHaveBeenCalledWith('test-key', 'json'); expect(startSpanSpy).toHaveBeenCalledWith( { + onlyIfParent: true, name: CACHE_GET, attributes: { [SENTRY_OP]: CACHE_GET, @@ -132,6 +135,7 @@ describe('instrumentKV', () => { expect(startSpanSpy).toHaveBeenNthCalledWith( 1, { + onlyIfParent: true, name: CACHE_PUT, attributes: { [SENTRY_OP]: CACHE_PUT, @@ -148,6 +152,7 @@ describe('instrumentKV', () => { expect(startSpanSpy).toHaveBeenNthCalledWith( 2, { + onlyIfParent: true, name: CACHE_REMOVE, attributes: { [SENTRY_OP]: CACHE_REMOVE, @@ -164,6 +169,7 @@ describe('instrumentKV', () => { expect(startSpanSpy).toHaveBeenNthCalledWith( 3, { + onlyIfParent: true, name: CACHE_GET, attributes: { [SENTRY_OP]: CACHE_GET, diff --git a/packages/nuxt/src/runtime/utils/instrumentDatabase.ts b/packages/nuxt/src/runtime/utils/instrumentDatabase.ts index 4c525e005869..08a886465e3f 100644 --- a/packages/nuxt/src/runtime/utils/instrumentDatabase.ts +++ b/packages/nuxt/src/runtime/utils/instrumentDatabase.ts @@ -271,6 +271,7 @@ function createStartSpanOptions( return { name, + onlyIfParent: true, attributes: { [DB_QUERY_TEXT]: queryText, [DB_QUERY_SUMMARY]: querySummary, diff --git a/packages/nuxt/src/runtime/utils/instrumentStorage.ts b/packages/nuxt/src/runtime/utils/instrumentStorage.ts index f0dd1fb1b399..75f8ed8ba054 100644 --- a/packages/nuxt/src/runtime/utils/instrumentStorage.ts +++ b/packages/nuxt/src/runtime/utils/instrumentStorage.ts @@ -258,6 +258,7 @@ function createSpanStartOptions( return { // With span streaming, span names have to be low cardinality, so we can't fall back to the cache keys. name: client && hasSpanStreamingEnabled(client) ? cacheOperation : keys.join(', '), + onlyIfParent: true, attributes, }; } diff --git a/packages/server-utils/src/integrations/aws-sdk/index.ts b/packages/server-utils/src/integrations/aws-sdk/index.ts index 10951179dd04..c6b3831e9a5c 100644 --- a/packages/server-utils/src/integrations/aws-sdk/index.ts +++ b/packages/server-utils/src/integrations/aws-sdk/index.ts @@ -9,7 +9,7 @@ import { HTTP_RESPONSE_STATUS_CODE, SENTRY_ORIGIN, } from '@sentry/conventions/attributes'; -import { RPC } from '@sentry/conventions/op'; +import { DB, RPC } from '@sentry/conventions/op'; import type { OrchestrionChannelContext } from '../../orchestrion/types'; import { CHANNELS } from '../../orchestrion/channels'; import { awsSdkModuleNames } from '../../orchestrion/config/aws-sdk'; @@ -116,6 +116,7 @@ function instrumentAwsSdk(servicesExtensions: ServicesExtensions): void { const span = startInactiveSpan({ name: requestMetadata.spanName ?? `${normalizedRequest.serviceName}.${normalizedRequest.commandName}`, op, + onlyIfParent: op === DB, attributes: { [SENTRY_KIND]: 'client', [SENTRY_ORIGIN]: getSpanOrigin(op), diff --git a/packages/server-utils/src/integrations/knex.ts b/packages/server-utils/src/integrations/knex.ts index bdc3d4dac16f..5aa05530100a 100644 --- a/packages/server-utils/src/integrations/knex.ts +++ b/packages/server-utils/src/integrations/knex.ts @@ -150,10 +150,6 @@ function subscribeQuery(): void { // The builder captures the span active when it was created (see `subscribeBuilder`). // `onlyIfParent`: only instrument queries that run as part of an existing trace, matching OTel. const parentSpan = builder?.[parentSpanSymbol] ?? getActiveSpan(); - if (!parentSpan) { - return undefined; - } - const query = data.arguments[0]; const client = runner?.client; const connection = client?.config?.connection; @@ -193,6 +189,7 @@ function subscribeQuery(): void { : (dbStatement ?? getName(dbNameSpace, operation, table) ?? 'knex.query'); return startInactiveSpan({ + onlyIfParent: true, name: spanName, parentSpan, attributes, diff --git a/packages/server-utils/src/integrations/mongoose/mongoose-dc-subscriber.ts b/packages/server-utils/src/integrations/mongoose/mongoose-dc-subscriber.ts index e7e9e3c44c71..cc2d800bce51 100644 --- a/packages/server-utils/src/integrations/mongoose/mongoose-dc-subscriber.ts +++ b/packages/server-utils/src/integrations/mongoose/mongoose-dc-subscriber.ts @@ -130,6 +130,7 @@ function setupChannel(tracingChannel: MongooseTracingChannelFactory, channelName : `mongoose.${data.operation}`; return startInactiveSpan({ + onlyIfParent: true, name, attributes: { [SENTRY_ORIGIN]: ORIGIN, diff --git a/packages/server-utils/src/integrations/mongoose/mongoose-legacy-span.ts b/packages/server-utils/src/integrations/mongoose/mongoose-legacy-span.ts index d22e7c8a1063..d77a8935ff36 100644 --- a/packages/server-utils/src/integrations/mongoose/mongoose-legacy-span.ts +++ b/packages/server-utils/src/integrations/mongoose/mongoose-legacy-span.ts @@ -73,6 +73,7 @@ export function startMongooseLegacySpan({ : `mongoose.${modelName}.${operation}`; return startInactiveSpan({ + onlyIfParent: true, name, // Set this explicitly, for platforms lacking `inferDbSpanData` attributes, diff --git a/packages/server-utils/src/integrations/mysql.ts b/packages/server-utils/src/integrations/mysql.ts index de538d52afd7..138b0680ecab 100644 --- a/packages/server-utils/src/integrations/mysql.ts +++ b/packages/server-utils/src/integrations/mysql.ts @@ -90,6 +90,7 @@ function instrumentMysql(): void { : (queryText ?? 'mysql.query'); return startInactiveSpan({ + onlyIfParent: true, name, attributes: { [SENTRY_OP]: DB, diff --git a/packages/server-utils/src/integrations/nitro/captureStorageEvents.ts b/packages/server-utils/src/integrations/nitro/captureStorageEvents.ts index 0e464947c37c..43ab9048ef04 100644 --- a/packages/server-utils/src/integrations/nitro/captureStorageEvents.ts +++ b/packages/server-utils/src/integrations/nitro/captureStorageEvents.ts @@ -98,6 +98,7 @@ function setupStorageTracingChannel(operation: TracedOperation): void { const client = getClient(); return startInactiveSpan({ + onlyIfParent: true, // With span streaming, span names have to be low cardinality, so we can't fall back to the cache keys. name: client && hasSpanStreamingEnabled(client) ? OPERATION_SPAN_OPS[operation] : cacheKeys.join(', ') || operation, diff --git a/packages/server-utils/src/integrations/postgresjs.ts b/packages/server-utils/src/integrations/postgresjs.ts index c8f11e709f48..ea061292eca0 100644 --- a/packages/server-utils/src/integrations/postgresjs.ts +++ b/packages/server-utils/src/integrations/postgresjs.ts @@ -5,7 +5,6 @@ import { debug, - getActiveSpan, getClient, hasSpanStreamingEnabled, isObjectLike, @@ -242,7 +241,7 @@ function _wrapSingleQueryHandle( const wrappedHandle = async function (this: { executed?: boolean }, ...args: unknown[]): Promise { // postgres.js calls handle() from then/catch/finally — only the first call executes SQL, // subsequent calls are no-ops (guarded by this.executed). Skip span creation for no-ops. - if (this.executed || !_shouldCreateSpans(options)) { + if (this.executed) { return originalHandle.apply(this, args); } @@ -264,6 +263,7 @@ function _wrapSingleQueryHandle( return startSpanManual( { name, + onlyIfParent: options.requireParentSpan, attributes: { [SENTRY_OP]: DB, [SENTRY_ORIGIN]: 'auto.db.postgresjs', @@ -341,16 +341,6 @@ function _wrapSingleQueryHandle( query.handle = wrappedHandle; } -/** - * Determines whether a span should be created based on the current context. - * If `requireParentSpan` is set to true in the options, a span will - * only be created if there is a parent span available. - */ -function _shouldCreateSpans(options: PostgresJsSqlInstrumentationOptions): boolean { - const hasParentSpan = getActiveSpan() !== undefined; - return hasParentSpan || !options.requireParentSpan; -} - /** * Reconstructs the full SQL query from template strings with PostgreSQL placeholders. * diff --git a/packages/server-utils/src/integrations/prisma/tracing-helper.ts b/packages/server-utils/src/integrations/prisma/tracing-helper.ts index 218e7c788134..2f935aa33d19 100644 --- a/packages/server-utils/src/integrations/prisma/tracing-helper.ts +++ b/packages/server-utils/src/integrations/prisma/tracing-helper.ts @@ -295,6 +295,7 @@ export class ActiveTracingHelper implements TracingHelper { const attributes = buildSpanAttributes(name, options.attributes); const spanOptions = { name: buildSpanName(name, attributes), + onlyIfParent: name !== 'prisma:client:connect', attributes, kind: options.kind, links: options.links, @@ -332,6 +333,7 @@ function dispatchEngineSpan( startSpanManual( { name: buildSpanName(engineSpan.name, attributes), + onlyIfParent: engineSpan.name !== 'prisma:engine:connect', attributes: { ...attributes, [SENTRY_KIND]: engineSpan.kind === 'client' ? 'client' : undefined, diff --git a/packages/server-utils/src/integrations/redis/index.ts b/packages/server-utils/src/integrations/redis/index.ts index 7176a14b57ec..2c5e86dc5bdb 100644 --- a/packages/server-utils/src/integrations/redis/index.ts +++ b/packages/server-utils/src/integrations/redis/index.ts @@ -116,6 +116,7 @@ function startCommandSpan( const cacheProperties = getRedisCacheAttributes(commandName, commandArgs, attributes, cacheOptions); return startInactiveSpan({ + onlyIfParent: true, name: cacheProperties?.name ?? streamedName ?? (dbStatement || `redis-${commandName}`), attributes: { [SENTRY_KIND]: 'client', @@ -268,6 +269,7 @@ function bindNodeRedisBatchChannel( const options = (data.self as NodeRedisClient | undefined)?.options; const operation = getOperation(data); return startInactiveSpan({ + onlyIfParent: true, name: operation, attributes: { [SENTRY_KIND]: 'client', diff --git a/packages/server-utils/src/integrations/redis/redis-dc-subscriber.ts b/packages/server-utils/src/integrations/redis/redis-dc-subscriber.ts index 5db9dc2e5458..7e3887d82b75 100644 --- a/packages/server-utils/src/integrations/redis/redis-dc-subscriber.ts +++ b/packages/server-utils/src/integrations/redis/redis-dc-subscriber.ts @@ -160,6 +160,7 @@ function setupCommandChannel( }; const cacheProperties = getRedisCacheAttributes(data.command, args, attributes, cacheOptions); return startInactiveSpan({ + onlyIfParent: true, name: cacheProperties?.name ?? streamedName ?? `redis-${data.command}`, attributes: { ...attributes, ...cacheProperties?.attributes }, }); @@ -181,6 +182,7 @@ function setupBatchChannel( bindTracingChannelToSpan(tracingChannel(channelName), data => { const operation = getOperationName(data); return startInactiveSpan({ + onlyIfParent: true, name: operation, attributes: { [SENTRY_ORIGIN]: ORIGIN, diff --git a/packages/server-utils/test/integrations/prisma.test.ts b/packages/server-utils/test/integrations/prisma.test.ts index 2d02718b6d1e..00af81b1f7d4 100644 --- a/packages/server-utils/test/integrations/prisma.test.ts +++ b/packages/server-utils/test/integrations/prisma.test.ts @@ -1,5 +1,13 @@ import type { Span } from '@sentry/core'; -import { Client, createTransport, getCurrentScope, initAndBind, resolvedSyncPromise, spanToJSON } from '@sentry/core'; +import { + Client, + createTransport, + getCurrentScope, + initAndBind, + resolvedSyncPromise, + spanToJSON, + startSpan, +} from '@sentry/core'; import { afterEach, describe, expect, it } from 'vitest'; import { instrumentPrisma } from '../../src/integrations/prisma'; import type { TracingHelper } from '../../src/integrations/prisma/types'; @@ -37,8 +45,10 @@ function initTestClient(): void { /** Runs a `db_query` span through the installed helper and returns the span it created. */ function runDbQuerySpan(attributes: Record): Span { let span: Span | undefined; - getHelper()?.runInChildSpan({ name: 'db_query', attributes }, createdSpan => { - span = createdSpan; + startSpan({ name: 'parent' }, () => { + getHelper()?.runInChildSpan({ name: 'db_query', attributes }, createdSpan => { + span = createdSpan; + }); }); return span!; }