Skip to content

Commit 3e5d2ae

Browse files
authored
feat(core): Add sentry.trace_lifecycle attribute (#21850)
Adds a [new attribute](https://getsentry.github.io/sentry-conventions/attributes/sentry/#sentry-trace_lifecycle) that allows us to clearly identify streamed spans in the product. closes #21750
1 parent aa7a30b commit 3e5d2ae

18 files changed

Lines changed: 104 additions & 3 deletions

File tree

dev-packages/browser-integration-tests/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
"@sentry/browser": "10.63.0",
6464
"@sentry/replay": "10.63.0",
6565
"@sentry/opentelemetry": "10.63.0",
66+
"@sentry/conventions": "0.15.1",
6667
"@supabase/supabase-js": "2.49.3",
6768
"axios": "1.16.0",
6869
"babel-loader": "^10.1.1",

dev-packages/browser-integration-tests/suites/public-api/startSpan/streamed/test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
import { sentryTest } from '../../../../utils/fixtures';
1717
import { shouldSkipTracingTest } from '../../../../utils/helpers';
1818
import { waitForStreamedSpanEnvelope } from '../../../../utils/spanUtils';
19+
import { SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes';
1920

2021
sentryTest(
2122
'sends a streamed span envelope if spanStreamingIntegration is enabled',
@@ -100,6 +101,10 @@ sentryTest(
100101
type: 'string',
101102
value: 'production',
102103
},
104+
[SENTRY_TRACE_LIFECYCLE]: {
105+
type: 'string',
106+
value: 'stream',
107+
},
103108
},
104109
end_timestamp: expect.any(Number),
105110
is_segment: false,
@@ -136,6 +141,10 @@ sentryTest(
136141
type: 'string',
137142
value: 'production',
138143
},
144+
[SENTRY_TRACE_LIFECYCLE]: {
145+
type: 'string',
146+
value: 'stream',
147+
},
139148
},
140149
end_timestamp: expect.any(Number),
141150
is_segment: false,
@@ -176,6 +185,10 @@ sentryTest(
176185
type: 'string',
177186
value: 'Connection Refused',
178187
},
188+
[SENTRY_TRACE_LIFECYCLE]: {
189+
type: 'string',
190+
value: 'stream',
191+
},
179192
},
180193
end_timestamp: expect.any(Number),
181194
is_segment: false,
@@ -252,6 +265,10 @@ sentryTest(
252265
type: 'string',
253266
value: 'production',
254267
},
268+
[SENTRY_TRACE_LIFECYCLE]: {
269+
type: 'string',
270+
value: 'stream',
271+
},
255272
},
256273
end_timestamp: expect.any(Number),
257274
is_segment: true,

dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/interactions-streamed/test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME,
1313
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
1414
} from '@sentry/core';
15+
import { SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes';
1516
import { sentryTest } from '../../../../utils/fixtures';
1617
import { shouldSkipTracingTest } from '../../../../utils/helpers';
1718
import { getSpanOp, waitForStreamedSpan, waitForStreamedSpans } from '../../../../utils/spanUtils';
@@ -42,6 +43,10 @@ sentryTest('captures streamed interaction span tree. @firefox', async ({ browser
4243

4344
expect(interactionSegmentSpan).toEqual({
4445
attributes: {
46+
[SENTRY_TRACE_LIFECYCLE]: {
47+
type: 'string',
48+
value: 'stream',
49+
},
4550
'culture.calendar': {
4651
type: 'string',
4752
value: expect.any(String),
@@ -122,6 +127,10 @@ sentryTest('captures streamed interaction span tree. @firefox', async ({ browser
122127
const interactionSpan = interactionSpanTree.find(span => getSpanOp(span) === 'ui.interaction.click');
123128
expect(interactionSpan).toEqual({
124129
attributes: {
130+
[SENTRY_TRACE_LIFECYCLE]: {
131+
type: 'string',
132+
value: 'stream',
133+
},
125134
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: {
126135
type: 'string',
127136
value: 'ui.interaction.click',

dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/navigation-streamed/test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
SEMANTIC_ATTRIBUTE_SENTRY_SDK_INTEGRATIONS,
99
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
1010
} from '@sentry/core';
11+
import { SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes';
1112
import { sentryTest } from '../../../../utils/fixtures';
1213
import { shouldSkipTracingTest } from '../../../../utils/helpers';
1314
import {
@@ -71,6 +72,10 @@ sentryTest('starts a streamed navigation span on page navigation', async ({ brow
7172

7273
expect(navigationSpan).toEqual({
7374
attributes: {
75+
[SENTRY_TRACE_LIFECYCLE]: {
76+
type: 'string',
77+
value: 'stream',
78+
},
7479
'culture.calendar': {
7580
type: 'string',
7681
value: expect.any(String),

dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-streamed/test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME,
1313
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
1414
} from '@sentry/core';
15+
import { SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes';
1516
import { sentryTest } from '../../../../utils/fixtures';
1617
import { shouldSkipTracingTest } from '../../../../utils/helpers';
1718
import { getSpanOp, getSpansFromEnvelope, waitForStreamedSpanEnvelope } from '../../../../utils/spanUtils';
@@ -164,6 +165,10 @@ sentryTest(
164165
type: 'string',
165166
value: 'production',
166167
},
168+
[SENTRY_TRACE_LIFECYCLE]: {
169+
type: 'string',
170+
value: 'stream',
171+
},
167172
},
168173
end_timestamp: expect.any(Number),
169174
is_segment: true,

dev-packages/cloudflare-integration-tests/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"devDependencies": {
2222
"@cloudflare/workers-types": "^4.20260426.0",
2323
"@sentry-internal/test-utils": "10.63.0",
24+
"@sentry/conventions": "0.15.1",
2425
"eslint-plugin-regexp": "^3.1.0",
2526
"vitest": "^3.2.6",
2627
"wrangler": "4.86.0"

dev-packages/cloudflare-integration-tests/suites/public-api/startSpan-streamed/test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME,
1414
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
1515
} from '@sentry/core';
16+
import { SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes';
1617
import { expect, it } from 'vitest';
1718
import { createRunner } from '../../../runner';
1819

@@ -77,6 +78,7 @@ it('sends a streamed span envelope with correct spans for a manually started spa
7778
expect(childSpan).toBeDefined();
7879
expect(childSpan).toEqual({
7980
attributes: {
81+
[SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' },
8082
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: {
8183
type: 'string',
8284
value: 'test-child',
@@ -103,6 +105,7 @@ it('sends a streamed span envelope with correct spans for a manually started spa
103105
expect(inactiveSpan).toBeDefined();
104106
expect(inactiveSpan).toEqual({
105107
attributes: {
108+
[SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' },
106109
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: { type: 'string', value: 'manual' },
107110
[SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: CLOUDFLARE_SDK },
108111
[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
138141
expect(manualSpan).toBeDefined();
139142
expect(manualSpan).toEqual({
140143
attributes: {
144+
[SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' },
141145
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: { type: 'string', value: 'manual' },
142146
[SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: CLOUDFLARE_SDK },
143147
[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
158162

159163
expect(parentTestSpan).toEqual({
160164
attributes: {
165+
[SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' },
161166
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'test' },
162167
[SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: CLOUDFLARE_SDK },
163168
[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
179184

180185
expect(segmentSpan).toEqual({
181186
attributes: {
187+
[SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' },
182188
[SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: CLOUDFLARE_SDK },
183189
[SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION },
184190
[SEMANTIC_ATTRIBUTE_SENTRY_SDK_INTEGRATIONS]: {

dev-packages/e2e-tests/test-applications/deno-streamed/tests/spans.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import { waitForStreamedSpans, getSpanOp } from '@sentry-internal/test-utils';
33

44
const SEGMENT_SPAN = {
55
attributes: {
6+
['sentry.trace_lifecycle']: {
7+
type: 'string',
8+
value: 'stream',
9+
},
610
'app.start_time': {
711
type: 'string',
812
value: expect.any(String),
@@ -170,6 +174,10 @@ test('Sends streamed spans (http.server and manual with Sentry.startSpan)', asyn
170174
expect(spans).toEqual([
171175
{
172176
attributes: {
177+
['sentry.trace_lifecycle']: {
178+
type: 'string',
179+
value: 'stream',
180+
},
173181
'sentry.environment': {
174182
type: 'string',
175183
value: 'qa',
@@ -238,6 +246,10 @@ test('OTel span appears as child of Sentry span (interop)', async ({ baseURL })
238246

239247
expect(sentrySpan).toEqual({
240248
attributes: {
249+
['sentry.trace_lifecycle']: {
250+
type: 'string',
251+
value: 'stream',
252+
},
241253
'sentry.environment': {
242254
type: 'string',
243255
value: 'qa',
@@ -275,6 +287,10 @@ test('OTel span appears as child of Sentry span (interop)', async ({ baseURL })
275287

276288
expect(otelSpan).toEqual({
277289
attributes: {
290+
['sentry.trace_lifecycle']: {
291+
type: 'string',
292+
value: 'stream',
293+
},
278294
'sentry.environment': {
279295
type: 'string',
280296
value: 'qa',

dev-packages/node-core-integration-tests/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"yargs": "^16.2.0"
5151
},
5252
"devDependencies": {
53+
"@sentry/conventions": "0.15.1",
5354
"@types/node-cron": "^3.0.11",
5455
"@types/node-schedule": "^2.1.7",
5556
"eslint-plugin-regexp": "^3.1.0",

dev-packages/node-core-integration-tests/suites/public-api/startSpan/basic-usage-streamed/test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME,
1212
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
1313
} from '@sentry/core';
14+
import { SENTRY_TRACE_LIFECYCLE } from '@sentry/conventions/attributes';
1415
import { expect, test } from 'vitest';
1516
import { createRunner } from '../../../../utils/runner';
1617

@@ -53,6 +54,7 @@ test('sends a streamed span envelope with correct spans for a manually started s
5354
expect(childSpan).toBeDefined();
5455
expect(childSpan).toEqual({
5556
attributes: {
57+
[SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' },
5658
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: {
5759
type: 'string',
5860
value: 'test-child',
@@ -80,6 +82,7 @@ test('sends a streamed span envelope with correct spans for a manually started s
8082
expect(inactiveSpan).toBeDefined();
8183
expect(inactiveSpan).toEqual({
8284
attributes: {
85+
[SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' },
8386
[SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: 'sentry.javascript.node-core' },
8487
[SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION },
8588
[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
116119
expect(manualSpan).toBeDefined();
117120
expect(manualSpan).toEqual({
118121
attributes: {
122+
[SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' },
119123
[SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: 'sentry.javascript.node-core' },
120124
[SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: { type: 'string', value: SDK_VERSION },
121125
[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
136140
});
137141

138142
const expectedAttributes: Record<string, unknown> = {
143+
[SENTRY_TRACE_LIFECYCLE]: { type: 'string', value: 'stream' },
139144
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'test' },
140145
[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: { type: 'integer', value: 1 },
141146
[SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: { type: 'string', value: 'sentry.javascript.node-core' },

0 commit comments

Comments
 (0)