diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/basic/subject.js b/dev-packages/browser-integration-tests/suites/public-api/startSpan/basic/subject.js index aaf2de868f6f..35d41b55e69d 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/basic/subject.js +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/basic/subject.js @@ -3,6 +3,9 @@ async function run() { Sentry.startSpan({ name: 'child_span' }, () => { // whatever a user would do here }); + + // unfinished spans are filtered out + Sentry.startInactiveSpan({ name: 'span_4' }); }); } diff --git a/dev-packages/browser-integration-tests/suites/public-api/startTransaction/circular_data/subject.js b/dev-packages/browser-integration-tests/suites/public-api/startSpan/circular_data/subject.js similarity index 100% rename from dev-packages/browser-integration-tests/suites/public-api/startTransaction/circular_data/subject.js rename to dev-packages/browser-integration-tests/suites/public-api/startSpan/circular_data/subject.js diff --git a/dev-packages/browser-integration-tests/suites/public-api/startTransaction/circular_data/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/circular_data/test.ts similarity index 100% rename from dev-packages/browser-integration-tests/suites/public-api/startTransaction/circular_data/test.ts rename to dev-packages/browser-integration-tests/suites/public-api/startSpan/circular_data/test.ts diff --git a/dev-packages/browser-integration-tests/suites/public-api/startTransaction/setMeasurement/subject.js b/dev-packages/browser-integration-tests/suites/public-api/startSpan/setMeasurement/subject.js similarity index 68% rename from dev-packages/browser-integration-tests/suites/public-api/startTransaction/setMeasurement/subject.js rename to dev-packages/browser-integration-tests/suites/public-api/startSpan/setMeasurement/subject.js index 5b14dd7b680b..9316ed946b2d 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startTransaction/setMeasurement/subject.js +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/setMeasurement/subject.js @@ -1,4 +1,7 @@ -const transaction = Sentry.startTransaction({ name: 'some_transaction' }); +const transaction = Sentry.startInactiveSpan({ + name: 'some_transaction', + forceTransaction: true, +}); transaction.setMeasurement('metric.foo', 42, 'ms'); transaction.setMeasurement('metric.bar', 1337, 'nanoseconds'); diff --git a/dev-packages/browser-integration-tests/suites/public-api/startTransaction/setMeasurement/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/setMeasurement/test.ts similarity index 100% rename from dev-packages/browser-integration-tests/suites/public-api/startTransaction/setMeasurement/test.ts rename to dev-packages/browser-integration-tests/suites/public-api/startSpan/setMeasurement/test.ts diff --git a/dev-packages/browser-integration-tests/suites/public-api/startTransaction/basic_usage/subject.js b/dev-packages/browser-integration-tests/suites/public-api/startTransaction/basic_usage/subject.js deleted file mode 100644 index 5942deca663b..000000000000 --- a/dev-packages/browser-integration-tests/suites/public-api/startTransaction/basic_usage/subject.js +++ /dev/null @@ -1,23 +0,0 @@ -Sentry.startSpan({ name: 'root_span' }, () => { - Sentry.startSpan( - { - name: 'span_1', - data: { - foo: 'bar', - baz: [1, 2, 3], - }, - }, - () => undefined, - ); - - // span_2 doesn't finish - Sentry.startInactiveSpan({ name: 'span_2' }); - - Sentry.startSpan({ name: 'span_3' }, () => { - // span_4 is the child of span_3 but doesn't finish. - Sentry.startInactiveSpan({ name: 'span_4', data: { qux: 'quux' } }); - - // span_5 is another child of span_3 but finishes. - Sentry.startInactiveSpan({ name: 'span_5' }).end(); - }); -}); diff --git a/dev-packages/browser-integration-tests/suites/public-api/startTransaction/basic_usage/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startTransaction/basic_usage/test.ts deleted file mode 100644 index 0624ff3f7dad..000000000000 --- a/dev-packages/browser-integration-tests/suites/public-api/startTransaction/basic_usage/test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; - -import { sentryTest } from '../../../../utils/fixtures'; -import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; - -sentryTest('should report a transaction in an envelope', async ({ getLocalTestPath, page }) => { - if (shouldSkipTracingTest()) { - sentryTest.skip(); - } - - const url = await getLocalTestPath({ testDir: __dirname }); - const transaction = await getFirstSentryEnvelopeRequest(page, url); - - expect(transaction.transaction).toBe('root_span'); - expect(transaction.spans).toBeDefined(); -}); - -sentryTest('should report finished spans as children of the root span', async ({ getLocalTestPath, page }) => { - if (shouldSkipTracingTest()) { - sentryTest.skip(); - } - - const url = await getLocalTestPath({ testDir: __dirname }); - const transaction = await getFirstSentryEnvelopeRequest(page, url); - - const rootSpanId = transaction?.contexts?.trace?.span_id; - - expect(transaction.spans).toHaveLength(3); - - const span_1 = transaction.spans?.[0]; - - expect(span_1).toBeDefined(); - expect(span_1!.description).toBe('span_1'); - expect(span_1!.parent_span_id).toEqual(rootSpanId); - expect(span_1!.data).toMatchObject({ foo: 'bar', baz: [1, 2, 3] }); - - const span_3 = transaction.spans?.[1]; - expect(span_3).toBeDefined(); - expect(span_3!.description).toBe('span_3'); - expect(span_3!.parent_span_id).toEqual(rootSpanId); - - const span_5 = transaction.spans?.[2]; - expect(span_5).toBeDefined(); - expect(span_5!.description).toBe('span_5'); - expect(span_5!.parent_span_id).toEqual(span_3!.span_id); -}); diff --git a/dev-packages/browser-integration-tests/suites/public-api/startTransaction/init.js b/dev-packages/browser-integration-tests/suites/public-api/startTransaction/init.js deleted file mode 100644 index 3fb0df7a75d4..000000000000 --- a/dev-packages/browser-integration-tests/suites/public-api/startTransaction/init.js +++ /dev/null @@ -1,11 +0,0 @@ -import * as Sentry from '@sentry/browser'; - -window.Sentry = Sentry; - -Sentry.addTracingExtensions(); - -Sentry.init({ - dsn: 'https://public@dsn.ingest.sentry.io/1337', - tracesSampleRate: 1.0, - normalizeDepth: 10, -}); diff --git a/packages/browser/src/exports.ts b/packages/browser/src/exports.ts index 643235a2ec36..a1599f4d7f77 100644 --- a/packages/browser/src/exports.ts +++ b/packages/browser/src/exports.ts @@ -43,8 +43,6 @@ export { makeMain, setCurrentClient, Scope, - // eslint-disable-next-line deprecation/deprecation - startTransaction, continueTrace, SDK_VERSION, setContext, diff --git a/packages/core/src/exports.ts b/packages/core/src/exports.ts index 54e158d4654a..2ccb6ef530e8 100644 --- a/packages/core/src/exports.ts +++ b/packages/core/src/exports.ts @@ -1,7 +1,6 @@ import type { CaptureContext, CheckIn, - CustomSamplingContext, Event, EventHint, EventProcessor, @@ -13,7 +12,6 @@ import type { Session, SessionContext, SeverityLevel, - TransactionContext, User, } from '@sentry/types'; import { GLOBAL_OBJ, isThenable, logger, timestampInSeconds, uuid4 } from '@sentry/utils'; @@ -22,7 +20,6 @@ import { DEFAULT_ENVIRONMENT } from './constants'; import { getClient, getCurrentScope, getIsolationScope } from './currentScopes'; import { DEBUG_BUILD } from './debug-build'; import type { Hub } from './hub'; -import { getCurrentHub } from './hub'; import { closeSession, makeSession, updateSession } from './session'; import type { ExclusiveEventHintOrCaptureContext } from './utils/prepareEvent'; import { parseEventHintOrCaptureContext } from './utils/prepareEvent'; @@ -124,36 +121,6 @@ export function setUser(user: User | null): ReturnType { getIsolationScope().setUser(user); } -/** - * Starts a new `Transaction` and returns it. This is the entry point to manual tracing instrumentation. - * - * A tree structure can be built by adding child spans to the transaction, and child spans to other spans. To start a - * new child span within the transaction or any span, call the respective `.startChild()` method. - * - * Every child span must be finished before the transaction is finished, otherwise the unfinished spans are discarded. - * - * The transaction must be finished with a call to its `.end()` method, at which point the transaction with all its - * finished child spans will be sent to Sentry. - * - * NOTE: This function should only be used for *manual* instrumentation. Auto-instrumentation should call - * `startTransaction` directly on the hub. - * - * @param context Properties of the new `Transaction`. - * @param customSamplingContext Information given to the transaction sampling function (along with context-dependent - * default values). See {@link Options.tracesSampler}. - * - * @returns The transaction which was just started - * - * @deprecated Use `startSpan()`, `startSpanManual()` or `startInactiveSpan()` instead. - */ -export function startTransaction( - context: TransactionContext, - customSamplingContext?: CustomSamplingContext, -): ReturnType { - // eslint-disable-next-line deprecation/deprecation - return getCurrentHub().startTransaction({ ...context }, customSamplingContext); -} - /** * Create a cron monitor check in and send it to Sentry. * diff --git a/packages/core/src/hub.ts b/packages/core/src/hub.ts index abfb22b612b3..6320849ce248 100644 --- a/packages/core/src/hub.ts +++ b/packages/core/src/hub.ts @@ -3,7 +3,6 @@ import type { Breadcrumb, BreadcrumbHint, Client, - CustomSamplingContext, Event, EventHint, Extra, @@ -16,8 +15,6 @@ import type { Session, SessionContext, SeverityLevel, - Transaction, - TransactionContext, User, } from '@sentry/types'; import { GLOBAL_OBJ, consoleSandbox, dateTimestampInSeconds, isThenable, logger, uuid4 } from '@sentry/utils'; @@ -438,46 +435,6 @@ export class Hub implements HubInterface { } } - /** - * Starts a new `Transaction` and returns it. This is the entry point to manual tracing instrumentation. - * - * A tree structure can be built by adding child spans to the transaction, and child spans to other spans. To start a - * new child span within the transaction or any span, call the respective `.startChild()` method. - * - * Every child span must be finished before the transaction is finished, otherwise the unfinished spans are discarded. - * - * The transaction must be finished with a call to its `.end()` method, at which point the transaction with all its - * finished child spans will be sent to Sentry. - * - * @param context Properties of the new `Transaction`. - * @param customSamplingContext Information given to the transaction sampling function (along with context-dependent - * default values). See {@link Options.tracesSampler}. - * - * @returns The transaction which was just started - * - * @deprecated Use `startSpan()`, `startSpanManual()` or `startInactiveSpan()` instead. - */ - public startTransaction(context: TransactionContext, customSamplingContext?: CustomSamplingContext): Transaction { - const result = this._callExtensionMethod('startTransaction', context, customSamplingContext); - - if (DEBUG_BUILD && !result) { - // eslint-disable-next-line deprecation/deprecation - const client = this.getClient(); - if (!client) { - logger.warn( - "Tracing extension 'startTransaction' is missing. You should 'init' the SDK before calling 'startTransaction'", - ); - } else { - logger.warn(`Tracing extension 'startTransaction' has not been added. Call 'addTracingExtensions' before calling 'init': -Sentry.addTracingExtensions(); -Sentry.init({...}); -`); - } - } - - return result; - } - /** * @inheritDoc * diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 6b4c6a13021f..52841ee68a6d 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -17,8 +17,6 @@ export { captureMessage, close, flush, - // eslint-disable-next-line deprecation/deprecation - startTransaction, setContext, setExtra, setExtras, diff --git a/packages/core/src/tracing/hubextensions.ts b/packages/core/src/tracing/hubextensions.ts index 6702a213549a..394a2be026fe 100644 --- a/packages/core/src/tracing/hubextensions.ts +++ b/packages/core/src/tracing/hubextensions.ts @@ -1,66 +1,9 @@ -import type { ClientOptions, CustomSamplingContext, Hub, TransactionContext } from '@sentry/types'; -import { getMainCarrier } from '../asyncContext'; - import { registerErrorInstrumentation } from './errors'; -import { sampleTransaction } from './sampling'; -import { Transaction } from './transaction'; /** - * Creates a new transaction and adds a sampling decision if it doesn't yet have one. - * - * The Hub.startTransaction method delegates to this method to do its work, passing the Hub instance in as `this`, as if - * it had been called on the hub directly. Exists as a separate function so that it can be injected into the class as an - * "extension method." - * - * @param this: The Hub starting the transaction - * @param transactionContext: Data used to configure the transaction - * @param CustomSamplingContext: Optional data to be provided to the `tracesSampler` function (if any) - * - * @returns The new transaction - * - * @see {@link Hub.startTransaction} - */ -function _startTransaction( - this: Hub, - transactionContext: TransactionContext, - customSamplingContext?: CustomSamplingContext, -): Transaction { - // eslint-disable-next-line deprecation/deprecation - const client = this.getClient(); - const options: Partial = (client && client.getOptions()) || {}; - - // eslint-disable-next-line deprecation/deprecation - let transaction = new Transaction(transactionContext, this); - transaction = sampleTransaction(transaction, options, { - name: transactionContext.name, - parentSampled: transactionContext.parentSampled, - transactionContext, - attributes: { - // eslint-disable-next-line deprecation/deprecation - ...transactionContext.data, - ...transactionContext.attributes, - }, - ...customSamplingContext, - }); - if (client) { - client.emit('startTransaction', transaction); - client.emit('spanStart', transaction); - } - return transaction; -} - -/** - * Adds tracing extensions to the global hub. + * Adds tracing extensions. + * TODO (v8): Do we still need this?? Can we solve this differently? */ export function addTracingExtensions(): void { - const carrier = getMainCarrier(); - if (!carrier.__SENTRY__) { - return; - } - carrier.__SENTRY__.extensions = carrier.__SENTRY__.extensions || {}; - if (!carrier.__SENTRY__.extensions.startTransaction) { - carrier.__SENTRY__.extensions.startTransaction = _startTransaction; - } - registerErrorInstrumentation(); } diff --git a/packages/core/src/tracing/sentrySpan.ts b/packages/core/src/tracing/sentrySpan.ts index 7bb13b37c18f..1df09d305cbb 100644 --- a/packages/core/src/tracing/sentrySpan.ts +++ b/packages/core/src/tracing/sentrySpan.ts @@ -60,8 +60,8 @@ export class SentrySpan implements Span { private _logMessage?: string; /** - * You should never call the constructor manually, always use `Sentry.startTransaction()` - * or call `startChild()` on an existing span. + * You should never call the constructor manually, always use `Sentry.startSpan()` + * or other span methods. * @internal * @hideconstructor * @hidden diff --git a/packages/core/src/tracing/trace.ts b/packages/core/src/tracing/trace.ts index e095b0df94a4..6faa9b4f9505 100644 --- a/packages/core/src/tracing/trace.ts +++ b/packages/core/src/tracing/trace.ts @@ -1,9 +1,17 @@ -import type { Hub, Scope, Span, SpanTimeInput, StartSpanOptions, TransactionContext } from '@sentry/types'; +import type { + ClientOptions, + Hub, + Scope, + Span, + SpanTimeInput, + StartSpanOptions, + TransactionContext, +} from '@sentry/types'; import { dropUndefinedKeys, logger, tracingContextFromHeaders } from '@sentry/utils'; import type { AsyncContextStrategy } from '../asyncContext'; import { getMainCarrier } from '../asyncContext'; -import { getCurrentScope, getIsolationScope, withScope } from '../currentScopes'; +import { getClient, getCurrentScope, getIsolationScope, withScope } from '../currentScopes'; import { DEBUG_BUILD } from '../debug-build'; import { getAsyncContextStrategy, getCurrentHub } from '../hub'; @@ -17,9 +25,11 @@ import { spanToJSON, } from '../utils/spanUtils'; import { getDynamicSamplingContextFromSpan } from './dynamicSamplingContext'; +import { sampleTransaction } from './sampling'; import { SentryNonRecordingSpan } from './sentryNonRecordingSpan'; import type { SentrySpan } from './sentrySpan'; import { SPAN_STATUS_ERROR } from './spanstatus'; +import { Transaction } from './transaction'; import { setCapturedScopesOnSpan } from './utils'; /** @@ -324,8 +334,7 @@ function createChildSpanOrTransaction( const { traceId, spanId: parentSpanId } = parentSpan.spanContext(); const sampled = spanIsSampled(parentSpan); - // eslint-disable-next-line deprecation/deprecation - span = hub.startTransaction({ + span = _startTransaction({ traceId, parentSpanId, parentSampled: sampled, @@ -342,8 +351,7 @@ function createChildSpanOrTransaction( ...scope.getPropagationContext(), }; - // eslint-disable-next-line deprecation/deprecation - span = hub.startTransaction({ + span = _startTransaction({ traceId, parentSpanId, parentSampled: sampled, @@ -390,3 +398,26 @@ function getAcs(): AsyncContextStrategy { const carrier = getMainCarrier(); return getAsyncContextStrategy(carrier); } + +function _startTransaction(transactionContext: TransactionContext): Transaction { + const client = getClient(); + const options: Partial = (client && client.getOptions()) || {}; + + // eslint-disable-next-line deprecation/deprecation + let transaction = new Transaction(transactionContext, getCurrentHub()); + transaction = sampleTransaction(transaction, options, { + name: transactionContext.name, + parentSampled: transactionContext.parentSampled, + transactionContext, + attributes: { + // eslint-disable-next-line deprecation/deprecation + ...transactionContext.data, + ...transactionContext.attributes, + }, + }); + if (client) { + client.emit('startTransaction', transaction); + client.emit('spanStart', transaction); + } + return transaction; +} diff --git a/packages/core/src/tracing/transaction.ts b/packages/core/src/tracing/transaction.ts index 847cffeaa37d..42a442d7ec0d 100644 --- a/packages/core/src/tracing/transaction.ts +++ b/packages/core/src/tracing/transaction.ts @@ -45,8 +45,7 @@ export class Transaction extends SentrySpan implements TransactionInterface { private _metadata: Partial; /** - * This constructor should never be called manually. Those instrumenting tracing should use - * `Sentry.startTransaction()`, and internal methods should use `hub.startTransaction()`. + * This constructor should never be called manually. * @internal * @hideconstructor * @hidden diff --git a/packages/core/test/lib/tracing/trace.test.ts b/packages/core/test/lib/tracing/trace.test.ts index 3395d9ee4133..5d57f770719b 100644 --- a/packages/core/test/lib/tracing/trace.test.ts +++ b/packages/core/test/lib/tracing/trace.test.ts @@ -3,7 +3,6 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_OP, Scope, addTracingExtensions, - getCurrentHub, getCurrentScope, getGlobalScope, getIsolationScope, @@ -83,23 +82,6 @@ describe('startSpan', () => { } }); - it('should return the same value as the callback if transactions are undefined', async () => { - // @ts-expect-error we are force overriding the transaction return to be undefined - // The `startTransaction` types are actually wrong - it can return undefined - // if tracingExtensions are not enabled - // eslint-disable-next-line deprecation/deprecation - jest.spyOn(getCurrentHub(), 'startTransaction').mockImplementationOnce(() => undefined); - - try { - const result = await startSpan({ name: 'GET users/[id]' }, () => { - return callback(); - }); - expect(result).toEqual(expected); - } catch (e) { - expect(e).toEqual(expected); - } - }); - it('creates a transaction', async () => { let _span: Span | undefined = undefined; client.on('finishTransaction', transaction => { diff --git a/packages/node-experimental/src/sdk/hub.ts b/packages/node-experimental/src/sdk/hub.ts index c6db8788280e..0ab3e0cd320c 100644 --- a/packages/node-experimental/src/sdk/hub.ts +++ b/packages/node-experimental/src/sdk/hub.ts @@ -1,14 +1,4 @@ -import type { - Client, - CustomSamplingContext, - EventHint, - Hub, - Integration, - IntegrationClass, - Scope, - SeverityLevel, - TransactionContext, -} from '@sentry/types'; +import type { Client, EventHint, Hub, Integration, IntegrationClass, Scope, SeverityLevel } from '@sentry/types'; import { addBreadcrumb, @@ -76,18 +66,6 @@ export function getCurrentHub(): Hub { return getClient().getIntegration(integration); }, - startTransaction( - _context: TransactionContext, - _customSamplingContext?: CustomSamplingContext, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ): any { - // eslint-disable-next-line no-console - console.warn('startTransaction is a noop in @sentry/node. Use `startSpan` instead.'); - // We return an object here as hub.ts checks for the result of this - // and renders a different warning if this is empty - return {}; - }, - startSession, endSession, diff --git a/packages/node/src/handlers.ts b/packages/node/src/handlers.ts index 826758befc75..306accbfb42f 100644 --- a/packages/node/src/handlers.ts +++ b/packages/node/src/handlers.ts @@ -1,5 +1,6 @@ import type * as http from 'http'; /* eslint-disable @typescript-eslint/no-explicit-any */ +import type { Transaction } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, @@ -12,7 +13,7 @@ import { getIsolationScope, hasTracingEnabled, setHttpStatus, - startTransaction, + startInactiveSpan, withIsolationScope, withScope, } from '@sentry/core'; @@ -21,7 +22,6 @@ import type { AddRequestDataToEventOptions } from '@sentry/utils'; import { addRequestDataToTransaction, extractPathForTransaction, - extractRequestData, isString, isThenable, logger, @@ -59,14 +59,14 @@ export function tracingHandler(): ( } const [name, source] = extractPathForTransaction(req, { path: true, method: true }); - const transaction = continueTrace({ sentryTrace, baggage }, ctx => - // TODO: Refactor this to use `startSpan()` - // eslint-disable-next-line deprecation/deprecation - startTransaction( - { + const transaction = continueTrace( + { sentryTrace, baggage }, + ctx => + startInactiveSpan({ name, op: 'http.server', origin: 'auto.http.node.tracingHandler', + forceTransaction: true, ...ctx, attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source, @@ -80,10 +80,7 @@ export function tracingHandler(): ( // be sure request: req, }, - }, - // extra context passed to the tracesSampler - { request: extractRequestData(req) }, - ), + }) as Transaction, ); // We put the transaction on the scope so users can attach children to it diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts index 9e43b7ba6696..73cd82c93b32 100644 --- a/packages/node/src/index.ts +++ b/packages/node/src/index.ts @@ -46,8 +46,6 @@ export { makeMain, setCurrentClient, Scope, - // eslint-disable-next-line deprecation/deprecation - startTransaction, SDK_VERSION, setContext, setExtra, diff --git a/packages/node/src/integrations/hapi/index.ts b/packages/node/src/integrations/hapi/index.ts index 88ebfbeb0512..da01232867f5 100644 --- a/packages/node/src/integrations/hapi/index.ts +++ b/packages/node/src/integrations/hapi/index.ts @@ -11,7 +11,7 @@ import { getRootSpan, setHttpStatus, spanToTraceHeader, - startTransaction, + startInactiveSpan, } from '@sentry/core'; import type { IntegrationFn } from '@sentry/types'; @@ -82,11 +82,11 @@ export const hapiTracingPlugin = { baggage: request.headers['baggage'] || undefined, }, transactionContext => { - // eslint-disable-next-line deprecation/deprecation - return startTransaction({ + return startInactiveSpan({ ...transactionContext, op: 'hapi.request', name: `${request.route.method} ${request.path}`, + forceTransaction: true, }); }, ); diff --git a/packages/node/test/handlers.test.ts b/packages/node/test/handlers.test.ts index fc27409eaca8..d8f483cb771a 100644 --- a/packages/node/test/handlers.test.ts +++ b/packages/node/test/handlers.test.ts @@ -251,38 +251,38 @@ describe('tracingHandler', () => { } it('creates a transaction when handling a request', () => { - const startTransaction = jest.spyOn(sentryCore, 'startTransaction'); + const startInactiveSpan = jest.spyOn(sentryCore, 'startInactiveSpan'); sentryTracingMiddleware(req, res, next); - expect(startTransaction).toHaveBeenCalled(); + expect(startInactiveSpan).toHaveBeenCalled(); }); it("doesn't create a transaction when handling a `HEAD` request", () => { - const startTransaction = jest.spyOn(sentryCore, 'startTransaction'); + const startInactiveSpan = jest.spyOn(sentryCore, 'startInactiveSpan'); req.method = 'HEAD'; sentryTracingMiddleware(req, res, next); - expect(startTransaction).not.toHaveBeenCalled(); + expect(startInactiveSpan).not.toHaveBeenCalled(); }); it("doesn't create a transaction when handling an `OPTIONS` request", () => { - const startTransaction = jest.spyOn(sentryCore, 'startTransaction'); + const startInactiveSpan = jest.spyOn(sentryCore, 'startInactiveSpan'); req.method = 'OPTIONS'; sentryTracingMiddleware(req, res, next); - expect(startTransaction).not.toHaveBeenCalled(); + expect(startInactiveSpan).not.toHaveBeenCalled(); }); it("doesn't create a transaction if tracing is disabled", () => { delete getClient()?.getOptions().tracesSampleRate; - const startTransaction = jest.spyOn(sentryCore, 'startTransaction'); + const startInactiveSpan = jest.spyOn(sentryCore, 'startInactiveSpan'); sentryTracingMiddleware(req, res, next); - expect(startTransaction).not.toHaveBeenCalled(); + expect(startInactiveSpan).not.toHaveBeenCalled(); }); it("pulls parent's data from tracing header on the request", () => { @@ -346,29 +346,6 @@ describe('tracingHandler', () => { expect(transaction.metadata?.dynamicSamplingContext).toStrictEqual({ version: '1.0', environment: 'production' }); }); - it('extracts request data for sampling context', () => { - const tracesSampler = jest.fn(); - const options = getDefaultNodeClientOptions({ tracesSampler }); - const client = new NodeClient(options); - setCurrentClient(client); - - withScope(() => { - sentryTracingMiddleware(req, res, next); - - expect(tracesSampler).toHaveBeenCalledWith( - expect.objectContaining({ - request: { - headers, - method, - url: `http://${hostname}${path}?${queryString}`, - cookies: { favorite: 'zukes' }, - query_string: queryString, - }, - }), - ); - }); - }); - it('puts its transaction on the scope', () => { const options = getDefaultNodeClientOptions({ tracesSampleRate: 1.0 }); const client = new NodeClient(options); @@ -400,7 +377,7 @@ describe('tracingHandler', () => { it('pulls status code from the response', done => { // eslint-disable-next-line deprecation/deprecation const transaction = new Transaction({ name: 'mockTransaction' }); - jest.spyOn(sentryCore, 'startTransaction').mockReturnValue(transaction as Transaction); + jest.spyOn(sentryCore, 'startInactiveSpan').mockReturnValue(transaction as Transaction); const finishTransaction = jest.spyOn(transaction, 'end'); sentryTracingMiddleware(req, res, next); @@ -448,7 +425,7 @@ describe('tracingHandler', () => { it('closes the transaction when request processing is done', done => { // eslint-disable-next-line deprecation/deprecation const transaction = new Transaction({ name: 'mockTransaction' }); - jest.spyOn(sentryCore, 'startTransaction').mockReturnValue(transaction as Transaction); + jest.spyOn(sentryCore, 'startInactiveSpan').mockReturnValue(transaction as Transaction); const finishTransaction = jest.spyOn(transaction, 'end'); sentryTracingMiddleware(req, res, next); @@ -468,7 +445,7 @@ describe('tracingHandler', () => { name: 'reallyCoolHandler', op: 'middleware', }); - jest.spyOn(sentryCore, 'startTransaction').mockReturnValue(transaction as Transaction); + jest.spyOn(sentryCore, 'startInactiveSpan').mockReturnValue(transaction as Transaction); const finishSpan = jest.spyOn(span, 'end'); const finishTransaction = jest.spyOn(transaction, 'end'); diff --git a/packages/opentelemetry/src/custom/getCurrentHub.ts b/packages/opentelemetry/src/custom/getCurrentHub.ts index 36699561aa99..4c257e037e38 100644 --- a/packages/opentelemetry/src/custom/getCurrentHub.ts +++ b/packages/opentelemetry/src/custom/getCurrentHub.ts @@ -1,14 +1,4 @@ -import type { - Client, - CustomSamplingContext, - EventHint, - Hub, - Integration, - IntegrationClass, - Scope, - SeverityLevel, - TransactionContext, -} from '@sentry/types'; +import type { Client, EventHint, Hub, Integration, IntegrationClass, Scope, SeverityLevel } from '@sentry/types'; import { addBreadcrumb, @@ -76,18 +66,6 @@ export function getCurrentHub(): Hub { return getClient()?.getIntegration(integration) || null; }, - startTransaction( - _context: TransactionContext, - _customSamplingContext?: CustomSamplingContext, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ): any { - // eslint-disable-next-line no-console - console.warn('startTransaction is a noop in @sentry/opentelemetry. Use `startSpan` instead.'); - // We return an object here as hub.ts checks for the result of this - // and renders a different warning if this is empty - return {}; - }, - startSession, endSession, diff --git a/packages/profiling-node/README.md b/packages/profiling-node/README.md index e496ba5f96a0..f2c9920f0ff1 100644 --- a/packages/profiling-node/README.md +++ b/packages/profiling-node/README.md @@ -38,15 +38,13 @@ Sentry.init({ }); ``` -Sentry SDK will now automatically profile all transactions, even the ones which may be started as a result of using an +Sentry SDK will now automatically profile all root spans, even the ones which may be started as a result of using an automatic instrumentation integration. ```javascript -const transaction = Sentry.startTransaction({ name: 'some workflow' }); - -// The code between startTransaction and transaction.finish will be profiled - -transaction.end(); +Sentry.startSpan({ name: 'some workflow' }, () => { + // The code in here will be profiled +}); ``` ### Building the package from source diff --git a/packages/profiling-node/test/spanProfileUtils.test.ts b/packages/profiling-node/test/spanProfileUtils.test.ts index a6a493fc7bbc..9083576a775c 100644 --- a/packages/profiling-node/test/spanProfileUtils.test.ts +++ b/packages/profiling-node/test/spanProfileUtils.test.ts @@ -50,8 +50,7 @@ describe('spanProfileUtils', () => { const transportSpy = jest.spyOn(transport, 'send').mockReturnValue(Promise.resolve({})); - // eslint-disable-next-line deprecation/deprecation - const transaction = Sentry.getCurrentHub().startTransaction({ name: 'profile_hub' }); + const transaction = Sentry.startInactiveSpan({ forceTransaction: true, name: 'profile_hub' }); await wait(500); transaction.end(); @@ -85,8 +84,7 @@ describe('spanProfileUtils', () => { jest.spyOn(transport, 'send').mockReturnValue(Promise.resolve({})); - // eslint-disable-next-line deprecation/deprecation - const transaction = Sentry.getCurrentHub().startTransaction({ name: 'profile_hub' }); + const transaction = Sentry.startInactiveSpan({ forceTransaction: true, name: 'profile_hub' }); transaction.end(); await Sentry.flush(1000); @@ -129,8 +127,7 @@ describe('spanProfileUtils', () => { jest.spyOn(transport, 'send').mockReturnValue(Promise.resolve({})); - // eslint-disable-next-line deprecation/deprecation - const transaction = Sentry.getCurrentHub().startTransaction({ name: 'profile_hub', traceId: 'boop' }); + const transaction = Sentry.startInactiveSpan({ forceTransaction: true, name: 'profile_hub', traceId: 'boop' }); await wait(500); transaction.end(); @@ -150,8 +147,7 @@ describe('spanProfileUtils', () => { jest.spyOn(transport, 'send').mockReturnValue(Promise.resolve({})); - // eslint-disable-next-line deprecation/deprecation - const transaction = Sentry.getCurrentHub().startTransaction({ name: 'profile_hub' }); + const transaction = Sentry.startInactiveSpan({ forceTransaction: true, name: 'profile_hub' }); await wait(500); transaction.end(); @@ -168,8 +164,7 @@ describe('spanProfileUtils', () => { const transportSpy = jest.spyOn(transport, 'send').mockReturnValue(Promise.resolve({})); - // eslint-disable-next-line deprecation/deprecation - const transaction = Sentry.getCurrentHub().startTransaction({ name: 'profile_hub' }); + const transaction = Sentry.startInactiveSpan({ forceTransaction: true, name: 'profile_hub' }); await wait(500); transaction.end(); @@ -216,8 +211,7 @@ describe('spanProfileUtils', () => { return Promise.resolve({}); }); - // eslint-disable-next-line deprecation/deprecation - const transaction = Sentry.getCurrentHub().startTransaction({ name: 'profile_hub' }); + const transaction = Sentry.startInactiveSpan({ forceTransaction: true, name: 'profile_hub' }); await wait(500); transaction.end(); @@ -237,8 +231,7 @@ describe('spanProfileUtils', () => { client.on('preprocessEvent', onPreprocessEvent); - // eslint-disable-next-line deprecation/deprecation - const transaction = Sentry.getCurrentHub().startTransaction({ name: 'profile_hub' }); + const transaction = Sentry.startInactiveSpan({ forceTransaction: true, name: 'profile_hub' }); await wait(500); transaction.end(); @@ -260,8 +253,7 @@ describe('spanProfileUtils', () => { Sentry.setCurrentClient(client); client.init(); - // eslint-disable-next-line deprecation/deprecation - const transaction = Sentry.getCurrentHub().startTransaction({ name: 'txn' }); + const transaction = Sentry.startInactiveSpan({ forceTransaction: true, name: 'txn' }); transaction.end(); transaction.end(); expect(stopProfilingSpy).toHaveBeenCalledTimes(1); @@ -302,8 +294,7 @@ describe('spanProfileUtils', () => { const transportSpy = jest.spyOn(transport, 'send').mockReturnValue(Promise.resolve({})); - // eslint-disable-next-line deprecation/deprecation - const transaction = Sentry.getCurrentHub().startTransaction({ name: 'profile_hub' }); + const transaction = Sentry.startInactiveSpan({ forceTransaction: true, name: 'profile_hub' }); await wait(500); transaction.end(); diff --git a/packages/remix/src/index.server.ts b/packages/remix/src/index.server.ts index 9c46fe804ca6..3ed510a5bb7b 100644 --- a/packages/remix/src/index.server.ts +++ b/packages/remix/src/index.server.ts @@ -35,8 +35,6 @@ export { setCurrentClient, NodeClient, Scope, - // eslint-disable-next-line deprecation/deprecation - startTransaction, SDK_VERSION, setContext, setExtra, diff --git a/packages/serverless/src/index.ts b/packages/serverless/src/index.ts index 8a04daea61f7..d160c6fed54b 100644 --- a/packages/serverless/src/index.ts +++ b/packages/serverless/src/index.ts @@ -46,8 +46,6 @@ export { setTag, setTags, setUser, - // eslint-disable-next-line deprecation/deprecation - startTransaction, withScope, withIsolationScope, NodeClient, diff --git a/packages/sveltekit/src/server/index.ts b/packages/sveltekit/src/server/index.ts index 36b5b5dd4e72..d843ab8499c7 100644 --- a/packages/sveltekit/src/server/index.ts +++ b/packages/sveltekit/src/server/index.ts @@ -30,8 +30,6 @@ export { makeMain, setCurrentClient, Scope, - // eslint-disable-next-line deprecation/deprecation - startTransaction, SDK_VERSION, setContext, setExtra, diff --git a/packages/types/src/hub.ts b/packages/types/src/hub.ts index e0864d461c72..77fec1dc9a69 100644 --- a/packages/types/src/hub.ts +++ b/packages/types/src/hub.ts @@ -7,7 +7,6 @@ import type { Primitive } from './misc'; import type { Scope } from './scope'; import type { Session } from './session'; import type { SeverityLevel } from './severity'; -import type { CustomSamplingContext, Transaction, TransactionContext } from './transaction'; import type { User } from './user'; /** @@ -204,27 +203,6 @@ export interface Hub { */ getIntegration(integration: IntegrationClass): T | null; - /** - * Starts a new `Transaction` and returns it. This is the entry point to manual tracing instrumentation. - * - * A tree structure can be built by adding child spans to the transaction, and child spans to other spans. To start a - * new child span within the transaction or any span, call the respective `.startChild()` method. - * - * Every child span must be finished before the transaction is finished, otherwise the unfinished spans are discarded. - * - * The transaction must be finished with a call to its `.end()` method, at which point the transaction with all its - * finished child spans will be sent to Sentry. - * - * @param context Properties of the new `Transaction`. - * @param customSamplingContext Information given to the transaction sampling function (along with context-dependent - * default values). See {@link Options.tracesSampler}. - * - * @returns The transaction which was just started - * - * @deprecated Use `startSpan()`, `startSpanManual()` or `startInactiveSpan()` instead. - */ - startTransaction(context: TransactionContext, customSamplingContext?: CustomSamplingContext): Transaction; - /** * Starts a new `Session`, sets on the current scope and returns it. *