diff --git a/packages/browser/src/tracing/request.ts b/packages/browser/src/tracing/request.ts index 368ea450b0d0..749ee6fde0dc 100644 --- a/packages/browser/src/tracing/request.ts +++ b/packages/browser/src/tracing/request.ts @@ -15,7 +15,7 @@ import { getActiveSpan, getLocationHref, getTraceData, - hasTracingEnabled, + hasSpansEnabled, instrumentFetchRequest, parseUrl, setHttpStatus, @@ -322,7 +322,7 @@ export function xhrCallback( return undefined; } - const shouldCreateSpanResult = hasTracingEnabled() && shouldCreateSpan(sentryXhrData.url); + const shouldCreateSpanResult = hasSpansEnabled() && shouldCreateSpan(sentryXhrData.url); // check first if the request has finished and is tracked by an existing span which should now end if (handlerData.endTimestamp && shouldCreateSpanResult) { @@ -370,7 +370,7 @@ export function xhrCallback( // If performance is disabled (TWP) or there's no active root span (pageload/navigation/interaction), // we do not want to use the span as base for the trace headers, // which means that the headers will be generated from the scope and the sampling decision is deferred - hasTracingEnabled() && hasParent ? span : undefined, + hasSpansEnabled() && hasParent ? span : undefined, ); } diff --git a/packages/core/src/fetch.ts b/packages/core/src/fetch.ts index 8998eb45fce0..54bd4c672dfc 100644 --- a/packages/core/src/fetch.ts +++ b/packages/core/src/fetch.ts @@ -5,7 +5,7 @@ import type { HandlerDataFetch, Span, SpanOrigin } from './types-hoist'; import { SENTRY_BAGGAGE_KEY_PREFIX } from './utils-hoist/baggage'; import { isInstanceOf } from './utils-hoist/is'; import { parseUrl } from './utils-hoist/url'; -import { hasTracingEnabled } from './utils/hasTracingEnabled'; +import { hasSpansEnabled } from './utils/hasSpansEnabled'; import { getActiveSpan } from './utils/spanUtils'; import { getTraceData } from './utils/traceData'; @@ -34,7 +34,7 @@ export function instrumentFetchRequest( return undefined; } - const shouldCreateSpanResult = hasTracingEnabled() && shouldCreateSpan(handlerData.fetchData.url); + const shouldCreateSpanResult = hasSpansEnabled() && shouldCreateSpan(handlerData.fetchData.url); if (handlerData.endTimestamp && shouldCreateSpanResult) { const spanId = handlerData.fetchData.__span; @@ -87,7 +87,7 @@ export function instrumentFetchRequest( // If performance is disabled (TWP) or there's no active root span (pageload/navigation/interaction), // we do not want to use the span as base for the trace headers, // which means that the headers will be generated from the scope and the sampling decision is deferred - hasTracingEnabled() && hasParent ? span : undefined, + hasSpansEnabled() && hasParent ? span : undefined, ); if (headers) { // Ensure this is actually set, if no options have been passed previously diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index fcc1d55128cf..f03f6b9779e9 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -68,7 +68,9 @@ export { export { applyScopeDataToEvent, mergeScopeData } from './utils/applyScopeDataToEvent'; export { prepareEvent } from './utils/prepareEvent'; export { createCheckInEnvelope } from './checkin'; -export { hasTracingEnabled } from './utils/hasTracingEnabled'; +// eslint-disable-next-line deprecation/deprecation +export { hasTracingEnabled } from './utils/hasSpansEnabled'; +export { hasSpansEnabled } from './utils/hasSpansEnabled'; export { isSentryRequestUrl } from './utils/isSentryRequestUrl'; export { handleCallbackErrors } from './utils/handleCallbackErrors'; export { parameterize } from './utils/parameterize'; diff --git a/packages/core/src/tracing/dynamicSamplingContext.ts b/packages/core/src/tracing/dynamicSamplingContext.ts index e6f3ceae79f8..f58f373447bb 100644 --- a/packages/core/src/tracing/dynamicSamplingContext.ts +++ b/packages/core/src/tracing/dynamicSamplingContext.ts @@ -9,7 +9,7 @@ import { dynamicSamplingContextToSentryBaggageHeader, } from '../utils-hoist/baggage'; import { addNonEnumerableProperty, dropUndefinedKeys } from '../utils-hoist/object'; -import { hasTracingEnabled } from '../utils/hasTracingEnabled'; +import { hasSpansEnabled } from '../utils/hasSpansEnabled'; import { getRootSpan, spanIsSampled, spanToJSON } from '../utils/spanUtils'; import { getCapturedScopesOnSpan } from './utils'; @@ -118,10 +118,10 @@ export function getDynamicSamplingContextFromSpan(span: Span): Readonly | undefined, +): boolean { + if (typeof __SENTRY_TRACING__ === 'boolean' && !__SENTRY_TRACING__) { + return false; + } + + const options = maybeOptions || getClient()?.getOptions(); + return ( + !!options && + // Note: This check is `!= null`, meaning "nullish". `0` is not "nullish", `undefined` and `null` are. (This comment was brought to you by 15 minutes of questioning life) + (options.tracesSampleRate != null || !!options.tracesSampler) + ); +} + +/** + * @see JSDoc of `hasSpansEnabled` + * @deprecated Use `hasSpansEnabled` instead, which is a more accurately named version of this function. + * This function will be removed in the next major version of the SDK. + */ +// TODO(v10): Remove this export +export const hasTracingEnabled = hasSpansEnabled; diff --git a/packages/core/src/utils/hasTracingEnabled.ts b/packages/core/src/utils/hasTracingEnabled.ts deleted file mode 100644 index a125c7a0cc9e..000000000000 --- a/packages/core/src/utils/hasTracingEnabled.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { getClient } from '../currentScopes'; -import type { Options } from '../types-hoist'; - -// Treeshakable guard to remove all code related to tracing -declare const __SENTRY_TRACING__: boolean | undefined; - -/** - * Determines if tracing is currently enabled. - * - * Tracing is enabled when at least one of `tracesSampleRate` and `tracesSampler` is defined in the SDK config. - */ -export function hasTracingEnabled( - maybeOptions?: Pick | undefined, -): boolean { - if (typeof __SENTRY_TRACING__ === 'boolean' && !__SENTRY_TRACING__) { - return false; - } - - const client = getClient(); - const options = maybeOptions || client?.getOptions(); - return ( - !!options && - // Note: This check is `!= null`, meaning "nullish". `0` is not "nullish", `undefined` and `null` are. (This comment was brought to you by 15 minutes of questioning life) - (options.tracesSampleRate != null || !!options.tracesSampler) - ); -} diff --git a/packages/core/test/lib/utils/hasTracingEnabled.test.ts b/packages/core/test/lib/utils/hasTracingEnabled.test.ts index a3191336bb1a..99062b437ec8 100644 --- a/packages/core/test/lib/utils/hasTracingEnabled.test.ts +++ b/packages/core/test/lib/utils/hasTracingEnabled.test.ts @@ -1,6 +1,7 @@ +import { hasSpansEnabled } from '../../../src'; import { hasTracingEnabled } from '../../../src'; -describe('hasTracingEnabled', () => { +describe('hasSpansEnabled', () => { const tracesSampler = () => 1; const tracesSampleRate = 1; it.each([ @@ -12,10 +13,9 @@ describe('hasTracingEnabled', () => { ['With tracesSampleRate=0', { tracesSampleRate: 0 }, true], ['With tracesSampler=undefined', { tracesSampler: undefined }, false], ['With tracesSampler and tracesSampleRate', { tracesSampler, tracesSampleRate }, true], - ])( - '%s', - (_: string, input: Parameters[0], output: ReturnType) => { - expect(hasTracingEnabled(input)).toBe(output); - }, - ); + ])('%s', (_: string, input: Parameters[0], output: ReturnType) => { + expect(hasSpansEnabled(input)).toBe(output); + // eslint-disable-next-line deprecation/deprecation + expect(hasTracingEnabled(input)).toBe(output); + }); }); diff --git a/packages/nextjs/test/config/wrappers.test.ts b/packages/nextjs/test/config/wrappers.test.ts index de9d125b7830..f18160a9fbf0 100644 --- a/packages/nextjs/test/config/wrappers.test.ts +++ b/packages/nextjs/test/config/wrappers.test.ts @@ -15,7 +15,7 @@ describe('data-fetching function wrappers should not create manual spans', () => req = { headers: {}, url: 'http://dogs.are.great/tricks/kangaroo' } as IncomingMessage; res = { end: jest.fn() } as unknown as ServerResponse; - jest.spyOn(SentryCore, 'hasTracingEnabled').mockReturnValue(true); + jest.spyOn(SentryCore, 'hasSpansEnabled').mockReturnValue(true); jest.spyOn(SentryCore, 'getClient').mockImplementation(() => { return { getOptions: () => ({}), diff --git a/packages/node/src/integrations/node-fetch.ts b/packages/node/src/integrations/node-fetch.ts index a4678be7239a..9655ea5641c5 100644 --- a/packages/node/src/integrations/node-fetch.ts +++ b/packages/node/src/integrations/node-fetch.ts @@ -11,7 +11,7 @@ import { getClient, getSanitizedUrlString, getTraceData, - hasTracingEnabled, + hasSpansEnabled, parseUrl, } from '@sentry/core'; import { shouldPropagateTraceForUrl } from '@sentry/opentelemetry'; @@ -49,9 +49,9 @@ const _nativeNodeFetchIntegration = ((options: NodeFetchOptions = {}) => { return true; } - // If tracing is disabled, we still want to propagate traces + // If span recording is disabled, we still want to propagate traces // So we do that manually here, matching what the instrumentation does otherwise - if (!hasTracingEnabled()) { + if (!hasSpansEnabled()) { const tracePropagationTargets = getClient()?.getOptions().tracePropagationTargets; const addedHeaders = shouldPropagateTraceForUrl(url, tracePropagationTargets, propagationDecisionMap) ? getTraceData() diff --git a/packages/node/src/sdk/index.ts b/packages/node/src/sdk/index.ts index 4a4900cf5b60..7b9f98ed7461 100644 --- a/packages/node/src/sdk/index.ts +++ b/packages/node/src/sdk/index.ts @@ -5,7 +5,7 @@ import { functionToStringIntegration, getCurrentScope, getIntegrationsToSetup, - hasTracingEnabled, + hasSpansEnabled, inboundFiltersIntegration, linkedErrorsIntegration, logger, @@ -80,7 +80,7 @@ export function getDefaultIntegrations(options: Options): Integration[] { // Note that this means that without tracing enabled, e.g. `expressIntegration()` will not be added // This means that generally request isolation will work (because that is done by httpIntegration) // But `transactionName` will not be set automatically - ...(hasTracingEnabled(options) ? getAutoPerformanceIntegrations() : []), + ...(hasSpansEnabled(options) ? getAutoPerformanceIntegrations() : []), ]; } @@ -175,7 +175,7 @@ export function validateOpenTelemetrySetup(): void { const required: ReturnType = ['SentryContextManager', 'SentryPropagator']; - if (hasTracingEnabled()) { + if (hasSpansEnabled()) { required.push('SentrySpanProcessor'); } diff --git a/packages/node/src/utils/ensureIsWrapped.ts b/packages/node/src/utils/ensureIsWrapped.ts index 0babb401d1f7..3a6518e7ec14 100644 --- a/packages/node/src/utils/ensureIsWrapped.ts +++ b/packages/node/src/utils/ensureIsWrapped.ts @@ -1,5 +1,5 @@ import { isWrapped } from '@opentelemetry/core'; -import { consoleSandbox, getClient, getGlobalScope, hasTracingEnabled, isEnabled } from '@sentry/core'; +import { consoleSandbox, getClient, getGlobalScope, hasSpansEnabled, isEnabled } from '@sentry/core'; import type { NodeClient } from '../sdk/client'; import { isCjs } from './commonjs'; import { createMissingInstrumentationContext } from './createMissingInstrumentationContext'; @@ -11,12 +11,12 @@ export function ensureIsWrapped( maybeWrappedFunction: unknown, name: 'express' | 'connect' | 'fastify' | 'hapi' | 'koa', ): void { - const client = getClient(); + const clientOptions = getClient()?.getOptions(); if ( - !client?.getOptions().disableInstrumentationWarnings && + !clientOptions?.disableInstrumentationWarnings && !isWrapped(maybeWrappedFunction) && isEnabled() && - hasTracingEnabled() + hasSpansEnabled(clientOptions) ) { consoleSandbox(() => { if (isCjs()) { diff --git a/packages/opentelemetry/src/sampler.ts b/packages/opentelemetry/src/sampler.ts index 9e2f00d565de..9c9889e2d2fa 100644 --- a/packages/opentelemetry/src/sampler.ts +++ b/packages/opentelemetry/src/sampler.ts @@ -13,7 +13,7 @@ import { import type { Client, SpanAttributes } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE } from '@sentry/core'; import { baggageHeaderToDynamicSamplingContext } from '@sentry/core'; -import { SEMANTIC_ATTRIBUTE_SENTRY_OP, hasTracingEnabled, logger, parseSampleRate, sampleSpan } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_OP, hasSpansEnabled, logger, parseSampleRate, sampleSpan } from '@sentry/core'; import { SENTRY_TRACE_STATE_DSC, SENTRY_TRACE_STATE_SAMPLED_NOT_RECORDING, @@ -52,7 +52,7 @@ export class SentrySampler implements Sampler { const parentSpan = getValidSpan(context); const parentContext = parentSpan?.spanContext(); - if (!hasTracingEnabled(options)) { + if (!hasSpansEnabled(options)) { return wrapSamplingDecision({ decision: undefined, context, spanAttributes }); } diff --git a/packages/opentelemetry/src/utils/enhanceDscWithOpenTelemetryRootSpanName.ts b/packages/opentelemetry/src/utils/enhanceDscWithOpenTelemetryRootSpanName.ts index 2860c93471b4..6384bd808dab 100644 --- a/packages/opentelemetry/src/utils/enhanceDscWithOpenTelemetryRootSpanName.ts +++ b/packages/opentelemetry/src/utils/enhanceDscWithOpenTelemetryRootSpanName.ts @@ -1,4 +1,4 @@ -import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, hasTracingEnabled, spanToJSON } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, hasSpansEnabled, spanToJSON } from '@sentry/core'; import type { Client } from '@sentry/core'; import { getSamplingDecision } from './getSamplingDecision'; import { parseSpanDescription } from './parseSpanDescription'; @@ -32,7 +32,7 @@ export function enhanceDscWithOpenTelemetryRootSpanName(client: Client): void { // Also ensure sampling decision is correctly inferred // In core, we use `spanIsSampled`, which just looks at the trace flags // but in OTEL, we use a slightly more complex logic to be able to differntiate between unsampled and deferred sampling - if (hasTracingEnabled()) { + if (hasSpansEnabled()) { const sampled = getSamplingDecision(rootSpan.spanContext()); dsc.sampled = sampled == undefined ? undefined : String(sampled); } diff --git a/packages/remix/src/utils/instrumentServer.ts b/packages/remix/src/utils/instrumentServer.ts index c6113ea7f0a3..25878becb82d 100644 --- a/packages/remix/src/utils/instrumentServer.ts +++ b/packages/remix/src/utils/instrumentServer.ts @@ -4,7 +4,7 @@ import { fill, getClient, getTraceData, - hasTracingEnabled, + hasSpansEnabled, isNodeEnv, loadModule, logger, @@ -197,7 +197,7 @@ function wrapRequestHandler(origRequestHandler: RequestHandler): RequestHandler isolationScope.setSDKProcessingMetadata({ normalizedRequest }); - if (!options || !hasTracingEnabled(options)) { + if (!options || !hasSpansEnabled(options)) { return origRequestHandler.call(this, request, loadContext); } diff --git a/packages/vercel-edge/src/sdk.ts b/packages/vercel-edge/src/sdk.ts index fb6c524df4b4..a816b02e27a9 100644 --- a/packages/vercel-edge/src/sdk.ts +++ b/packages/vercel-edge/src/sdk.ts @@ -15,7 +15,7 @@ import { functionToStringIntegration, getCurrentScope, getIntegrationsToSetup, - hasTracingEnabled, + hasSpansEnabled, inboundFiltersIntegration, linkedErrorsIntegration, logger, @@ -124,7 +124,7 @@ function validateOpenTelemetrySetup(): void { const required: ReturnType = ['SentryContextManager', 'SentryPropagator']; - if (hasTracingEnabled()) { + if (hasSpansEnabled()) { required.push('SentrySpanProcessor'); } diff --git a/packages/vue/src/integration.ts b/packages/vue/src/integration.ts index 167ea5c18d0c..63fc5a5786de 100644 --- a/packages/vue/src/integration.ts +++ b/packages/vue/src/integration.ts @@ -1,4 +1,4 @@ -import { GLOBAL_OBJ, consoleSandbox, defineIntegration, hasTracingEnabled } from '@sentry/core'; +import { GLOBAL_OBJ, consoleSandbox, defineIntegration, hasSpansEnabled } from '@sentry/core'; import { DEFAULT_HOOKS } from './constants'; import { DEBUG_BUILD } from './debug-build'; import { attachErrorHandler } from './errorhandler'; @@ -73,7 +73,7 @@ const vueInit = (app: Vue, options: Options): void => { attachErrorHandler(app, options); } - if (hasTracingEnabled(options)) { + if (hasSpansEnabled(options)) { app.mixin(createTracingMixins(options.tracingOptions)); } };