From d8307b2ce9459cf4b0cdab40c604e78417585483 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 21 May 2024 12:50:32 +0200 Subject: [PATCH 1/9] feat(core): Add `startNewTrace` function --- packages/astro/src/index.server.ts | 1 + packages/aws-serverless/src/index.ts | 1 + packages/browser/src/index.ts | 1 + packages/bun/src/index.ts | 1 + packages/core/src/tracing/index.ts | 1 + packages/core/src/tracing/trace.ts | 27 ++++++++++++++++++- packages/core/test/lib/tracing/trace.test.ts | 23 ++++++++++++++++ packages/deno/src/index.ts | 1 + packages/google-cloud-serverless/src/index.ts | 1 + packages/node/src/index.ts | 1 + packages/remix/src/index.server.ts | 1 + packages/sveltekit/src/server/index.ts | 1 + packages/vercel-edge/src/index.ts | 1 + 13 files changed, 60 insertions(+), 1 deletion(-) diff --git a/packages/astro/src/index.server.ts b/packages/astro/src/index.server.ts index a4f3ca59fb1f..6657b3030cb1 100644 --- a/packages/astro/src/index.server.ts +++ b/packages/astro/src/index.server.ts @@ -64,6 +64,7 @@ export { startSpan, startInactiveSpan, startSpanManual, + startNewTrace, withActiveSpan, getSpanDescendants, continueTrace, diff --git a/packages/aws-serverless/src/index.ts b/packages/aws-serverless/src/index.ts index 1d2323df06e5..62165a710127 100644 --- a/packages/aws-serverless/src/index.ts +++ b/packages/aws-serverless/src/index.ts @@ -62,6 +62,7 @@ export { startSpan, startInactiveSpan, startSpanManual, + startNewTrace, withActiveSpan, getRootSpan, getSpanDescendants, diff --git a/packages/browser/src/index.ts b/packages/browser/src/index.ts index 86e6ea20fe81..245eaa966859 100644 --- a/packages/browser/src/index.ts +++ b/packages/browser/src/index.ts @@ -59,6 +59,7 @@ export { startInactiveSpan, startSpanManual, withActiveSpan, + startNewTrace, getSpanDescendants, setMeasurement, getSpanStatusFromHttpCode, diff --git a/packages/bun/src/index.ts b/packages/bun/src/index.ts index fd7671b34b09..c3e8eff8beac 100644 --- a/packages/bun/src/index.ts +++ b/packages/bun/src/index.ts @@ -82,6 +82,7 @@ export { startSpan, startInactiveSpan, startSpanManual, + startNewTrace, withActiveSpan, getRootSpan, getSpanDescendants, diff --git a/packages/core/src/tracing/index.ts b/packages/core/src/tracing/index.ts index 90a5ac737aa1..0c08101acb68 100644 --- a/packages/core/src/tracing/index.ts +++ b/packages/core/src/tracing/index.ts @@ -17,6 +17,7 @@ export { continueTrace, withActiveSpan, suppressTracing, + startNewTrace, } from './trace'; export { getDynamicSamplingContextFromClient, diff --git a/packages/core/src/tracing/trace.ts b/packages/core/src/tracing/trace.ts index 4d910f54e996..ff6d4c26242c 100644 --- a/packages/core/src/tracing/trace.ts +++ b/packages/core/src/tracing/trace.ts @@ -1,5 +1,5 @@ import type { ClientOptions, Scope, SentrySpanArguments, Span, SpanTimeInput, StartSpanOptions } from '@sentry/types'; -import { propagationContextFromHeaders } from '@sentry/utils'; +import { propagationContextFromHeaders, uuid4 } from '@sentry/utils'; import type { AsyncContextStrategy } from '../asyncContext/types'; import { getMainCarrier } from '../carrier'; @@ -212,6 +212,24 @@ export function suppressTracing(callback: () => T): T { }); } +/** + * Starts a new trace by creating a new trace id. Spans started after this function is called + * will be part of the new trace instead of a potentially previous existing trace. + * + * Important: Only use this function if you want to override the default trace lifetime SDK. + * Please also note that as soon as you call this function, a previously distributed can no longer be + * continued. Instead, the newly created trace will also be the root of a new distributed trace. + * + * Default behavior: + * - Server-side: A new trace is started for each incoming request. + * - Browser: A new trace is started for each page our route. Navigating to a new route + * or page will automatically create a new trace. + */ +export function startNewTrace(): void { + getCurrentScope().setPropagationContext(generatePropagationContext()); + getIsolationScope().setPropagationContext(generatePropagationContext()); +} + function createChildOrRootSpan({ parentSpan, spanContext, @@ -394,3 +412,10 @@ function getParentSpan(scope: Scope): SentrySpan | undefined { return span; } + +function generatePropagationContext(): { traceId: string; spanId: string } { + return { + traceId: uuid4(), + spanId: uuid4().substring(16), + }; +} diff --git a/packages/core/test/lib/tracing/trace.test.ts b/packages/core/test/lib/tracing/trace.test.ts index f2aa8460dba4..39451e5c0f99 100644 --- a/packages/core/test/lib/tracing/trace.test.ts +++ b/packages/core/test/lib/tracing/trace.test.ts @@ -24,6 +24,7 @@ import { withActiveSpan, } from '../../../src/tracing'; import { SentryNonRecordingSpan } from '../../../src/tracing/sentryNonRecordingSpan'; +import { startNewTrace } from '../../../src/tracing/trace'; import { _setSpanForScope } from '../../../src/utils/spanOnScope'; import { getActiveSpan, getRootSpan, getSpanDescendants, spanIsSampled } from '../../../src/utils/spanUtils'; import { TestClient, getDefaultTestClientOptions } from '../../mocks/client'; @@ -1590,3 +1591,25 @@ describe('suppressTracing', () => { }); }); }); + +describe('startNewTrace', () => { + beforeEach(() => { + getCurrentScope().clear(); + getIsolationScope().clear(); + }); + + it('resets the propagation context on current scope and isolation scope', () => { + const oldIsolationScopeItraceId = getIsolationScope().getPropagationContext().traceId; + const oldCurrentScopeItraceId = getCurrentScope().getPropagationContext().traceId; + + startNewTrace(); + + const newIsolationScopeItraceId = getIsolationScope().getPropagationContext().traceId; + const newCurrentScopeItraceId = getCurrentScope().getPropagationContext().traceId; + + expect(newIsolationScopeItraceId).toMatch(/^[a-f0-9]{32}$/); + expect(newCurrentScopeItraceId).toMatch(/^[a-f0-9]{32}$/); + expect(newIsolationScopeItraceId).not.toBe(oldIsolationScopeItraceId); + expect(newCurrentScopeItraceId).not.toBe(oldCurrentScopeItraceId); + }); +}); diff --git a/packages/deno/src/index.ts b/packages/deno/src/index.ts index 1857de352798..aa30c762d624 100644 --- a/packages/deno/src/index.ts +++ b/packages/deno/src/index.ts @@ -58,6 +58,7 @@ export { startSpan, startInactiveSpan, startSpanManual, + startNewTrace, metricsDefault as metrics, inboundFiltersIntegration, linkedErrorsIntegration, diff --git a/packages/google-cloud-serverless/src/index.ts b/packages/google-cloud-serverless/src/index.ts index 067c27818a10..6affee429e1f 100644 --- a/packages/google-cloud-serverless/src/index.ts +++ b/packages/google-cloud-serverless/src/index.ts @@ -62,6 +62,7 @@ export { startSpan, startInactiveSpan, startSpanManual, + startNewTrace, withActiveSpan, getRootSpan, getSpanDescendants, diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts index 5cc16772189b..47d3d5d7735f 100644 --- a/packages/node/src/index.ts +++ b/packages/node/src/index.ts @@ -111,6 +111,7 @@ export { startSpan, startSpanManual, startInactiveSpan, + startNewTrace, getActiveSpan, withActiveSpan, getRootSpan, diff --git a/packages/remix/src/index.server.ts b/packages/remix/src/index.server.ts index ab35b4bf4847..a6476b692fbf 100644 --- a/packages/remix/src/index.server.ts +++ b/packages/remix/src/index.server.ts @@ -67,6 +67,7 @@ export { startSpan, startSpanManual, startInactiveSpan, + startNewTrace, withActiveSpan, getSpanDescendants, continueTrace, diff --git a/packages/sveltekit/src/server/index.ts b/packages/sveltekit/src/server/index.ts index d7d50f64481e..c8b97029e456 100644 --- a/packages/sveltekit/src/server/index.ts +++ b/packages/sveltekit/src/server/index.ts @@ -60,6 +60,7 @@ export { startSpan, startInactiveSpan, startSpanManual, + startNewTrace, withActiveSpan, continueTrace, cron, diff --git a/packages/vercel-edge/src/index.ts b/packages/vercel-edge/src/index.ts index ce4ef113908b..79c6d77c9d21 100644 --- a/packages/vercel-edge/src/index.ts +++ b/packages/vercel-edge/src/index.ts @@ -58,6 +58,7 @@ export { startSpan, startInactiveSpan, startSpanManual, + startNewTrace, withActiveSpan, getSpanDescendants, continueTrace, From 6fef293743f25c02eb43ffb6a37ebedf5f6925cd Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 21 May 2024 13:27:56 +0200 Subject: [PATCH 2/9] add integration test --- packages/core/src/tracing/trace.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/core/src/tracing/trace.ts b/packages/core/src/tracing/trace.ts index ff6d4c26242c..3205e3016187 100644 --- a/packages/core/src/tracing/trace.ts +++ b/packages/core/src/tracing/trace.ts @@ -1,11 +1,12 @@ import type { ClientOptions, Scope, SentrySpanArguments, Span, SpanTimeInput, StartSpanOptions } from '@sentry/types'; -import { propagationContextFromHeaders, uuid4 } from '@sentry/utils'; +import { logger, propagationContextFromHeaders, uuid4 } from '@sentry/utils'; import type { AsyncContextStrategy } from '../asyncContext/types'; import { getMainCarrier } from '../carrier'; import { getClient, getCurrentScope, getIsolationScope, withScope } from '../currentScopes'; import { getAsyncContextStrategy } from '../asyncContext'; +import { DEBUG_BUILD } from '../debug-build'; import { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '../semanticAttributes'; import { handleCallbackErrors } from '../utils/handleCallbackErrors'; import { hasTracingEnabled } from '../utils/hasTracingEnabled'; @@ -226,8 +227,9 @@ export function suppressTracing(callback: () => T): T { * or page will automatically create a new trace. */ export function startNewTrace(): void { - getCurrentScope().setPropagationContext(generatePropagationContext()); getIsolationScope().setPropagationContext(generatePropagationContext()); + getCurrentScope().setPropagationContext(generatePropagationContext()); + DEBUG_BUILD && logger.info(`Starting a new trace with id ${getCurrentScope().getPropagationContext().traceId}`); } function createChildOrRootSpan({ From 7c3662885457feaf42f41f3f8c32bc82a4aed886 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 21 May 2024 13:29:00 +0200 Subject: [PATCH 3/9] test for realz --- .../trace-lifetime/startNewTrace/subject.js | 7 ++ .../trace-lifetime/startNewTrace/test.ts | 80 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/subject.js create mode 100644 dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/test.ts diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/subject.js b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/subject.js new file mode 100644 index 000000000000..1f673af6f4d4 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/subject.js @@ -0,0 +1,7 @@ +const fetchBtn = document.getElementById('fetchBtn'); +fetchBtn.addEventListener('click', async () => { + Sentry.startNewTrace(); + Sentry.startSpan({ op: 'ui.interaction.click', name: 'fetch click' }, async () => { + await fetch('http://example.com'); + }); +}); diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/test.ts b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/test.ts new file mode 100644 index 000000000000..9394d48c63f7 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/test.ts @@ -0,0 +1,80 @@ +import { expect } from '@playwright/test'; +import { sentryTest } from '../../../../utils/fixtures'; +import type { EventAndTraceHeader } from '../../../../utils/helpers'; +import { + eventAndTraceHeaderRequestParser, + getFirstSentryEnvelopeRequest, + shouldSkipTracingTest, +} from '../../../../utils/helpers'; + +sentryTest('should create a new trace if `startNewTrace` is called', async ({ getLocalTestUrl, page }) => { + if (shouldSkipTracingTest()) { + sentryTest.skip(); + } + + const url = await getLocalTestUrl({ testDir: __dirname }); + + await page.route('http://example.com/**', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({}), + }); + }); + + const [pageloadEvent, pageloadTraceHeaders] = await getFirstSentryEnvelopeRequest( + page, + url, + eventAndTraceHeaderRequestParser, + ); + + const pageloadTraceContext = pageloadEvent.contexts?.trace; + + expect(pageloadEvent.type).toEqual('transaction'); + + expect(pageloadTraceContext).toMatchObject({ + op: 'pageload', + trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), + span_id: expect.stringMatching(/^[0-9a-f]{16}$/), + }); + expect(pageloadTraceContext).not.toHaveProperty('parent_span_id'); + + expect(pageloadTraceHeaders).toEqual({ + environment: 'production', + public_key: 'public', + sample_rate: '1', + sampled: 'true', + trace_id: pageloadTraceContext?.trace_id, + }); + + const customTransactionPromise = getFirstSentryEnvelopeRequest( + page, + undefined, + eventAndTraceHeaderRequestParser, + ); + + await page.locator('#fetchBtn').click(); + + const [customTransactionEvent, customTransactionTraceHeaders] = await customTransactionPromise; + + expect(customTransactionEvent.type).toEqual('transaction'); + expect(customTransactionEvent.transaction).toEqual('fetch click'); + + const customTransactionTraceContext = customTransactionEvent.contexts?.trace; + expect(customTransactionTraceContext).toMatchObject({ + op: 'ui.interaction.click', + trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), + span_id: expect.stringMatching(/^[0-9a-f]{16}$/), + }); + + expect(customTransactionTraceHeaders).toEqual({ + environment: 'production', + public_key: 'public', + sample_rate: '1', + sampled: 'true', + trace_id: customTransactionTraceContext?.trace_id, + transaction: 'fetch click', + }); + + expect(customTransactionTraceContext?.trace_id).not.toEqual(pageloadTraceContext?.trace_id); +}); From 611e7666ca01e5c7f1d1e09f8a48588c5f97c1c8 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 21 May 2024 13:37:52 +0200 Subject: [PATCH 4/9] small cleanup --- .../browser/src/tracing/browserTracingIntegration.ts | 11 ++--------- packages/core/src/scope.ts | 8 +------- packages/core/src/tracing/propagationContext.ts | 12 ++++++++++++ packages/core/src/tracing/trace.ts | 8 +------- .../core/test/lib/tracing/proagationContext.test.ts | 10 ++++++++++ 5 files changed, 26 insertions(+), 23 deletions(-) create mode 100644 packages/core/src/tracing/propagationContext.ts create mode 100644 packages/core/test/lib/tracing/proagationContext.test.ts diff --git a/packages/browser/src/tracing/browserTracingIntegration.ts b/packages/browser/src/tracing/browserTracingIntegration.ts index b3d530ee3653..68a574f5f4e9 100644 --- a/packages/browser/src/tracing/browserTracingIntegration.ts +++ b/packages/browser/src/tracing/browserTracingIntegration.ts @@ -22,6 +22,7 @@ import { spanIsSampled, spanToJSON, startIdleSpan, + startNewTrace, } from '@sentry/core'; import type { Client, IntegrationFn, StartSpanOptions, TransactionSource } from '@sentry/types'; import type { Span } from '@sentry/types'; @@ -412,8 +413,7 @@ export function startBrowserTracingPageLoadSpan( * This will only do something if a browser tracing integration has been setup. */ export function startBrowserTracingNavigationSpan(client: Client, spanOptions: StartSpanOptions): Span | undefined { - getCurrentScope().setPropagationContext(generatePropagationContext()); - getIsolationScope().setPropagationContext(generatePropagationContext()); + startNewTrace(); client.emit('startNavigationSpan', spanOptions); @@ -487,10 +487,3 @@ function registerInteractionListener( addEventListener('click', registerInteractionTransaction, { once: false, capture: true }); } } - -function generatePropagationContext(): { traceId: string; spanId: string } { - return { - traceId: uuid4(), - spanId: uuid4().substring(16), - }; -} diff --git a/packages/core/src/scope.ts b/packages/core/src/scope.ts index 724c9b621ce9..e8a5e9f62b3a 100644 --- a/packages/core/src/scope.ts +++ b/packages/core/src/scope.ts @@ -24,6 +24,7 @@ import type { import { dateTimestampInSeconds, isPlainObject, logger, uuid4 } from '@sentry/utils'; import { updateSession } from './session'; +import { generatePropagationContext } from './tracing/propagationContext'; import { _getSpanForScope, _setSpanForScope } from './utils/spanOnScope'; /** @@ -600,10 +601,3 @@ export const Scope = ScopeClass; * Holds additional event information. */ export type Scope = ScopeInterface; - -function generatePropagationContext(): PropagationContext { - return { - traceId: uuid4(), - spanId: uuid4().substring(16), - }; -} diff --git a/packages/core/src/tracing/propagationContext.ts b/packages/core/src/tracing/propagationContext.ts new file mode 100644 index 000000000000..99cd7dc0db83 --- /dev/null +++ b/packages/core/src/tracing/propagationContext.ts @@ -0,0 +1,12 @@ +import type { PropagationContext } from '@sentry/types'; +import { uuid4 } from '@sentry/utils'; + +/** + * Generates a new minimal propagation context + */ +export function generatePropagationContext(): PropagationContext { + return { + traceId: uuid4(), + spanId: uuid4().substring(16), + }; +} diff --git a/packages/core/src/tracing/trace.ts b/packages/core/src/tracing/trace.ts index 3205e3016187..5d6883be7d05 100644 --- a/packages/core/src/tracing/trace.ts +++ b/packages/core/src/tracing/trace.ts @@ -14,6 +14,7 @@ import { _getSpanForScope, _setSpanForScope } from '../utils/spanOnScope'; import { addChildSpanToSpan, getRootSpan, spanIsSampled, spanTimeInputToSeconds, spanToJSON } from '../utils/spanUtils'; import { freezeDscOnSpan, getDynamicSamplingContextFromSpan } from './dynamicSamplingContext'; import { logSpanStart } from './logSpans'; +import { generatePropagationContext } from './propagationContext'; import { sampleSpan } from './sampling'; import { SentryNonRecordingSpan } from './sentryNonRecordingSpan'; import { SentrySpan } from './sentrySpan'; @@ -414,10 +415,3 @@ function getParentSpan(scope: Scope): SentrySpan | undefined { return span; } - -function generatePropagationContext(): { traceId: string; spanId: string } { - return { - traceId: uuid4(), - spanId: uuid4().substring(16), - }; -} diff --git a/packages/core/test/lib/tracing/proagationContext.test.ts b/packages/core/test/lib/tracing/proagationContext.test.ts new file mode 100644 index 000000000000..4ea33c3b3439 --- /dev/null +++ b/packages/core/test/lib/tracing/proagationContext.test.ts @@ -0,0 +1,10 @@ +import { generatePropagationContext } from '../../../src/tracing/propagationContext'; + +describe('generatePropagationContext', () => { + it('generates a new minimal propagation context', () => { + expect(generatePropagationContext()).toEqual({ + traceId: expect.stringMatching(/^[0-9a-f]{32}$/), + spanId: expect.stringMatching(/^[0-9a-f]{16}$/), + }); + }); +}); From 91316eacda0350904b95eb8b24b0712f79b97c73 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 21 May 2024 14:53:19 +0200 Subject: [PATCH 5/9] make startNewTrace use a callback --- .../trace-lifetime/startNewTrace/subject.js | 16 ++++-- .../startNewTrace/template.html | 10 ++++ .../trace-lifetime/startNewTrace/test.ts | 52 +++++++++++++++---- .../src/tracing/browserTracingIntegration.ts | 4 +- packages/core/src/scope.ts | 3 +- packages/core/src/tracing/trace.ts | 26 ++++++---- packages/utils/src/index.ts | 1 + .../src}/propagationContext.ts | 4 +- .../test}/proagationContext.test.ts | 2 +- 9 files changed, 86 insertions(+), 32 deletions(-) create mode 100644 dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/template.html rename packages/{core/src/tracing => utils/src}/propagationContext.ts (70%) rename packages/{core/test/lib/tracing => utils/test}/proagationContext.test.ts (77%) diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/subject.js b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/subject.js index 1f673af6f4d4..5b28df9da5e8 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/subject.js +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/subject.js @@ -1,7 +1,15 @@ -const fetchBtn = document.getElementById('fetchBtn'); -fetchBtn.addEventListener('click', async () => { - Sentry.startNewTrace(); - Sentry.startSpan({ op: 'ui.interaction.click', name: 'fetch click' }, async () => { +const newTraceBtn = document.getElementById('newTrace'); +newTraceBtn.addEventListener('click', async () => { + Sentry.startNewTrace(() => { + Sentry.startSpan({ op: 'ui.interaction.click', name: 'new-trace' }, async () => { + await fetch('http://example.com'); + }); + }); +}); + +const oldTraceBtn = document.getElementById('oldTrace'); +oldTraceBtn.addEventListener('click', async () => { + Sentry.startSpan({ op: 'ui.interaction.click', name: 'old-trace' }, async () => { await fetch('http://example.com'); }); }); diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/template.html b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/template.html new file mode 100644 index 000000000000..7d3c25bf7b84 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/template.html @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/test.ts b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/test.ts index 9394d48c63f7..d8e73d523903 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/test.ts @@ -47,34 +47,64 @@ sentryTest('should create a new trace if `startNewTrace` is called', async ({ ge trace_id: pageloadTraceContext?.trace_id, }); - const customTransactionPromise = getFirstSentryEnvelopeRequest( + const newTraceTransactionPromise = getFirstSentryEnvelopeRequest( page, undefined, eventAndTraceHeaderRequestParser, ); - await page.locator('#fetchBtn').click(); + await page.locator('#newTrace').click(); - const [customTransactionEvent, customTransactionTraceHeaders] = await customTransactionPromise; + const [newTraceTransactionEvent, newTraceTransactionTraceHeaders] = await newTraceTransactionPromise; - expect(customTransactionEvent.type).toEqual('transaction'); - expect(customTransactionEvent.transaction).toEqual('fetch click'); + expect(newTraceTransactionEvent.type).toEqual('transaction'); + expect(newTraceTransactionEvent.transaction).toEqual('new-trace'); - const customTransactionTraceContext = customTransactionEvent.contexts?.trace; - expect(customTransactionTraceContext).toMatchObject({ + const newTraceTransactionTraceContext = newTraceTransactionEvent.contexts?.trace; + expect(newTraceTransactionTraceContext).toMatchObject({ op: 'ui.interaction.click', trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), span_id: expect.stringMatching(/^[0-9a-f]{16}$/), }); - expect(customTransactionTraceHeaders).toEqual({ + expect(newTraceTransactionTraceHeaders).toEqual({ environment: 'production', public_key: 'public', sample_rate: '1', sampled: 'true', - trace_id: customTransactionTraceContext?.trace_id, - transaction: 'fetch click', + trace_id: newTraceTransactionTraceContext?.trace_id, + transaction: 'new-trace', }); - expect(customTransactionTraceContext?.trace_id).not.toEqual(pageloadTraceContext?.trace_id); + const oldTraceTransactionPromise = getFirstSentryEnvelopeRequest( + page, + undefined, + eventAndTraceHeaderRequestParser, + ); + await page.locator('#oldTrace').click(); + + const [oldTraceTransactionEvent, oldTraceTransactionTraceHeaders] = await oldTraceTransactionPromise; + + expect(oldTraceTransactionEvent.type).toEqual('transaction'); + expect(oldTraceTransactionEvent.transaction).toEqual('old-trace'); + + const oldTraceTransactionEventTraceContext = oldTraceTransactionEvent.contexts?.trace; + expect(oldTraceTransactionEventTraceContext).toMatchObject({ + op: 'ui.interaction.click', + trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), + span_id: expect.stringMatching(/^[0-9a-f]{16}$/), + }); + + expect(oldTraceTransactionTraceHeaders).toEqual({ + environment: 'production', + public_key: 'public', + sample_rate: '1', + sampled: 'true', + trace_id: oldTraceTransactionTraceHeaders?.trace_id, + // transaction: 'old-trace', <-- this is not in the DSC because the DSC is continued from the pageload transaction + // which does not have a `transaction` field because its source is URL. + }); + + expect(oldTraceTransactionEventTraceContext?.trace_id).toEqual(pageloadTraceContext?.trace_id); + expect(newTraceTransactionTraceContext?.trace_id).not.toEqual(pageloadTraceContext?.trace_id); }); diff --git a/packages/browser/src/tracing/browserTracingIntegration.ts b/packages/browser/src/tracing/browserTracingIntegration.ts index 68a574f5f4e9..28a46dfa091d 100644 --- a/packages/browser/src/tracing/browserTracingIntegration.ts +++ b/packages/browser/src/tracing/browserTracingIntegration.ts @@ -28,6 +28,7 @@ import type { Client, IntegrationFn, StartSpanOptions, TransactionSource } from import type { Span } from '@sentry/types'; import { browserPerformanceTimeOrigin, + generatePropagationContext, getDomElement, logger, propagationContextFromHeaders, @@ -413,7 +414,8 @@ export function startBrowserTracingPageLoadSpan( * This will only do something if a browser tracing integration has been setup. */ export function startBrowserTracingNavigationSpan(client: Client, spanOptions: StartSpanOptions): Span | undefined { - startNewTrace(); + getIsolationScope().setPropagationContext(generatePropagationContext()); + getCurrentScope().setPropagationContext(generatePropagationContext()); client.emit('startNavigationSpan', spanOptions); diff --git a/packages/core/src/scope.ts b/packages/core/src/scope.ts index e8a5e9f62b3a..ff89c0d593a9 100644 --- a/packages/core/src/scope.ts +++ b/packages/core/src/scope.ts @@ -21,10 +21,9 @@ import type { SeverityLevel, User, } from '@sentry/types'; -import { dateTimestampInSeconds, isPlainObject, logger, uuid4 } from '@sentry/utils'; +import { dateTimestampInSeconds, generatePropagationContext, isPlainObject, logger, uuid4 } from '@sentry/utils'; import { updateSession } from './session'; -import { generatePropagationContext } from './tracing/propagationContext'; import { _getSpanForScope, _setSpanForScope } from './utils/spanOnScope'; /** diff --git a/packages/core/src/tracing/trace.ts b/packages/core/src/tracing/trace.ts index 5d6883be7d05..e34c2c1a62d3 100644 --- a/packages/core/src/tracing/trace.ts +++ b/packages/core/src/tracing/trace.ts @@ -1,5 +1,5 @@ import type { ClientOptions, Scope, SentrySpanArguments, Span, SpanTimeInput, StartSpanOptions } from '@sentry/types'; -import { logger, propagationContextFromHeaders, uuid4 } from '@sentry/utils'; +import { generatePropagationContext, logger, propagationContextFromHeaders } from '@sentry/utils'; import type { AsyncContextStrategy } from '../asyncContext/types'; import { getMainCarrier } from '../carrier'; @@ -14,7 +14,6 @@ import { _getSpanForScope, _setSpanForScope } from '../utils/spanOnScope'; import { addChildSpanToSpan, getRootSpan, spanIsSampled, spanTimeInputToSeconds, spanToJSON } from '../utils/spanUtils'; import { freezeDscOnSpan, getDynamicSamplingContextFromSpan } from './dynamicSamplingContext'; import { logSpanStart } from './logSpans'; -import { generatePropagationContext } from './propagationContext'; import { sampleSpan } from './sampling'; import { SentryNonRecordingSpan } from './sentryNonRecordingSpan'; import { SentrySpan } from './sentrySpan'; @@ -215,22 +214,27 @@ export function suppressTracing(callback: () => T): T { } /** - * Starts a new trace by creating a new trace id. Spans started after this function is called - * will be part of the new trace instead of a potentially previous existing trace. + * Starts a new trace for the duration of the provided callback. Spans started within the + * callback will be part of the new trace instead of a potentially previously started trace. * - * Important: Only use this function if you want to override the default trace lifetime SDK. - * Please also note that as soon as you call this function, a previously distributed can no longer be - * continued. Instead, the newly created trace will also be the root of a new distributed trace. + * Important: Only use this function if you want to override the default trace lifetime and + * propagation mechanism of the SDK for the duration and scope of the provided callback. + * The newly created trace will also be the root of a new distributed trace, for example if + * you make http requests within the callback. + * This function might be useful if the operation you want to instrument should not be part + * of a potentially ongoing trace. * * Default behavior: * - Server-side: A new trace is started for each incoming request. * - Browser: A new trace is started for each page our route. Navigating to a new route * or page will automatically create a new trace. */ -export function startNewTrace(): void { - getIsolationScope().setPropagationContext(generatePropagationContext()); - getCurrentScope().setPropagationContext(generatePropagationContext()); - DEBUG_BUILD && logger.info(`Starting a new trace with id ${getCurrentScope().getPropagationContext().traceId}`); +export function startNewTrace(callback: () => T): T { + return withScope(scope => { + scope.setPropagationContext(generatePropagationContext()); + DEBUG_BUILD && logger.info(`Starting a new trace with id ${scope.getPropagationContext().traceId}`); + return withActiveSpan(null, callback); + }); } function createChildOrRootSpan({ diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index a0649cef48ad..2fb6f420ab58 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -35,3 +35,4 @@ export * from './eventbuilder'; export * from './anr'; export * from './lru'; export * from './buildPolyfills'; +export * from './propagationContext'; diff --git a/packages/core/src/tracing/propagationContext.ts b/packages/utils/src/propagationContext.ts similarity index 70% rename from packages/core/src/tracing/propagationContext.ts rename to packages/utils/src/propagationContext.ts index 99cd7dc0db83..745531c8aa98 100644 --- a/packages/core/src/tracing/propagationContext.ts +++ b/packages/utils/src/propagationContext.ts @@ -1,8 +1,8 @@ import type { PropagationContext } from '@sentry/types'; -import { uuid4 } from '@sentry/utils'; +import { uuid4 } from './misc'; /** - * Generates a new minimal propagation context + * Returns a new minimal propagation context */ export function generatePropagationContext(): PropagationContext { return { diff --git a/packages/core/test/lib/tracing/proagationContext.test.ts b/packages/utils/test/proagationContext.test.ts similarity index 77% rename from packages/core/test/lib/tracing/proagationContext.test.ts rename to packages/utils/test/proagationContext.test.ts index 4ea33c3b3439..01c8569bde9b 100644 --- a/packages/core/test/lib/tracing/proagationContext.test.ts +++ b/packages/utils/test/proagationContext.test.ts @@ -1,4 +1,4 @@ -import { generatePropagationContext } from '../../../src/tracing/propagationContext'; +import { generatePropagationContext } from '../src/propagationContext'; describe('generatePropagationContext', () => { it('generates a new minimal propagation context', () => { From 0fc87b378e4dbd1d6d9b9c231d465bc9501bc7dd Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 21 May 2024 14:57:53 +0200 Subject: [PATCH 6/9] adjust test --- .../trace-lifetime/startNewTrace/test.ts | 203 +++++++++--------- 1 file changed, 103 insertions(+), 100 deletions(-) diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/test.ts b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/test.ts index d8e73d523903..84d8f8b3858a 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/test.ts @@ -7,104 +7,107 @@ import { shouldSkipTracingTest, } from '../../../../utils/helpers'; -sentryTest('should create a new trace if `startNewTrace` is called', async ({ getLocalTestUrl, page }) => { - if (shouldSkipTracingTest()) { - sentryTest.skip(); - } - - const url = await getLocalTestUrl({ testDir: __dirname }); - - await page.route('http://example.com/**', route => { - return route.fulfill({ - status: 200, - contentType: 'application/json', - body: JSON.stringify({}), +sentryTest( + 'creates a new trace if `startNewTrace` is called and leaves old trace valid outside the callback', + async ({ getLocalTestUrl, page }) => { + if (shouldSkipTracingTest()) { + sentryTest.skip(); + } + + const url = await getLocalTestUrl({ testDir: __dirname }); + + await page.route('http://example.com/**', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({}), + }); }); - }); - - const [pageloadEvent, pageloadTraceHeaders] = await getFirstSentryEnvelopeRequest( - page, - url, - eventAndTraceHeaderRequestParser, - ); - - const pageloadTraceContext = pageloadEvent.contexts?.trace; - - expect(pageloadEvent.type).toEqual('transaction'); - - expect(pageloadTraceContext).toMatchObject({ - op: 'pageload', - trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), - span_id: expect.stringMatching(/^[0-9a-f]{16}$/), - }); - expect(pageloadTraceContext).not.toHaveProperty('parent_span_id'); - - expect(pageloadTraceHeaders).toEqual({ - environment: 'production', - public_key: 'public', - sample_rate: '1', - sampled: 'true', - trace_id: pageloadTraceContext?.trace_id, - }); - - const newTraceTransactionPromise = getFirstSentryEnvelopeRequest( - page, - undefined, - eventAndTraceHeaderRequestParser, - ); - - await page.locator('#newTrace').click(); - - const [newTraceTransactionEvent, newTraceTransactionTraceHeaders] = await newTraceTransactionPromise; - - expect(newTraceTransactionEvent.type).toEqual('transaction'); - expect(newTraceTransactionEvent.transaction).toEqual('new-trace'); - - const newTraceTransactionTraceContext = newTraceTransactionEvent.contexts?.trace; - expect(newTraceTransactionTraceContext).toMatchObject({ - op: 'ui.interaction.click', - trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), - span_id: expect.stringMatching(/^[0-9a-f]{16}$/), - }); - - expect(newTraceTransactionTraceHeaders).toEqual({ - environment: 'production', - public_key: 'public', - sample_rate: '1', - sampled: 'true', - trace_id: newTraceTransactionTraceContext?.trace_id, - transaction: 'new-trace', - }); - - const oldTraceTransactionPromise = getFirstSentryEnvelopeRequest( - page, - undefined, - eventAndTraceHeaderRequestParser, - ); - await page.locator('#oldTrace').click(); - - const [oldTraceTransactionEvent, oldTraceTransactionTraceHeaders] = await oldTraceTransactionPromise; - - expect(oldTraceTransactionEvent.type).toEqual('transaction'); - expect(oldTraceTransactionEvent.transaction).toEqual('old-trace'); - - const oldTraceTransactionEventTraceContext = oldTraceTransactionEvent.contexts?.trace; - expect(oldTraceTransactionEventTraceContext).toMatchObject({ - op: 'ui.interaction.click', - trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), - span_id: expect.stringMatching(/^[0-9a-f]{16}$/), - }); - - expect(oldTraceTransactionTraceHeaders).toEqual({ - environment: 'production', - public_key: 'public', - sample_rate: '1', - sampled: 'true', - trace_id: oldTraceTransactionTraceHeaders?.trace_id, - // transaction: 'old-trace', <-- this is not in the DSC because the DSC is continued from the pageload transaction - // which does not have a `transaction` field because its source is URL. - }); - - expect(oldTraceTransactionEventTraceContext?.trace_id).toEqual(pageloadTraceContext?.trace_id); - expect(newTraceTransactionTraceContext?.trace_id).not.toEqual(pageloadTraceContext?.trace_id); -}); + + const [pageloadEvent, pageloadTraceHeaders] = await getFirstSentryEnvelopeRequest( + page, + url, + eventAndTraceHeaderRequestParser, + ); + + const pageloadTraceContext = pageloadEvent.contexts?.trace; + + expect(pageloadEvent.type).toEqual('transaction'); + + expect(pageloadTraceContext).toMatchObject({ + op: 'pageload', + trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), + span_id: expect.stringMatching(/^[0-9a-f]{16}$/), + }); + expect(pageloadTraceContext).not.toHaveProperty('parent_span_id'); + + expect(pageloadTraceHeaders).toEqual({ + environment: 'production', + public_key: 'public', + sample_rate: '1', + sampled: 'true', + trace_id: pageloadTraceContext?.trace_id, + }); + + const newTraceTransactionPromise = getFirstSentryEnvelopeRequest( + page, + undefined, + eventAndTraceHeaderRequestParser, + ); + + await page.locator('#newTrace').click(); + + const [newTraceTransactionEvent, newTraceTransactionTraceHeaders] = await newTraceTransactionPromise; + + expect(newTraceTransactionEvent.type).toEqual('transaction'); + expect(newTraceTransactionEvent.transaction).toEqual('new-trace'); + + const newTraceTransactionTraceContext = newTraceTransactionEvent.contexts?.trace; + expect(newTraceTransactionTraceContext).toMatchObject({ + op: 'ui.interaction.click', + trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), + span_id: expect.stringMatching(/^[0-9a-f]{16}$/), + }); + + expect(newTraceTransactionTraceHeaders).toEqual({ + environment: 'production', + public_key: 'public', + sample_rate: '1', + sampled: 'true', + trace_id: newTraceTransactionTraceContext?.trace_id, + transaction: 'new-trace', + }); + + const oldTraceTransactionPromise = getFirstSentryEnvelopeRequest( + page, + undefined, + eventAndTraceHeaderRequestParser, + ); + await page.locator('#oldTrace').click(); + + const [oldTraceTransactionEvent, oldTraceTransactionTraceHeaders] = await oldTraceTransactionPromise; + + expect(oldTraceTransactionEvent.type).toEqual('transaction'); + expect(oldTraceTransactionEvent.transaction).toEqual('old-trace'); + + const oldTraceTransactionEventTraceContext = oldTraceTransactionEvent.contexts?.trace; + expect(oldTraceTransactionEventTraceContext).toMatchObject({ + op: 'ui.interaction.click', + trace_id: expect.stringMatching(/^[0-9a-f]{32}$/), + span_id: expect.stringMatching(/^[0-9a-f]{16}$/), + }); + + expect(oldTraceTransactionTraceHeaders).toEqual({ + environment: 'production', + public_key: 'public', + sample_rate: '1', + sampled: 'true', + trace_id: oldTraceTransactionTraceHeaders?.trace_id, + // transaction: 'old-trace', <-- this is not in the DSC because the DSC is continued from the pageload transaction + // which does not have a `transaction` field because its source is URL. + }); + + expect(oldTraceTransactionEventTraceContext?.trace_id).toEqual(pageloadTraceContext?.trace_id); + expect(newTraceTransactionTraceContext?.trace_id).not.toEqual(pageloadTraceContext?.trace_id); + }, +); From e9c23626ef6728b122ebdb83dc8b131bd30a66f2 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 21 May 2024 17:32:11 +0200 Subject: [PATCH 7/9] fix tests --- packages/core/test/lib/tracing/trace.test.ts | 25 +++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/packages/core/test/lib/tracing/trace.test.ts b/packages/core/test/lib/tracing/trace.test.ts index 39451e5c0f99..9399aa6b5a57 100644 --- a/packages/core/test/lib/tracing/trace.test.ts +++ b/packages/core/test/lib/tracing/trace.test.ts @@ -1598,18 +1598,25 @@ describe('startNewTrace', () => { getIsolationScope().clear(); }); - it('resets the propagation context on current scope and isolation scope', () => { - const oldIsolationScopeItraceId = getIsolationScope().getPropagationContext().traceId; + it('creates a new propagation context on the current scope', () => { const oldCurrentScopeItraceId = getCurrentScope().getPropagationContext().traceId; - startNewTrace(); + startNewTrace(() => { + const newCurrentScopeItraceId = getCurrentScope().getPropagationContext().traceId; - const newIsolationScopeItraceId = getIsolationScope().getPropagationContext().traceId; - const newCurrentScopeItraceId = getCurrentScope().getPropagationContext().traceId; + expect(newCurrentScopeItraceId).toMatch(/^[a-f0-9]{32}$/); + expect(newCurrentScopeItraceId).not.toEqual(oldCurrentScopeItraceId); + }); + }); + + it('keeps the propagation context on the isolation scope as-is', () => { + const oldIsolationScopeTraceId = getIsolationScope().getPropagationContext().traceId; - expect(newIsolationScopeItraceId).toMatch(/^[a-f0-9]{32}$/); - expect(newCurrentScopeItraceId).toMatch(/^[a-f0-9]{32}$/); - expect(newIsolationScopeItraceId).not.toBe(oldIsolationScopeItraceId); - expect(newCurrentScopeItraceId).not.toBe(oldCurrentScopeItraceId); + startNewTrace(() => { + const newIsolationScopeTraceId = getIsolationScope().getPropagationContext().traceId; + + expect(newIsolationScopeTraceId).toMatch(/^[a-f0-9]{32}$/); + expect(newIsolationScopeTraceId).toEqual(oldIsolationScopeTraceId); + }); }); }); From 7411e69c247f3567355e1bddfc4694995803cba6 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 24 May 2024 16:42:51 +0200 Subject: [PATCH 8/9] fix flaky integration test --- .../trace-lifetime/startNewTrace/test.ts | 27 +++++++------------ 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/test.ts b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/test.ts index 84d8f8b3858a..3ddca4787aee 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/startNewTrace/test.ts @@ -4,6 +4,7 @@ import type { EventAndTraceHeader } from '../../../../utils/helpers'; import { eventAndTraceHeaderRequestParser, getFirstSentryEnvelopeRequest, + getMultipleSentryEnvelopeRequests, shouldSkipTracingTest, } from '../../../../utils/helpers'; @@ -49,18 +50,22 @@ sentryTest( trace_id: pageloadTraceContext?.trace_id, }); - const newTraceTransactionPromise = getFirstSentryEnvelopeRequest( + const transactionPromises = getMultipleSentryEnvelopeRequests( page, - undefined, + 2, + { envelopeType: 'transaction' }, eventAndTraceHeaderRequestParser, ); await page.locator('#newTrace').click(); + await page.locator('#oldTrace').click(); - const [newTraceTransactionEvent, newTraceTransactionTraceHeaders] = await newTraceTransactionPromise; + const [txnEvent1, txnEvent2] = await transactionPromises; - expect(newTraceTransactionEvent.type).toEqual('transaction'); - expect(newTraceTransactionEvent.transaction).toEqual('new-trace'); + const [newTraceTransactionEvent, newTraceTransactionTraceHeaders] = + txnEvent1[0].transaction === 'new-trace' ? txnEvent1 : txnEvent2; + const [oldTraceTransactionEvent, oldTraceTransactionTraceHeaders] = + txnEvent1[0].transaction === 'old-trace' ? txnEvent1 : txnEvent2; const newTraceTransactionTraceContext = newTraceTransactionEvent.contexts?.trace; expect(newTraceTransactionTraceContext).toMatchObject({ @@ -78,18 +83,6 @@ sentryTest( transaction: 'new-trace', }); - const oldTraceTransactionPromise = getFirstSentryEnvelopeRequest( - page, - undefined, - eventAndTraceHeaderRequestParser, - ); - await page.locator('#oldTrace').click(); - - const [oldTraceTransactionEvent, oldTraceTransactionTraceHeaders] = await oldTraceTransactionPromise; - - expect(oldTraceTransactionEvent.type).toEqual('transaction'); - expect(oldTraceTransactionEvent.transaction).toEqual('old-trace'); - const oldTraceTransactionEventTraceContext = oldTraceTransactionEvent.contexts?.trace; expect(oldTraceTransactionEventTraceContext).toMatchObject({ op: 'ui.interaction.click', From 820d38b129a663f0f527ff28f4bf0dc6ab454480 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 24 May 2024 17:37:54 +0200 Subject: [PATCH 9/9] cdn tracing bundle export --- packages/browser/src/index.bundle.tracing.replay.feedback.ts | 1 + packages/browser/src/index.bundle.tracing.replay.ts | 1 + packages/browser/src/index.bundle.tracing.ts | 1 + packages/browser/src/tracing/browserTracingIntegration.ts | 2 -- 4 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/browser/src/index.bundle.tracing.replay.feedback.ts b/packages/browser/src/index.bundle.tracing.replay.feedback.ts index de8453db8784..b9dc457640be 100644 --- a/packages/browser/src/index.bundle.tracing.replay.feedback.ts +++ b/packages/browser/src/index.bundle.tracing.replay.feedback.ts @@ -10,6 +10,7 @@ export { startSpan, startInactiveSpan, startSpanManual, + startNewTrace, withActiveSpan, getSpanDescendants, setMeasurement, diff --git a/packages/browser/src/index.bundle.tracing.replay.ts b/packages/browser/src/index.bundle.tracing.replay.ts index 3b8a51e661dc..a0e4d4736384 100644 --- a/packages/browser/src/index.bundle.tracing.replay.ts +++ b/packages/browser/src/index.bundle.tracing.replay.ts @@ -10,6 +10,7 @@ export { startSpan, startInactiveSpan, startSpanManual, + startNewTrace, withActiveSpan, getSpanDescendants, setMeasurement, diff --git a/packages/browser/src/index.bundle.tracing.ts b/packages/browser/src/index.bundle.tracing.ts index e93bf68994e3..d540ff0bd6f9 100644 --- a/packages/browser/src/index.bundle.tracing.ts +++ b/packages/browser/src/index.bundle.tracing.ts @@ -11,6 +11,7 @@ export { startSpan, startInactiveSpan, startSpanManual, + startNewTrace, withActiveSpan, getSpanDescendants, setMeasurement, diff --git a/packages/browser/src/tracing/browserTracingIntegration.ts b/packages/browser/src/tracing/browserTracingIntegration.ts index 28a46dfa091d..f6528e4d155d 100644 --- a/packages/browser/src/tracing/browserTracingIntegration.ts +++ b/packages/browser/src/tracing/browserTracingIntegration.ts @@ -22,7 +22,6 @@ import { spanIsSampled, spanToJSON, startIdleSpan, - startNewTrace, } from '@sentry/core'; import type { Client, IntegrationFn, StartSpanOptions, TransactionSource } from '@sentry/types'; import type { Span } from '@sentry/types'; @@ -32,7 +31,6 @@ import { getDomElement, logger, propagationContextFromHeaders, - uuid4, } from '@sentry/utils'; import { DEBUG_BUILD } from '../debug-build';