From 9a0603922c3cddcefbee25384cb5920fda8dc1f1 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Mon, 29 Jun 2026 17:45:27 +0200 Subject: [PATCH 1/3] feat(core): Add `sentry.trace_lifecycle` attribute --- .../public-api/startSpan/streamed/test.ts | 17 +++++++++++++++++ .../interactions-streamed/test.ts | 9 +++++++++ .../navigation-streamed/test.ts | 5 +++++ .../pageload-streamed/test.ts | 5 +++++ .../public-api/startSpan-streamed/test.ts | 6 ++++++ .../deno-streamed/tests/spans.test.ts | 16 ++++++++++++++++ .../startSpan/basic-usage-streamed/test.ts | 5 +++++ .../startSpan/basic-usage-streamed/test.ts | 5 +++++ .../suites/tracing/postgres-streamed/test.ts | 6 +++++- .../test/integrations/spanstreaming.test.ts | 5 +++++ packages/core/src/semanticAttributes.ts | 6 ++++++ packages/core/src/tracing/spans/captureSpan.ts | 2 ++ .../test/lib/tracing/spans/captureSpan.test.ts | 14 ++++++++++++++ 13 files changed, 100 insertions(+), 1 deletion(-) diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/streamed/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/streamed/test.ts index 0b6af5fb420d..6b1d532f1436 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/streamed/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/streamed/test.ts @@ -12,6 +12,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SEMANTIC_ATTRIBUTE_SENTRY_STATUS_MESSAGE, + SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { shouldSkipTracingTest } from '../../../../utils/helpers'; @@ -100,6 +101,10 @@ sentryTest( type: 'string', value: 'production', }, + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + type: 'string', + value: 'stream', + }, }, end_timestamp: expect.any(Number), is_segment: false, @@ -136,6 +141,10 @@ sentryTest( type: 'string', value: 'production', }, + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + type: 'string', + value: 'stream', + }, }, end_timestamp: expect.any(Number), is_segment: false, @@ -176,6 +185,10 @@ sentryTest( type: 'string', value: 'Connection Refused', }, + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + type: 'string', + value: 'stream', + }, }, end_timestamp: expect.any(Number), is_segment: false, @@ -252,6 +265,10 @@ sentryTest( type: 'string', value: 'production', }, + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + type: 'string', + value: 'stream', + }, }, end_timestamp: expect.any(Number), is_segment: true, diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/interactions-streamed/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/interactions-streamed/test.ts index 8d4269d2c88b..327aac7972cf 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/interactions-streamed/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/interactions-streamed/test.ts @@ -11,6 +11,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID, SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { shouldSkipTracingTest } from '../../../../utils/helpers'; @@ -42,6 +43,10 @@ sentryTest('captures streamed interaction span tree. @firefox', async ({ browser expect(interactionSegmentSpan).toEqual({ attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + type: 'string', + value: 'stream', + }, 'culture.calendar': { type: 'string', value: expect.any(String), @@ -122,6 +127,10 @@ sentryTest('captures streamed interaction span tree. @firefox', async ({ browser const interactionSpan = interactionSpanTree.find(span => getSpanOp(span) === 'ui.interaction.click'); expect(interactionSpan).toEqual({ attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + type: 'string', + value: 'stream', + }, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'ui.interaction.click', diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/navigation-streamed/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/navigation-streamed/test.ts index af6f8bedb75e..54128df8b210 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/navigation-streamed/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/navigation-streamed/test.ts @@ -7,6 +7,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SDK_INTEGRATIONS, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { shouldSkipTracingTest } from '../../../../utils/helpers'; @@ -71,6 +72,10 @@ sentryTest('starts a streamed navigation span on page navigation', async ({ brow expect(navigationSpan).toEqual({ attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + type: 'string', + value: 'stream', + }, 'culture.calendar': { type: 'string', value: expect.any(String), diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-streamed/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-streamed/test.ts index 027c3e62aca5..bed58af888b0 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-streamed/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-streamed/test.ts @@ -11,6 +11,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID, SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { shouldSkipTracingTest } from '../../../../utils/helpers'; @@ -64,6 +65,10 @@ sentryTest( expect(pageloadSpan).toEqual({ attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + type: 'string', + value: 'stream', + }, 'culture.calendar': { type: 'string', value: expect.any(String), diff --git a/dev-packages/cloudflare-integration-tests/suites/public-api/startSpan-streamed/test.ts b/dev-packages/cloudflare-integration-tests/suites/public-api/startSpan-streamed/test.ts index c51a400e7857..c21799da7c6f 100644 --- a/dev-packages/cloudflare-integration-tests/suites/public-api/startSpan-streamed/test.ts +++ b/dev-packages/cloudflare-integration-tests/suites/public-api/startSpan-streamed/test.ts @@ -12,6 +12,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID, SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, } from '@sentry/core'; import { expect, it } from 'vitest'; import { createRunner } from '../../../runner'; @@ -77,6 +78,7 @@ it('sends a streamed span envelope with correct spans for a manually started spa expect(childSpan).toBeDefined(); expect(childSpan).toEqual({ attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'test-child', @@ -103,6 +105,7 @@ it('sends a streamed span envelope with correct spans for a manually started spa expect(inactiveSpan).toBeDefined(); expect(inactiveSpan).toEqual({ attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: { type: 'string', value: 'manual' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: CLOUDFLARE_SDK }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION }, @@ -138,6 +141,7 @@ it('sends a streamed span envelope with correct spans for a manually started spa expect(manualSpan).toBeDefined(); expect(manualSpan).toEqual({ attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: { type: 'string', value: 'manual' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: CLOUDFLARE_SDK }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION }, @@ -158,6 +162,7 @@ it('sends a streamed span envelope with correct spans for a manually started spa expect(parentTestSpan).toEqual({ attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'test' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: CLOUDFLARE_SDK }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION }, @@ -179,6 +184,7 @@ it('sends a streamed span envelope with correct spans for a manually started spa expect(segmentSpan).toEqual({ attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: CLOUDFLARE_SDK }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_INTEGRATIONS]: { diff --git a/dev-packages/e2e-tests/test-applications/deno-streamed/tests/spans.test.ts b/dev-packages/e2e-tests/test-applications/deno-streamed/tests/spans.test.ts index 7ed898351fc2..ef8883aacef4 100644 --- a/dev-packages/e2e-tests/test-applications/deno-streamed/tests/spans.test.ts +++ b/dev-packages/e2e-tests/test-applications/deno-streamed/tests/spans.test.ts @@ -3,6 +3,10 @@ import { waitForStreamedSpans, getSpanOp } from '@sentry-internal/test-utils'; const SEGMENT_SPAN = { attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + type: 'string', + value: 'stream', + }, 'app.start_time': { type: 'string', value: expect.any(String), @@ -170,6 +174,10 @@ test('Sends streamed spans (http.server and manual with Sentry.startSpan)', asyn expect(spans).toEqual([ { attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + type: 'string', + value: 'stream', + }, 'sentry.environment': { type: 'string', value: 'qa', @@ -238,6 +246,10 @@ test('OTel span appears as child of Sentry span (interop)', async ({ baseURL }) expect(sentrySpan).toEqual({ attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + type: 'string', + value: 'stream', + }, 'sentry.environment': { type: 'string', value: 'qa', @@ -275,6 +287,10 @@ test('OTel span appears as child of Sentry span (interop)', async ({ baseURL }) expect(otelSpan).toEqual({ attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + type: 'string', + value: 'stream', + }, 'sentry.environment': { type: 'string', value: 'qa', diff --git a/dev-packages/node-core-integration-tests/suites/public-api/startSpan/basic-usage-streamed/test.ts b/dev-packages/node-core-integration-tests/suites/public-api/startSpan/basic-usage-streamed/test.ts index 34b02875830b..b7329ead23b7 100644 --- a/dev-packages/node-core-integration-tests/suites/public-api/startSpan/basic-usage-streamed/test.ts +++ b/dev-packages/node-core-integration-tests/suites/public-api/startSpan/basic-usage-streamed/test.ts @@ -10,6 +10,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID, SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, } from '@sentry/core'; import { expect, test } from 'vitest'; import { createRunner } from '../../../../utils/runner'; @@ -53,6 +54,7 @@ test('sends a streamed span envelope with correct spans for a manually started s expect(childSpan).toBeDefined(); expect(childSpan).toEqual({ attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'test-child', @@ -80,6 +82,7 @@ test('sends a streamed span envelope with correct spans for a manually started s expect(inactiveSpan).toBeDefined(); expect(inactiveSpan).toEqual({ attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: 'sentry.javascript.node-core' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION }, [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID]: { type: 'string', value: segmentSpanId }, @@ -116,6 +119,7 @@ test('sends a streamed span envelope with correct spans for a manually started s expect(manualSpan).toBeDefined(); expect(manualSpan).toEqual({ attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: 'sentry.javascript.node-core' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION }, [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID]: { type: 'string', value: segmentSpanId }, @@ -136,6 +140,7 @@ test('sends a streamed span envelope with correct spans for a manually started s }); const expectedAttributes: Record = { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'test' }, [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: { type: 'integer', value: 1 }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: 'sentry.javascript.node-core' }, diff --git a/dev-packages/node-integration-tests/suites/public-api/startSpan/basic-usage-streamed/test.ts b/dev-packages/node-integration-tests/suites/public-api/startSpan/basic-usage-streamed/test.ts index 7bc6db742834..0f46fb143ed2 100644 --- a/dev-packages/node-integration-tests/suites/public-api/startSpan/basic-usage-streamed/test.ts +++ b/dev-packages/node-integration-tests/suites/public-api/startSpan/basic-usage-streamed/test.ts @@ -11,6 +11,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID, SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, } from '@sentry/core'; import { expect, test } from 'vitest'; import { createRunner } from '../../../../utils/runner'; @@ -54,6 +55,7 @@ test('sends a streamed span envelope with correct spans for a manually started s expect(childSpan).toBeDefined(); expect(childSpan).toEqual({ attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'test-child', @@ -82,6 +84,7 @@ test('sends a streamed span envelope with correct spans for a manually started s expect(inactiveSpan).toBeDefined(); expect(inactiveSpan).toEqual({ attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: 'sentry.javascript.node' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION }, [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID]: { type: 'string', value: segmentSpanId }, @@ -119,6 +122,7 @@ test('sends a streamed span envelope with correct spans for a manually started s expect(manualSpan).toBeDefined(); expect(manualSpan).toEqual({ attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: 'sentry.javascript.node' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION }, [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID]: { type: 'string', value: segmentSpanId }, @@ -140,6 +144,7 @@ test('sends a streamed span envelope with correct spans for a manually started s }); const expectedAttributes: Record = { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'test' }, [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: { type: 'integer', value: 1 }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: 'sentry.javascript.node' }, diff --git a/dev-packages/node-integration-tests/suites/tracing/postgres-streamed/test.ts b/dev-packages/node-integration-tests/suites/tracing/postgres-streamed/test.ts index 6ada072d11db..50d7b2741a60 100644 --- a/dev-packages/node-integration-tests/suites/tracing/postgres-streamed/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/postgres-streamed/test.ts @@ -1,4 +1,4 @@ -import { SEMANTIC_ATTRIBUTE_SENTRY_OP } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE } from '@sentry/core'; import type { SerializedStreamedSpanContainer } from '@sentry/core'; import { afterAll, describe, expect } from 'vitest'; import { conditionalTest, isOrchestrionEnabled } from '../../../utils'; @@ -75,6 +75,10 @@ const COMMON_DB_ATTRIBUTES = { type: 'string', value: 'task', }, + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + type: 'string', + value: 'stream', + }, }; /** diff --git a/packages/browser/test/integrations/spanstreaming.test.ts b/packages/browser/test/integrations/spanstreaming.test.ts index b480d0240701..e34dacc9da6c 100644 --- a/packages/browser/test/integrations/spanstreaming.test.ts +++ b/packages/browser/test/integrations/spanstreaming.test.ts @@ -3,6 +3,7 @@ import { debug, SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT, SEMANTIC_ATTRIBUTE_SENTRY_SDK_INTEGRATIONS, + SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, } from '@sentry/core/browser'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { BrowserClient, spanStreamingIntegration } from '../../src'; @@ -137,6 +138,10 @@ describe('spanStreamingIntegration', () => { start_timestamp: expect.any(Number), status: 'ok', attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + type: 'string', + value: 'stream', + }, 'sentry.origin': { type: 'string', value: 'manual', diff --git a/packages/core/src/semanticAttributes.ts b/packages/core/src/semanticAttributes.ts index 8df3b5e8b013..8976b8bded6d 100644 --- a/packages/core/src/semanticAttributes.ts +++ b/packages/core/src/semanticAttributes.ts @@ -65,6 +65,12 @@ export const SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION = 'sentry.sdk.version'; /** The list of integrations enabled in the Sentry SDK (e.g., ["InboundFilters", "BrowserTracing"]) */ export const SEMANTIC_ATTRIBUTE_SENTRY_SDK_INTEGRATIONS = 'sentry.sdk.integrations'; +/** + * Indicates the trace lifecycle mode with which a span was sent by the SDK. + * Either "stream" (streamed span) or "static" (transaction-sent span). + */ +export const SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE = 'sentry.trace_lifecycle'; + /** The user ID */ export const SEMANTIC_ATTRIBUTE_USER_ID = 'user.id'; /** The user email */ diff --git a/packages/core/src/tracing/spans/captureSpan.ts b/packages/core/src/tracing/spans/captureSpan.ts index a2fc6595e348..0f25cd845409 100644 --- a/packages/core/src/tracing/spans/captureSpan.ts +++ b/packages/core/src/tracing/spans/captureSpan.ts @@ -10,6 +10,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID, SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, SEMANTIC_ATTRIBUTE_USER_EMAIL, SEMANTIC_ATTRIBUTE_USER_ID, SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS, @@ -138,6 +139,7 @@ function applyCommonSpanAttributes( // avoid overwriting any previously set attributes (from users or potentially our SDK instrumentation) safeSetSpanJSONAttributes(spanJSON, { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: 'stream', [SEMANTIC_ATTRIBUTE_SENTRY_RELEASE]: release, [SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT]: environment || DEFAULT_ENVIRONMENT, [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME]: serializedSegmentSpan.name, diff --git a/packages/core/test/lib/tracing/spans/captureSpan.test.ts b/packages/core/test/lib/tracing/spans/captureSpan.test.ts index aa81d664ea8c..47da9abe5578 100644 --- a/packages/core/test/lib/tracing/spans/captureSpan.test.ts +++ b/packages/core/test/lib/tracing/spans/captureSpan.test.ts @@ -13,6 +13,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID, SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, SEMANTIC_ATTRIBUTE_USER_EMAIL, SEMANTIC_ATTRIBUTE_USER_ID, SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS, @@ -67,6 +68,10 @@ describe('captureSpan', () => { status: 'ok', is_segment: true, attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + type: 'string', + value: 'stream', + }, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'http.client', @@ -204,6 +209,10 @@ describe('captureSpan', () => { value: 'staging', type: 'string', }, + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + value: 'stream', + type: 'string', + }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { value: 'sentry.javascript.node', type: 'string', @@ -300,6 +309,10 @@ describe('captureSpan', () => { value: 'production', type: 'string', }, + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + value: 'stream', + type: 'string', + }, }, _segmentSpan: span, }); @@ -344,6 +357,7 @@ describe('captureSpan', () => { status: 'ok', is_segment: true, attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'http.client' }, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: { type: 'string', value: 'manual' }, [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: { type: 'integer', value: 1 }, From 34c397b58cd25383653b056830ce2bb369f7563f Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 2 Jul 2026 13:23:07 +0200 Subject: [PATCH 2/3] use attribute from @sentry/conventions and adjust tests accordingly --- dev-packages/browser-integration-tests/package.json | 1 + .../suites/public-api/startSpan/streamed/test.ts | 10 +++++----- .../interactions-streamed/test.ts | 6 +++--- .../navigation-streamed/test.ts | 4 ++-- .../pageload-streamed/test.ts | 10 +++++----- .../cloudflare-integration-tests/package.json | 1 + .../suites/public-api/startSpan-streamed/test.ts | 12 ++++++------ .../deno-streamed/tests/spans.test.ts | 8 ++++---- .../node-core-integration-tests/package.json | 1 + .../startSpan/basic-usage-streamed/test.ts | 10 +++++----- dev-packages/node-integration-tests/package.json | 1 + .../startSpan/basic-usage-streamed/test.ts | 10 +++++----- .../suites/tracing/postgres-streamed/test.ts | 5 +++-- .../browser/test/integrations/spanstreaming.test.ts | 4 ++-- packages/core/src/semanticAttributes.ts | 6 ------ packages/core/src/tracing/spans/captureSpan.ts | 5 ++--- .../core/test/lib/tracing/spans/captureSpan.test.ts | 11 +++++------ yarn.lock | 2 +- 18 files changed, 52 insertions(+), 55 deletions(-) diff --git a/dev-packages/browser-integration-tests/package.json b/dev-packages/browser-integration-tests/package.json index 50ef6c483135..ca00e7f20d53 100644 --- a/dev-packages/browser-integration-tests/package.json +++ b/dev-packages/browser-integration-tests/package.json @@ -63,6 +63,7 @@ "@sentry/browser": "10.63.0", "@sentry/replay": "10.63.0", "@sentry/opentelemetry": "10.63.0", + "@sentry/conventions": "0.15.1", "@supabase/supabase-js": "2.49.3", "axios": "1.16.0", "babel-loader": "^10.1.1", diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/streamed/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/streamed/test.ts index 6b1d532f1436..624f565a9369 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/streamed/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/streamed/test.ts @@ -12,11 +12,11 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SEMANTIC_ATTRIBUTE_SENTRY_STATUS_MESSAGE, - SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { shouldSkipTracingTest } from '../../../../utils/helpers'; import { waitForStreamedSpanEnvelope } from '../../../../utils/spanUtils'; +import { SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes'; sentryTest( 'sends a streamed span envelope if spanStreamingIntegration is enabled', @@ -101,7 +101,7 @@ sentryTest( type: 'string', value: 'production', }, - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream', }, @@ -141,7 +141,7 @@ sentryTest( type: 'string', value: 'production', }, - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream', }, @@ -185,7 +185,7 @@ sentryTest( type: 'string', value: 'Connection Refused', }, - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream', }, @@ -265,7 +265,7 @@ sentryTest( type: 'string', value: 'production', }, - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream', }, diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/interactions-streamed/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/interactions-streamed/test.ts index 327aac7972cf..bcd9e0a7a9ba 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/interactions-streamed/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/interactions-streamed/test.ts @@ -11,8 +11,8 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID, SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, - SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, } from '@sentry/core'; +import { SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes'; import { sentryTest } from '../../../../utils/fixtures'; import { shouldSkipTracingTest } from '../../../../utils/helpers'; import { getSpanOp, waitForStreamedSpan, waitForStreamedSpans } from '../../../../utils/spanUtils'; @@ -43,7 +43,7 @@ sentryTest('captures streamed interaction span tree. @firefox', async ({ browser expect(interactionSegmentSpan).toEqual({ attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream', }, @@ -127,7 +127,7 @@ sentryTest('captures streamed interaction span tree. @firefox', async ({ browser const interactionSpan = interactionSpanTree.find(span => getSpanOp(span) === 'ui.interaction.click'); expect(interactionSpan).toEqual({ attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream', }, diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/navigation-streamed/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/navigation-streamed/test.ts index 54128df8b210..6f08a47cb624 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/navigation-streamed/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/navigation-streamed/test.ts @@ -7,8 +7,8 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SDK_INTEGRATIONS, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, - SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, } from '@sentry/core'; +import { SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes'; import { sentryTest } from '../../../../utils/fixtures'; import { shouldSkipTracingTest } from '../../../../utils/helpers'; import { @@ -72,7 +72,7 @@ sentryTest('starts a streamed navigation span on page navigation', async ({ brow expect(navigationSpan).toEqual({ attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream', }, diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-streamed/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-streamed/test.ts index bed58af888b0..16791d22a212 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-streamed/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-streamed/test.ts @@ -11,8 +11,8 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID, SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, - SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, } from '@sentry/core'; +import { SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes'; import { sentryTest } from '../../../../utils/fixtures'; import { shouldSkipTracingTest } from '../../../../utils/helpers'; import { getSpanOp, getSpansFromEnvelope, waitForStreamedSpanEnvelope } from '../../../../utils/spanUtils'; @@ -65,10 +65,6 @@ sentryTest( expect(pageloadSpan).toEqual({ attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { - type: 'string', - value: 'stream', - }, 'culture.calendar': { type: 'string', value: expect.any(String), @@ -169,6 +165,10 @@ sentryTest( type: 'string', value: 'production', }, + [SENTRY_TRACE_LIFECYCLE]: { + type: 'string', + value: 'stream', + }, }, end_timestamp: expect.any(Number), is_segment: true, diff --git a/dev-packages/cloudflare-integration-tests/package.json b/dev-packages/cloudflare-integration-tests/package.json index f7f2045059d9..ca5d894fcb04 100644 --- a/dev-packages/cloudflare-integration-tests/package.json +++ b/dev-packages/cloudflare-integration-tests/package.json @@ -21,6 +21,7 @@ "devDependencies": { "@cloudflare/workers-types": "^4.20260426.0", "@sentry-internal/test-utils": "10.63.0", + "@sentry/conventions": "0.15.1", "eslint-plugin-regexp": "^3.1.0", "vitest": "^3.2.6", "wrangler": "4.86.0" diff --git a/dev-packages/cloudflare-integration-tests/suites/public-api/startSpan-streamed/test.ts b/dev-packages/cloudflare-integration-tests/suites/public-api/startSpan-streamed/test.ts index c21799da7c6f..9d1280f64034 100644 --- a/dev-packages/cloudflare-integration-tests/suites/public-api/startSpan-streamed/test.ts +++ b/dev-packages/cloudflare-integration-tests/suites/public-api/startSpan-streamed/test.ts @@ -12,8 +12,8 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID, SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, - SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, } from '@sentry/core'; +import { SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes'; import { expect, it } from 'vitest'; import { createRunner } from '../../../runner'; @@ -78,7 +78,7 @@ it('sends a streamed span envelope with correct spans for a manually started spa expect(childSpan).toBeDefined(); expect(childSpan).toEqual({ attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'test-child', @@ -105,7 +105,7 @@ it('sends a streamed span envelope with correct spans for a manually started spa expect(inactiveSpan).toBeDefined(); expect(inactiveSpan).toEqual({ attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: { type: 'string', value: 'manual' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: CLOUDFLARE_SDK }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION }, @@ -141,7 +141,7 @@ it('sends a streamed span envelope with correct spans for a manually started spa expect(manualSpan).toBeDefined(); expect(manualSpan).toEqual({ attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: { type: 'string', value: 'manual' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: CLOUDFLARE_SDK }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION }, @@ -162,7 +162,7 @@ it('sends a streamed span envelope with correct spans for a manually started spa expect(parentTestSpan).toEqual({ attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'test' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: CLOUDFLARE_SDK }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION }, @@ -184,7 +184,7 @@ it('sends a streamed span envelope with correct spans for a manually started spa expect(segmentSpan).toEqual({ attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: CLOUDFLARE_SDK }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_INTEGRATIONS]: { diff --git a/dev-packages/e2e-tests/test-applications/deno-streamed/tests/spans.test.ts b/dev-packages/e2e-tests/test-applications/deno-streamed/tests/spans.test.ts index ef8883aacef4..f6d3029db39a 100644 --- a/dev-packages/e2e-tests/test-applications/deno-streamed/tests/spans.test.ts +++ b/dev-packages/e2e-tests/test-applications/deno-streamed/tests/spans.test.ts @@ -3,7 +3,7 @@ import { waitForStreamedSpans, getSpanOp } from '@sentry-internal/test-utils'; const SEGMENT_SPAN = { attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + ['sentry.trace_lifecycle']: { type: 'string', value: 'stream', }, @@ -174,7 +174,7 @@ test('Sends streamed spans (http.server and manual with Sentry.startSpan)', asyn expect(spans).toEqual([ { attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + ['sentry.trace_lifecycle']: { type: 'string', value: 'stream', }, @@ -246,7 +246,7 @@ test('OTel span appears as child of Sentry span (interop)', async ({ baseURL }) expect(sentrySpan).toEqual({ attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + ['sentry.trace_lifecycle']: { type: 'string', value: 'stream', }, @@ -287,7 +287,7 @@ test('OTel span appears as child of Sentry span (interop)', async ({ baseURL }) expect(otelSpan).toEqual({ attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + ['sentry.trace_lifecycle']: { type: 'string', value: 'stream', }, diff --git a/dev-packages/node-core-integration-tests/package.json b/dev-packages/node-core-integration-tests/package.json index 339c81f55ea1..5e70a70a4659 100644 --- a/dev-packages/node-core-integration-tests/package.json +++ b/dev-packages/node-core-integration-tests/package.json @@ -50,6 +50,7 @@ "yargs": "^16.2.0" }, "devDependencies": { + "@sentry/conventions": "0.15.1", "@types/node-cron": "^3.0.11", "@types/node-schedule": "^2.1.7", "eslint-plugin-regexp": "^3.1.0", diff --git a/dev-packages/node-core-integration-tests/suites/public-api/startSpan/basic-usage-streamed/test.ts b/dev-packages/node-core-integration-tests/suites/public-api/startSpan/basic-usage-streamed/test.ts index b7329ead23b7..567fea6f81d4 100644 --- a/dev-packages/node-core-integration-tests/suites/public-api/startSpan/basic-usage-streamed/test.ts +++ b/dev-packages/node-core-integration-tests/suites/public-api/startSpan/basic-usage-streamed/test.ts @@ -10,8 +10,8 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID, SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, - SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, } from '@sentry/core'; +import { SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes'; import { expect, test } from 'vitest'; import { createRunner } from '../../../../utils/runner'; @@ -54,7 +54,7 @@ test('sends a streamed span envelope with correct spans for a manually started s expect(childSpan).toBeDefined(); expect(childSpan).toEqual({ attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'test-child', @@ -82,7 +82,7 @@ test('sends a streamed span envelope with correct spans for a manually started s expect(inactiveSpan).toBeDefined(); expect(inactiveSpan).toEqual({ attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: 'sentry.javascript.node-core' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION }, [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID]: { type: 'string', value: segmentSpanId }, @@ -119,7 +119,7 @@ test('sends a streamed span envelope with correct spans for a manually started s expect(manualSpan).toBeDefined(); expect(manualSpan).toEqual({ attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: 'sentry.javascript.node-core' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION }, [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID]: { type: 'string', value: segmentSpanId }, @@ -140,7 +140,7 @@ test('sends a streamed span envelope with correct spans for a manually started s }); const expectedAttributes: Record = { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'test' }, [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: { type: 'integer', value: 1 }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: 'sentry.javascript.node-core' }, diff --git a/dev-packages/node-integration-tests/package.json b/dev-packages/node-integration-tests/package.json index c60d7d3ee0fe..d1acf8239f1a 100644 --- a/dev-packages/node-integration-tests/package.json +++ b/dev-packages/node-integration-tests/package.json @@ -100,6 +100,7 @@ "yargs": "^16.2.0" }, "devDependencies": { + "@sentry/conventions": "0.15.1", "@sentry-internal/test-utils": "10.63.0", "@types/amqplib": "^0.10.5", "@types/node-cron": "^3.0.11", diff --git a/dev-packages/node-integration-tests/suites/public-api/startSpan/basic-usage-streamed/test.ts b/dev-packages/node-integration-tests/suites/public-api/startSpan/basic-usage-streamed/test.ts index 0f46fb143ed2..4bd43379f914 100644 --- a/dev-packages/node-integration-tests/suites/public-api/startSpan/basic-usage-streamed/test.ts +++ b/dev-packages/node-integration-tests/suites/public-api/startSpan/basic-usage-streamed/test.ts @@ -11,8 +11,8 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID, SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, - SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, } from '@sentry/core'; +import { SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes'; import { expect, test } from 'vitest'; import { createRunner } from '../../../../utils/runner'; @@ -55,7 +55,7 @@ test('sends a streamed span envelope with correct spans for a manually started s expect(childSpan).toBeDefined(); expect(childSpan).toEqual({ attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'test-child', @@ -84,7 +84,7 @@ test('sends a streamed span envelope with correct spans for a manually started s expect(inactiveSpan).toBeDefined(); expect(inactiveSpan).toEqual({ attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: 'sentry.javascript.node' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION }, [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID]: { type: 'string', value: segmentSpanId }, @@ -122,7 +122,7 @@ test('sends a streamed span envelope with correct spans for a manually started s expect(manualSpan).toBeDefined(); expect(manualSpan).toEqual({ attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: 'sentry.javascript.node' }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION }, [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID]: { type: 'string', value: segmentSpanId }, @@ -144,7 +144,7 @@ test('sends a streamed span envelope with correct spans for a manually started s }); const expectedAttributes: Record = { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'test' }, [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: { type: 'integer', value: 1 }, [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: 'sentry.javascript.node' }, diff --git a/dev-packages/node-integration-tests/suites/tracing/postgres-streamed/test.ts b/dev-packages/node-integration-tests/suites/tracing/postgres-streamed/test.ts index 50d7b2741a60..e6d4e1300866 100644 --- a/dev-packages/node-integration-tests/suites/tracing/postgres-streamed/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/postgres-streamed/test.ts @@ -1,5 +1,6 @@ -import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_OP } from '@sentry/core'; import type { SerializedStreamedSpanContainer } from '@sentry/core'; +import { SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes'; import { afterAll, describe, expect } from 'vitest'; import { conditionalTest, isOrchestrionEnabled } from '../../../utils'; import { cleanupChildProcesses, createEsmAndCjsTests } from '../../../utils/runner'; @@ -75,7 +76,7 @@ const COMMON_DB_ATTRIBUTES = { type: 'string', value: 'task', }, - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream', }, diff --git a/packages/browser/test/integrations/spanstreaming.test.ts b/packages/browser/test/integrations/spanstreaming.test.ts index e34dacc9da6c..dd5268dab4ec 100644 --- a/packages/browser/test/integrations/spanstreaming.test.ts +++ b/packages/browser/test/integrations/spanstreaming.test.ts @@ -3,8 +3,8 @@ import { debug, SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT, SEMANTIC_ATTRIBUTE_SENTRY_SDK_INTEGRATIONS, - SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, } from '@sentry/core/browser'; +import { SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { BrowserClient, spanStreamingIntegration } from '../../src'; import { getDefaultBrowserClientOptions } from '../helper/browser-client-options'; @@ -138,7 +138,7 @@ describe('spanStreamingIntegration', () => { start_timestamp: expect.any(Number), status: 'ok', attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream', }, diff --git a/packages/core/src/semanticAttributes.ts b/packages/core/src/semanticAttributes.ts index 8976b8bded6d..8df3b5e8b013 100644 --- a/packages/core/src/semanticAttributes.ts +++ b/packages/core/src/semanticAttributes.ts @@ -65,12 +65,6 @@ export const SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION = 'sentry.sdk.version'; /** The list of integrations enabled in the Sentry SDK (e.g., ["InboundFilters", "BrowserTracing"]) */ export const SEMANTIC_ATTRIBUTE_SENTRY_SDK_INTEGRATIONS = 'sentry.sdk.integrations'; -/** - * Indicates the trace lifecycle mode with which a span was sent by the SDK. - * Either "stream" (streamed span) or "static" (transaction-sent span). - */ -export const SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE = 'sentry.trace_lifecycle'; - /** The user ID */ export const SEMANTIC_ATTRIBUTE_USER_ID = 'user.id'; /** The user email */ diff --git a/packages/core/src/tracing/spans/captureSpan.ts b/packages/core/src/tracing/spans/captureSpan.ts index 0f25cd845409..748c90f5c615 100644 --- a/packages/core/src/tracing/spans/captureSpan.ts +++ b/packages/core/src/tracing/spans/captureSpan.ts @@ -10,7 +10,6 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID, SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, - SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, SEMANTIC_ATTRIBUTE_USER_EMAIL, SEMANTIC_ATTRIBUTE_USER_ID, SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS, @@ -28,7 +27,7 @@ import { getCapturedScopesOnSpan } from '../utils'; import { isStreamedBeforeSendSpanCallback } from './beforeSendSpan'; import { scopeContextsToSpanAttributes } from './scopeContextAttributes'; import { DEFAULT_ENVIRONMENT } from '../../constants'; -import { SENTRY_SPAN_SOURCE } from '@sentry/conventions/attributes'; +import { SENTRY_SPAN_SOURCE, SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes'; export type SerializedStreamedSpanWithSegmentSpan = SerializedStreamedSpan & { _segmentSpan: Span; @@ -139,7 +138,7 @@ function applyCommonSpanAttributes( // avoid overwriting any previously set attributes (from users or potentially our SDK instrumentation) safeSetSpanJSONAttributes(spanJSON, { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: 'stream', + [SENTRY_TRACE_LIFECYCLE]: 'stream', [SEMANTIC_ATTRIBUTE_SENTRY_RELEASE]: release, [SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT]: environment || DEFAULT_ENVIRONMENT, [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME]: serializedSegmentSpan.name, diff --git a/packages/core/test/lib/tracing/spans/captureSpan.test.ts b/packages/core/test/lib/tracing/spans/captureSpan.test.ts index 47da9abe5578..e2b81fbd85df 100644 --- a/packages/core/test/lib/tracing/spans/captureSpan.test.ts +++ b/packages/core/test/lib/tracing/spans/captureSpan.test.ts @@ -13,7 +13,6 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID, SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, - SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE, SEMANTIC_ATTRIBUTE_USER_EMAIL, SEMANTIC_ATTRIBUTE_USER_ID, SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS, @@ -26,7 +25,7 @@ import { import { safeSetSpanJSONAttributes } from '../../../../src/tracing/spans/captureSpan'; import { scopeContextsToSpanAttributes } from '../../../../src/tracing/spans/scopeContextAttributes'; import { getDefaultTestClientOptions, TestClient } from '../../../mocks/client'; -import { SENTRY_SPAN_SOURCE } from '@sentry/conventions/attributes'; +import { SENTRY_SPAN_SOURCE, SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes'; describe('captureSpan', () => { it.each([true, false, undefined])( @@ -68,7 +67,7 @@ describe('captureSpan', () => { status: 'ok', is_segment: true, attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream', }, @@ -209,7 +208,7 @@ describe('captureSpan', () => { value: 'staging', type: 'string', }, - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + [SENTRY_TRACE_LIFECYCLE]: { value: 'stream', type: 'string', }, @@ -309,7 +308,7 @@ describe('captureSpan', () => { value: 'production', type: 'string', }, - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { + [SENTRY_TRACE_LIFECYCLE]: { value: 'stream', type: 'string', }, @@ -357,7 +356,7 @@ describe('captureSpan', () => { status: 'ok', is_segment: true, attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, + [SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' }, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'http.client' }, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: { type: 'string', value: 'manual' }, [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: { type: 'integer', value: 1 }, diff --git a/yarn.lock b/yarn.lock index 4e94f640b6d5..6f0cbc213b09 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7482,7 +7482,7 @@ "@sentry/cli-win32-i686" "2.58.6" "@sentry/cli-win32-x64" "2.58.6" -"@sentry/conventions@^0.15.1": +"@sentry/conventions@0.15.1", "@sentry/conventions@^0.15.1": version "0.15.1" resolved "https://registry.yarnpkg.com/@sentry/conventions/-/conventions-0.15.1.tgz#5b8888862d1e444678938f5afdd7842bca42f7cc" integrity sha512-ZLP8bRdMON3prWE2tJyImuYscCxdcJeIPIhrOs/rgyFm3C1nCh1B6gdvPj3AZ5zW08oSFFCsq7T+tYEW3h8MNA== From a81d494a4284671da1fe5c1f39e0e948754c6f71 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 2 Jul 2026 14:05:23 +0200 Subject: [PATCH 3/3] fix mysql test --- .../node-integration-tests/suites/tracing/mysql/test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dev-packages/node-integration-tests/suites/tracing/mysql/test.ts b/dev-packages/node-integration-tests/suites/tracing/mysql/test.ts index 0cf5e04c1932..fdb936cf3d70 100644 --- a/dev-packages/node-integration-tests/suites/tracing/mysql/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/mysql/test.ts @@ -5,6 +5,7 @@ import { startMysqlTestServer } from './mysql-test-server'; import type { SerializedStreamedSpanContainer } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP } from '@sentry/core'; import { isOrchestrionEnabled } from '../../../utils'; +import { SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes'; describe('mysql auto instrumentation', () => { // A minimal in-process MySQL server (on a random free port) so the client's @@ -266,6 +267,10 @@ describe('mysql auto instrumentation', () => { type: 'string', value: 'task', }, + [SENTRY_TRACE_LIFECYCLE]: { + type: 'string', + value: 'stream', + }, }; const COMMON_SPAN_PROPS = {