diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans-with-parentSpanId/subject.js b/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans-with-parentSpanId/subject.js index 56c0e05a269c..85a9847e1c3f 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans-with-parentSpanId/subject.js +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans-with-parentSpanId/subject.js @@ -1,6 +1,5 @@ Sentry.getCurrentScope().setPropagationContext({ parentSpanId: '1234567890123456', - spanId: '123456789012345x', traceId: '12345678901234567890123456789012', }); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/init.js b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/init.js new file mode 100644 index 000000000000..c026daa1eed9 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/init.js @@ -0,0 +1,12 @@ +import * as Sentry from '@sentry/browser'; + +window.Sentry = Sentry; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + integrations: integrations => { + integrations.push(Sentry.browserTracingIntegration()); + return integrations.filter(i => i.name !== 'BrowserSession'); + }, + tracesSampleRate: 0, +}); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/subject.js b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/subject.js new file mode 100644 index 000000000000..b7d62f8cfb95 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/subject.js @@ -0,0 +1,2 @@ +Sentry.captureException(new Error('test error')); +Sentry.captureException(new Error('test error 2')); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/template.html b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/template.html new file mode 100644 index 000000000000..22d155bf8648 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/template.html @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/test.ts new file mode 100644 index 000000000000..5bed055dbc0a --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors-meta/test.ts @@ -0,0 +1,35 @@ +import { expect } from '@playwright/test'; +import type { Event } from '@sentry/browser'; +import { sentryTest } from '../../../../utils/fixtures'; +import { getMultipleSentryEnvelopeRequests, shouldSkipTracingTest } from '../../../../utils/helpers'; + +sentryTest('errors in TwP mode have same trace ID & span IDs', async ({ getLocalTestUrl, page }) => { + if (shouldSkipTracingTest()) { + sentryTest.skip(); + } + + const traceId = '12312012123120121231201212312012'; + const spanId = '1121201211212012'; + + const url = await getLocalTestUrl({ testDir: __dirname }); + const [event1, event2] = await getMultipleSentryEnvelopeRequests(page, 2, { url }); + + // Ensure these are the actual errors we care about + expect(event1.exception?.values?.[0].value).toContain('test error'); + expect(event2.exception?.values?.[0].value).toContain('test error'); + + const contexts1 = event1.contexts; + const { trace_id: traceId1, span_id: spanId1 } = contexts1?.trace || {}; + expect(traceId1).toEqual(traceId); + + // Span ID is a virtual span, not the propagated one + expect(spanId1).not.toEqual(spanId); + expect(spanId1).toMatch(/^[a-f0-9]{16}$/); + + const contexts2 = event2.contexts; + const { trace_id: traceId2, span_id: spanId2 } = contexts2?.trace || {}; + expect(traceId2).toEqual(traceId); + expect(spanId2).toMatch(/^[a-f0-9]{16}$/); + + expect(spanId2).toEqual(spanId1); +}); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/init.js b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/init.js new file mode 100644 index 000000000000..c026daa1eed9 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/init.js @@ -0,0 +1,12 @@ +import * as Sentry from '@sentry/browser'; + +window.Sentry = Sentry; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + integrations: integrations => { + integrations.push(Sentry.browserTracingIntegration()); + return integrations.filter(i => i.name !== 'BrowserSession'); + }, + tracesSampleRate: 0, +}); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/subject.js b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/subject.js new file mode 100644 index 000000000000..b7d62f8cfb95 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/subject.js @@ -0,0 +1,2 @@ +Sentry.captureException(new Error('test error')); +Sentry.captureException(new Error('test error 2')); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/test.ts new file mode 100644 index 000000000000..3048de92b2f1 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/twp-errors/test.ts @@ -0,0 +1,30 @@ +import { expect } from '@playwright/test'; +import type { Event } from '@sentry/browser'; +import { sentryTest } from '../../../../utils/fixtures'; +import { getMultipleSentryEnvelopeRequests, shouldSkipTracingTest } from '../../../../utils/helpers'; + +sentryTest('errors in TwP mode have same trace ID & span IDs', async ({ getLocalTestUrl, page }) => { + if (shouldSkipTracingTest()) { + sentryTest.skip(); + } + + const url = await getLocalTestUrl({ testDir: __dirname }); + const [event1, event2] = await getMultipleSentryEnvelopeRequests(page, 2, { url }); + + // Ensure these are the actual errors we care about + expect(event1.exception?.values?.[0].value).toContain('test error'); + expect(event2.exception?.values?.[0].value).toContain('test error'); + + const contexts1 = event1.contexts; + const { trace_id: traceId1, span_id: spanId1 } = contexts1?.trace || {}; + expect(traceId1).toMatch(/^[a-f0-9]{32}$/); + expect(spanId1).toMatch(/^[a-f0-9]{16}$/); + + const contexts2 = event2.contexts; + const { trace_id: traceId2, span_id: spanId2 } = contexts2?.trace || {}; + expect(traceId2).toMatch(/^[a-f0-9]{32}$/); + expect(spanId2).toMatch(/^[a-f0-9]{16}$/); + + expect(traceId2).toEqual(traceId1); + expect(spanId2).toEqual(spanId1); +}); diff --git a/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-root-spans/scenario.ts b/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-root-spans/scenario.ts index e352fff5c02c..9275f9fe4505 100644 --- a/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-root-spans/scenario.ts +++ b/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-root-spans/scenario.ts @@ -10,7 +10,6 @@ Sentry.init({ Sentry.getCurrentScope().setPropagationContext({ parentSpanId: '1234567890123456', - spanId: '123456789012345x', traceId: '12345678901234567890123456789012', }); diff --git a/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope-with-parentSpanId/scenario.ts b/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope-with-parentSpanId/scenario.ts index 7c4f702f5df8..cbd2dd023f37 100644 --- a/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope-with-parentSpanId/scenario.ts +++ b/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope-with-parentSpanId/scenario.ts @@ -11,7 +11,6 @@ Sentry.init({ Sentry.withScope(scope => { scope.setPropagationContext({ parentSpanId: '1234567890123456', - spanId: '123456789012345x', traceId: '12345678901234567890123456789012', }); diff --git a/dev-packages/node-integration-tests/suites/tracing/meta-tags-twp-errors/test.ts b/dev-packages/node-integration-tests/suites/tracing/meta-tags-twp-errors/test.ts index 9abb7b1a631c..d4447255bf51 100644 --- a/dev-packages/node-integration-tests/suites/tracing/meta-tags-twp-errors/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/meta-tags-twp-errors/test.ts @@ -5,6 +5,7 @@ describe('errors in TwP mode have same trace in trace context and getTraceData() cleanupChildProcesses(); }); + // In a request handler, the spanId is consistent inside of the request test('in incoming request', done => { createRunner(__dirname, 'server.js') .expect({ @@ -30,6 +31,7 @@ describe('errors in TwP mode have same trace in trace context and getTraceData() .makeRequest('get', '/test'); }); + // Outside of a request handler, the spanId is random test('outside of a request handler', done => { createRunner(__dirname, 'no-server.js') .expect({ @@ -41,11 +43,18 @@ describe('errors in TwP mode have same trace in trace context and getTraceData() const traceData = contexts?.traceData || {}; - expect(traceData['sentry-trace']).toEqual(`${trace_id}-${span_id}`); + expect(traceData['sentry-trace']).toMatch(/^[a-f0-9]{32}-[a-f0-9]{16}$/); + expect(traceData['sentry-trace']).toContain(`${trace_id}-`); + // span_id is a random span ID + expect(traceData['sentry-trace']).not.toContain(span_id); + expect(traceData.baggage).toContain(`sentry-trace_id=${trace_id}`); expect(traceData.baggage).not.toContain('sentry-sampled='); - expect(traceData.metaTags).toContain(``); + expect(traceData.metaTags).toMatch(//); + expect(traceData.metaTags).toContain(` { scope.setPropagationContext({ traceId: 'd4cda95b652f4a1592b449d5929fda1b', parentSpanId: '6e0c63257de34c93', - spanId: '6e0c63257de34c92', sampled: true, }); @@ -59,7 +58,7 @@ describe('SentryPropagator', () => { 'sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b', ].sort(), ); - expect(carrier[SENTRY_TRACE_HEADER]).toBe('d4cda95b652f4a1592b449d5929fda1b-6e0c63257de34c92-1'); + expect(carrier[SENTRY_TRACE_HEADER]).toMatch(/d4cda95b652f4a1592b449d5929fda1b-[a-f0-9]{16}-1/); }); }); @@ -68,7 +67,6 @@ describe('SentryPropagator', () => { scope.setPropagationContext({ traceId: 'd4cda95b652f4a1592b449d5929fda1b', parentSpanId: '6e0c63257de34c93', - spanId: '6e0c63257de34c92', sampled: true, dsc: { transaction: 'sampled-transaction', @@ -96,7 +94,7 @@ describe('SentryPropagator', () => { 'sentry-replay_id=dsc_replay_id', ].sort(), ); - expect(carrier[SENTRY_TRACE_HEADER]).toBe('d4cda95b652f4a1592b449d5929fda1b-6e0c63257de34c92-1'); + expect(carrier[SENTRY_TRACE_HEADER]).toMatch(/d4cda95b652f4a1592b449d5929fda1b-[a-f0-9]{16}-1/); }); }); @@ -322,7 +320,6 @@ describe('SentryPropagator', () => { scope.setPropagationContext({ traceId: 'TRACE_ID', parentSpanId: 'PARENT_SPAN_ID', - spanId: 'SPAN_ID', sampled: true, }); @@ -362,7 +359,6 @@ describe('SentryPropagator', () => { scope.setPropagationContext({ traceId: 'TRACE_ID', parentSpanId: 'PARENT_SPAN_ID', - spanId: 'SPAN_ID', sampled: true, }); @@ -399,7 +395,6 @@ describe('SentryPropagator', () => { scope.setPropagationContext({ traceId: 'TRACE_ID', parentSpanId: 'PARENT_SPAN_ID', - spanId: 'SPAN_ID', sampled: true, }); @@ -601,7 +596,6 @@ describe('SentryPropagator', () => { const context = propagator.extract(ROOT_CONTEXT, carrier, defaultTextMapGetter); expect(trace.getSpanContext(context)).toEqual(undefined); expect(getCurrentScope().getPropagationContext()).toEqual({ - spanId: expect.stringMatching(/[a-f0-9]{16}/), traceId: expect.stringMatching(/[a-f0-9]{32}/), }); }); @@ -652,7 +646,6 @@ describe('SentryPropagator', () => { const context = propagator.extract(ROOT_CONTEXT, carrier, defaultTextMapGetter); expect(trace.getSpanContext(context)).toEqual(undefined); expect(getCurrentScope().getPropagationContext()).toEqual({ - spanId: expect.stringMatching(/[a-f0-9]{16}/), traceId: expect.stringMatching(/[a-f0-9]{32}/), }); }); diff --git a/packages/opentelemetry/test/trace.test.ts b/packages/opentelemetry/test/trace.test.ts index 6852b8b40988..cbded44a6139 100644 --- a/packages/opentelemetry/test/trace.test.ts +++ b/packages/opentelemetry/test/trace.test.ts @@ -1545,8 +1545,6 @@ describe('continueTrace', () => { }); expect(scope.getPropagationContext()).toEqual({ - sampled: undefined, - spanId: expect.any(String), traceId: expect.any(String), }); @@ -1554,7 +1552,7 @@ describe('continueTrace', () => { }); it('works with trace data', () => { - const scope = continueTrace( + continueTrace( { sentryTrace: '12312012123120121231201212312012-1121201211212012-0', baggage: undefined, @@ -1570,21 +1568,12 @@ describe('continueTrace', () => { }); expect(getSamplingDecision(span.spanContext())).toBe(false); expect(spanIsSampled(span)).toBe(false); - - return getCurrentScope(); }, ); - - expect(scope.getPropagationContext()).toEqual({ - spanId: expect.any(String), - traceId: expect.any(String), - }); - - expect(scope.getScopeData().sdkProcessingMetadata).toEqual({}); }); it('works with trace & baggage data', () => { - const scope = continueTrace( + continueTrace( { sentryTrace: '12312012123120121231201212312012-1121201211212012-1', baggage: 'sentry-version=1.0,sentry-environment=production', @@ -1600,21 +1589,12 @@ describe('continueTrace', () => { }); expect(getSamplingDecision(span.spanContext())).toBe(true); expect(spanIsSampled(span)).toBe(true); - - return getCurrentScope(); }, ); - - expect(scope.getPropagationContext()).toEqual({ - spanId: expect.any(String), - traceId: expect.any(String), - }); - - expect(scope.getScopeData().sdkProcessingMetadata).toEqual({}); }); it('works with trace & 3rd party baggage data', () => { - const scope = continueTrace( + continueTrace( { sentryTrace: '12312012123120121231201212312012-1121201211212012-1', baggage: 'sentry-version=1.0,sentry-environment=production,dogs=great,cats=boring', @@ -1630,16 +1610,8 @@ describe('continueTrace', () => { }); expect(getSamplingDecision(span.spanContext())).toBe(true); expect(spanIsSampled(span)).toBe(true); - - return getCurrentScope(); }, ); - - expect(scope.getPropagationContext()).toEqual({ - spanId: expect.any(String), - traceId: expect.any(String), - }); - expect(scope.getScopeData().sdkProcessingMetadata).toEqual({}); }); it('returns response of callback', () => { diff --git a/packages/opentelemetry/test/utils/getTraceData.test.ts b/packages/opentelemetry/test/utils/getTraceData.test.ts index e0f2270d8e22..f18f1c307639 100644 --- a/packages/opentelemetry/test/utils/getTraceData.test.ts +++ b/packages/opentelemetry/test/utils/getTraceData.test.ts @@ -55,7 +55,6 @@ describe('getTraceData', () => { getCurrentScope().setPropagationContext({ traceId: '12345678901234567890123456789012', sampled: true, - spanId: '1234567890123456', dsc: { environment: 'staging', public_key: 'key', @@ -65,10 +64,10 @@ describe('getTraceData', () => { const traceData = getTraceData(); - expect(traceData).toEqual({ - 'sentry-trace': '12345678901234567890123456789012-1234567890123456-1', - baggage: 'sentry-environment=staging,sentry-public_key=key,sentry-trace_id=12345678901234567890123456789012', - }); + expect(traceData['sentry-trace']).toMatch(/^12345678901234567890123456789012-[a-f0-9]{16}-1$/); + expect(traceData.baggage).toEqual( + 'sentry-environment=staging,sentry-public_key=key,sentry-trace_id=12345678901234567890123456789012', + ); }); it('works with an span with frozen DSC in traceState', () => {