Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/browser/src/tracing/request.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import {
getActiveSpan,
getLocationHref,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
instrumentFetchRequest,
parseUrl,
setHttpStatus,
Expand DownExpand Up@@ -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) {
Expand DownExpand Up@@ -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,
);
}

Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';

Expand DownExpand Up@@ -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;
Expand DownExpand Up@@ -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
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/tracing/dynamicSamplingContext.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';

Expand DownExpand Up@@ -118,10 +118,10 @@ export function getDynamicSamplingContextFromSpan(span: Span): Readonly<Partial<
dsc.transaction = name;
}

// How can we even land here with hasTracingEnabled() returning false?
// How can we even land here with hasSpansEnabled() returning false?
// Otel creates a Non-recording span in Tracing Without Performance mode when handling incoming requests
// So we end up with an active span that is not sampled (neither positively nor negatively)
if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
dsc.sampled = String(spanIsSampled(rootSpan));
dsc.sample_rand =
// In OTEL we store the sample rand on the trace state because we cannot access scopes for NonRecordingSpans
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/tracing/idleSpan.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ import { DEBUG_BUILD } from '../debug-build';
import { SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON } from '../semanticAttributes';
import { logger } from '../utils-hoist/logger';
import { timestampInSeconds } from '../utils-hoist/time';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { _setSpanForScope } from '../utils/spanOnScope';
import {
getActiveSpan,
Expand DownExpand Up@@ -109,7 +109,7 @@ export function startIdleSpan(startSpanOptions: StartSpanOptions, options: Parti

const client = getClient();

if (!client || !hasTracingEnabled()) {
if (!client || !hasSpansEnabled()) {
const span = new SentryNonRecordingSpan();

const dsc = {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/tracing/sampling.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,7 @@ import type { Options, SamplingContext } from '../types-hoist';

import { DEBUG_BUILD } from '../debug-build';
import { logger } from '../utils-hoist/logger';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { parseSampleRate } from '../utils/parseSampleRate';

/**
Expand All@@ -16,8 +16,8 @@ export function sampleSpan(
samplingContext: SamplingContext,
sampleRand: number,
): [sampled: boolean, sampleRate?: number, localSampleRateWasApplied?: boolean] {
// nothing to do if tracing is not enabled
if (!hasTracingEnabled(options)) {
// nothing to do if span recording is not enabled
if (!hasSpansEnabled(options)) {
return [false];
}

Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/tracing/trace.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ import { logger } from '../utils-hoist/logger';
import { generateTraceId } from '../utils-hoist/propagationContext';
import { propagationContextFromHeaders } from '../utils-hoist/tracing';
import { handleCallbackErrors } from '../utils/handleCallbackErrors';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { parseSampleRate } from '../utils/parseSampleRate';
import { _getSpanForScope, _setSpanForScope } from '../utils/spanOnScope';
import { addChildSpanToSpan, getRootSpan, spanIsSampled, spanTimeInputToSeconds, spanToJSON } from '../utils/spanUtils';
Expand DownExpand Up@@ -302,7 +302,7 @@ function createChildOrRootSpan({
forceTransaction?: boolean;
scope: Scope;
}): Span {
if (!hasTracingEnabled()) {
if (!hasSpansEnabled()) {
const span = new SentryNonRecordingSpan();

// If this is a root span, we ensure to freeze a DSC
Expand Down
44 changes: 44 additions & 0 deletions packages/core/src/utils/hasSpansEnabled.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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 span recording is currently enabled.
*
* Spans are recorded when at least one of `tracesSampleRate` and `tracesSampler`
* is defined in the SDK config. This function does not make any assumption about
* sampling decisions, it only checks if the SDK is configured to record spans.
*
* Important: This function only determines if span recording is enabled. Trace
* continuation and propagation is separately controlled and not covered by this function.
* If this function returns `false`, traces can still be propagated (which is what
* we refer to by "Tracing without Performance")
* @see https://develop.sentry.dev/sdk/telemetry/traces/tracing-without-performance/
*
* @param maybeOptions An SDK options object to be passed to this function.
* If this option is not provided, the function will use the current client's options.
*/
export function hasSpansEnabled(
maybeOptions?: Pick<Options, 'tracesSampleRate' | 'tracesSampler'> | 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;
26 changes: 0 additions & 26 deletions packages/core/src/utils/hasTracingEnabled.ts

This file was deleted.

14 changes: 7 additions & 7 deletions packages/core/test/lib/utils/hasTracingEnabled.test.ts
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
import { hasSpansEnabled } from '../../../src';
import { hasTracingEnabled } from '../../../src';

describe('hasTracingEnabled', () => {
describe('hasSpansEnabled', () => {
const tracesSampler = () => 1;
const tracesSampleRate = 1;
it.each([
Expand All@@ -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<typeof hasTracingEnabled>[0], output: ReturnType<typeof hasTracingEnabled>) => {
expect(hasTracingEnabled(input)).toBe(output);
},
);
])('%s', (_: string, input: Parameters<typeof hasSpansEnabled>[0], output: ReturnType<typeof hasSpansEnabled>) => {
expect(hasSpansEnabled(input)).toBe(output);
// eslint-disable-next-line deprecation/deprecation
expect(hasTracingEnabled(input)).toBe(output);
});
});
2 changes: 1 addition & 1 deletion packages/nextjs/test/config/wrappers.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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: () => ({}),
Expand Down
6 changes: 3 additions & 3 deletions packages/node/src/integrations/node-fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@ import {
getClient,
getSanitizedUrlString,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
parseUrl,
} from '@sentry/core';
import { shouldPropagateTraceForUrl } from '@sentry/opentelemetry';
Expand DownExpand Up@@ -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()
Expand Down
6 changes: 3 additions & 3 deletions packages/node/src/sdk/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ import {
functionToStringIntegration,
getCurrentScope,
getIntegrationsToSetup,
hasTracingEnabled,
hasSpansEnabled,
inboundFiltersIntegration,
linkedErrorsIntegration,
logger,
Expand DownExpand Up@@ -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() : []),
];
}

Expand DownExpand Up@@ -175,7 +175,7 @@ export function validateOpenTelemetrySetup(): void {

const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];

if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
required.push('SentrySpanProcessor');
}

Expand Down
8 changes: 4 additions & 4 deletions packages/node/src/utils/ensureIsWrapped.ts
Original file line numberDiff line numberDiff line change
@@ -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';
Expand All@@ -11,12 +11,12 @@ export function ensureIsWrapped(
maybeWrappedFunction: unknown,
name: 'express' | 'connect' | 'fastify' | 'hapi' | 'koa',
): void {
const client = getClient<NodeClient>();
const clientOptions = getClient<NodeClient>()?.getOptions();
if (
!client?.getOptions().disableInstrumentationWarnings &&
!clientOptions?.disableInstrumentationWarnings &&
!isWrapped(maybeWrappedFunction) &&
isEnabled() &&
hasTracingEnabled()
hasSpansEnabled(clientOptions)
) {
consoleSandbox(() => {
if (isCjs()) {
Expand Down
4 changes: 2 additions & 2 deletions packages/opentelemetry/src/sampler.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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,
Expand DownExpand Up@@ -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 });
}

Expand Down
Original file line numberDiff line numberDiff line change
@@ -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';
Expand DownExpand Up@@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/remix/src/utils/instrumentServer.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ import {
fill,
getClient,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
isNodeEnv,
loadModule,
logger,
Expand DownExpand Up@@ -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);
}

Expand Down
4 changes: 2 additions & 2 deletions packages/vercel-edge/src/sdk.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import {
functionToStringIntegration,
getCurrentScope,
getIntegrationsToSetup,
hasTracingEnabled,
hasSpansEnabled,
inboundFiltersIntegration,
linkedErrorsIntegration,
logger,
Expand DownExpand Up@@ -124,7 +124,7 @@ function validateOpenTelemetrySetup(): void {

const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];

if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
required.push('SentrySpanProcessor');
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/browser/src/tracing/request.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import {
getActiveSpan,
getLocationHref,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
instrumentFetchRequest,
parseUrl,
setHttpStatus,
Expand DownExpand Up@@ -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) {
Expand DownExpand Up@@ -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,
);
}

Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';

Expand DownExpand Up@@ -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;
Expand DownExpand Up@@ -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
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/tracing/dynamicSamplingContext.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';

Expand DownExpand Up@@ -118,10 +118,10 @@ export function getDynamicSamplingContextFromSpan(span: Span): Readonly<Partial<
dsc.transaction = name;
}

// How can we even land here with hasTracingEnabled() returning false?
// How can we even land here with hasSpansEnabled() returning false?
// Otel creates a Non-recording span in Tracing Without Performance mode when handling incoming requests
// So we end up with an active span that is not sampled (neither positively nor negatively)
if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
dsc.sampled = String(spanIsSampled(rootSpan));
dsc.sample_rand =
// In OTEL we store the sample rand on the trace state because we cannot access scopes for NonRecordingSpans
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/tracing/idleSpan.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ import { DEBUG_BUILD } from '../debug-build';
import { SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON } from '../semanticAttributes';
import { logger } from '../utils-hoist/logger';
import { timestampInSeconds } from '../utils-hoist/time';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { _setSpanForScope } from '../utils/spanOnScope';
import {
getActiveSpan,
Expand DownExpand Up@@ -109,7 +109,7 @@ export function startIdleSpan(startSpanOptions: StartSpanOptions, options: Parti

const client = getClient();

if (!client || !hasTracingEnabled()) {
if (!client || !hasSpansEnabled()) {
const span = new SentryNonRecordingSpan();

const dsc = {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/tracing/sampling.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,7 @@ import type { Options, SamplingContext } from '../types-hoist';

import { DEBUG_BUILD } from '../debug-build';
import { logger } from '../utils-hoist/logger';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { parseSampleRate } from '../utils/parseSampleRate';

/**
Expand All@@ -16,8 +16,8 @@ export function sampleSpan(
samplingContext: SamplingContext,
sampleRand: number,
): [sampled: boolean, sampleRate?: number, localSampleRateWasApplied?: boolean] {
// nothing to do if tracing is not enabled
if (!hasTracingEnabled(options)) {
// nothing to do if span recording is not enabled
if (!hasSpansEnabled(options)) {
return [false];
}

Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/tracing/trace.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ import { logger } from '../utils-hoist/logger';
import { generateTraceId } from '../utils-hoist/propagationContext';
import { propagationContextFromHeaders } from '../utils-hoist/tracing';
import { handleCallbackErrors } from '../utils/handleCallbackErrors';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { parseSampleRate } from '../utils/parseSampleRate';
import { _getSpanForScope, _setSpanForScope } from '../utils/spanOnScope';
import { addChildSpanToSpan, getRootSpan, spanIsSampled, spanTimeInputToSeconds, spanToJSON } from '../utils/spanUtils';
Expand DownExpand Up@@ -302,7 +302,7 @@ function createChildOrRootSpan({
forceTransaction?: boolean;
scope: Scope;
}): Span {
if (!hasTracingEnabled()) {
if (!hasSpansEnabled()) {
const span = new SentryNonRecordingSpan();

// If this is a root span, we ensure to freeze a DSC
Expand Down
44 changes: 44 additions & 0 deletions packages/core/src/utils/hasSpansEnabled.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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 span recording is currently enabled.
*
* Spans are recorded when at least one of `tracesSampleRate` and `tracesSampler`
* is defined in the SDK config. This function does not make any assumption about
* sampling decisions, it only checks if the SDK is configured to record spans.
*
* Important: This function only determines if span recording is enabled. Trace
* continuation and propagation is separately controlled and not covered by this function.
* If this function returns `false`, traces can still be propagated (which is what
* we refer to by "Tracing without Performance")
* @see https://develop.sentry.dev/sdk/telemetry/traces/tracing-without-performance/
*
* @param maybeOptions An SDK options object to be passed to this function.
* If this option is not provided, the function will use the current client's options.
*/
export function hasSpansEnabled(
maybeOptions?: Pick<Options, 'tracesSampleRate' | 'tracesSampler'> | 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;
26 changes: 0 additions & 26 deletions packages/core/src/utils/hasTracingEnabled.ts

This file was deleted.

14 changes: 7 additions & 7 deletions packages/core/test/lib/utils/hasTracingEnabled.test.ts
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
import { hasSpansEnabled } from '../../../src';
import { hasTracingEnabled } from '../../../src';

describe('hasTracingEnabled', () => {
describe('hasSpansEnabled', () => {
const tracesSampler = () => 1;
const tracesSampleRate = 1;
it.each([
Expand All@@ -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<typeof hasTracingEnabled>[0], output: ReturnType<typeof hasTracingEnabled>) => {
expect(hasTracingEnabled(input)).toBe(output);
},
);
])('%s', (_: string, input: Parameters<typeof hasSpansEnabled>[0], output: ReturnType<typeof hasSpansEnabled>) => {
expect(hasSpansEnabled(input)).toBe(output);
// eslint-disable-next-line deprecation/deprecation
expect(hasTracingEnabled(input)).toBe(output);
});
});
2 changes: 1 addition & 1 deletion packages/nextjs/test/config/wrappers.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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: () => ({}),
Expand Down
6 changes: 3 additions & 3 deletions packages/node/src/integrations/node-fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@ import {
getClient,
getSanitizedUrlString,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
parseUrl,
} from '@sentry/core';
import { shouldPropagateTraceForUrl } from '@sentry/opentelemetry';
Expand DownExpand Up@@ -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()
Expand Down
6 changes: 3 additions & 3 deletions packages/node/src/sdk/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ import {
functionToStringIntegration,
getCurrentScope,
getIntegrationsToSetup,
hasTracingEnabled,
hasSpansEnabled,
inboundFiltersIntegration,
linkedErrorsIntegration,
logger,
Expand DownExpand Up@@ -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() : []),
];
}

Expand DownExpand Up@@ -175,7 +175,7 @@ export function validateOpenTelemetrySetup(): void {

const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];

if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
required.push('SentrySpanProcessor');
}

Expand Down
8 changes: 4 additions & 4 deletions packages/node/src/utils/ensureIsWrapped.ts
Original file line numberDiff line numberDiff line change
@@ -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';
Expand All@@ -11,12 +11,12 @@ export function ensureIsWrapped(
maybeWrappedFunction: unknown,
name: 'express' | 'connect' | 'fastify' | 'hapi' | 'koa',
): void {
const client = getClient<NodeClient>();
const clientOptions = getClient<NodeClient>()?.getOptions();
if (
!client?.getOptions().disableInstrumentationWarnings &&
!clientOptions?.disableInstrumentationWarnings &&
!isWrapped(maybeWrappedFunction) &&
isEnabled() &&
hasTracingEnabled()
hasSpansEnabled(clientOptions)
) {
consoleSandbox(() => {
if (isCjs()) {
Expand Down
4 changes: 2 additions & 2 deletions packages/opentelemetry/src/sampler.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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,
Expand DownExpand Up@@ -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 });
}

Expand Down
Original file line numberDiff line numberDiff line change
@@ -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';
Expand DownExpand Up@@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/remix/src/utils/instrumentServer.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ import {
fill,
getClient,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
isNodeEnv,
loadModule,
logger,
Expand DownExpand Up@@ -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);
}

Expand Down
4 changes: 2 additions & 2 deletions packages/vercel-edge/src/sdk.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import {
functionToStringIntegration,
getCurrentScope,
getIntegrationsToSetup,
hasTracingEnabled,
hasSpansEnabled,
inboundFiltersIntegration,
linkedErrorsIntegration,
logger,
Expand DownExpand Up@@ -124,7 +124,7 @@ function validateOpenTelemetrySetup(): void {

const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];

if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
required.push('SentrySpanProcessor');
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/browser/src/tracing/request.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import {
getActiveSpan,
getLocationHref,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
instrumentFetchRequest,
parseUrl,
setHttpStatus,
Expand DownExpand Up@@ -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) {
Expand DownExpand Up@@ -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,
);
}

Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';

Expand DownExpand Up@@ -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;
Expand DownExpand Up@@ -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
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/tracing/dynamicSamplingContext.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';

Expand DownExpand Up@@ -118,10 +118,10 @@ export function getDynamicSamplingContextFromSpan(span: Span): Readonly<Partial<
dsc.transaction = name;
}

// How can we even land here with hasTracingEnabled() returning false?
// How can we even land here with hasSpansEnabled() returning false?
// Otel creates a Non-recording span in Tracing Without Performance mode when handling incoming requests
// So we end up with an active span that is not sampled (neither positively nor negatively)
if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
dsc.sampled = String(spanIsSampled(rootSpan));
dsc.sample_rand =
// In OTEL we store the sample rand on the trace state because we cannot access scopes for NonRecordingSpans
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/tracing/idleSpan.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ import { DEBUG_BUILD } from '../debug-build';
import { SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON } from '../semanticAttributes';
import { logger } from '../utils-hoist/logger';
import { timestampInSeconds } from '../utils-hoist/time';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { _setSpanForScope } from '../utils/spanOnScope';
import {
getActiveSpan,
Expand DownExpand Up@@ -109,7 +109,7 @@ export function startIdleSpan(startSpanOptions: StartSpanOptions, options: Parti

const client = getClient();

if (!client || !hasTracingEnabled()) {
if (!client || !hasSpansEnabled()) {
const span = new SentryNonRecordingSpan();

const dsc = {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/tracing/sampling.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,7 @@ import type { Options, SamplingContext } from '../types-hoist';

import { DEBUG_BUILD } from '../debug-build';
import { logger } from '../utils-hoist/logger';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { parseSampleRate } from '../utils/parseSampleRate';

/**
Expand All@@ -16,8 +16,8 @@ export function sampleSpan(
samplingContext: SamplingContext,
sampleRand: number,
): [sampled: boolean, sampleRate?: number, localSampleRateWasApplied?: boolean] {
// nothing to do if tracing is not enabled
if (!hasTracingEnabled(options)) {
// nothing to do if span recording is not enabled
if (!hasSpansEnabled(options)) {
return [false];
}

Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/tracing/trace.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ import { logger } from '../utils-hoist/logger';
import { generateTraceId } from '../utils-hoist/propagationContext';
import { propagationContextFromHeaders } from '../utils-hoist/tracing';
import { handleCallbackErrors } from '../utils/handleCallbackErrors';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { parseSampleRate } from '../utils/parseSampleRate';
import { _getSpanForScope, _setSpanForScope } from '../utils/spanOnScope';
import { addChildSpanToSpan, getRootSpan, spanIsSampled, spanTimeInputToSeconds, spanToJSON } from '../utils/spanUtils';
Expand DownExpand Up@@ -302,7 +302,7 @@ function createChildOrRootSpan({
forceTransaction?: boolean;
scope: Scope;
}): Span {
if (!hasTracingEnabled()) {
if (!hasSpansEnabled()) {
const span = new SentryNonRecordingSpan();

// If this is a root span, we ensure to freeze a DSC
Expand Down
44 changes: 44 additions & 0 deletions packages/core/src/utils/hasSpansEnabled.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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 span recording is currently enabled.
*
* Spans are recorded when at least one of `tracesSampleRate` and `tracesSampler`
* is defined in the SDK config. This function does not make any assumption about
* sampling decisions, it only checks if the SDK is configured to record spans.
*
* Important: This function only determines if span recording is enabled. Trace
* continuation and propagation is separately controlled and not covered by this function.
* If this function returns `false`, traces can still be propagated (which is what
* we refer to by "Tracing without Performance")
* @see https://develop.sentry.dev/sdk/telemetry/traces/tracing-without-performance/
*
* @param maybeOptions An SDK options object to be passed to this function.
* If this option is not provided, the function will use the current client's options.
*/
export function hasSpansEnabled(
maybeOptions?: Pick<Options, 'tracesSampleRate' | 'tracesSampler'> | 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;
26 changes: 0 additions & 26 deletions packages/core/src/utils/hasTracingEnabled.ts

This file was deleted.

14 changes: 7 additions & 7 deletions packages/core/test/lib/utils/hasTracingEnabled.test.ts
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
import { hasSpansEnabled } from '../../../src';
import { hasTracingEnabled } from '../../../src';

describe('hasTracingEnabled', () => {
describe('hasSpansEnabled', () => {
const tracesSampler = () => 1;
const tracesSampleRate = 1;
it.each([
Expand All@@ -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<typeof hasTracingEnabled>[0], output: ReturnType<typeof hasTracingEnabled>) => {
expect(hasTracingEnabled(input)).toBe(output);
},
);
])('%s', (_: string, input: Parameters<typeof hasSpansEnabled>[0], output: ReturnType<typeof hasSpansEnabled>) => {
expect(hasSpansEnabled(input)).toBe(output);
// eslint-disable-next-line deprecation/deprecation
expect(hasTracingEnabled(input)).toBe(output);
});
});
2 changes: 1 addition & 1 deletion packages/nextjs/test/config/wrappers.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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: () => ({}),
Expand Down
6 changes: 3 additions & 3 deletions packages/node/src/integrations/node-fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@ import {
getClient,
getSanitizedUrlString,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
parseUrl,
} from '@sentry/core';
import { shouldPropagateTraceForUrl } from '@sentry/opentelemetry';
Expand DownExpand Up@@ -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()
Expand Down
6 changes: 3 additions & 3 deletions packages/node/src/sdk/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ import {
functionToStringIntegration,
getCurrentScope,
getIntegrationsToSetup,
hasTracingEnabled,
hasSpansEnabled,
inboundFiltersIntegration,
linkedErrorsIntegration,
logger,
Expand DownExpand Up@@ -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() : []),
];
}

Expand DownExpand Up@@ -175,7 +175,7 @@ export function validateOpenTelemetrySetup(): void {

const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];

if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
required.push('SentrySpanProcessor');
}

Expand Down
8 changes: 4 additions & 4 deletions packages/node/src/utils/ensureIsWrapped.ts
Original file line numberDiff line numberDiff line change
@@ -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';
Expand All@@ -11,12 +11,12 @@ export function ensureIsWrapped(
maybeWrappedFunction: unknown,
name: 'express' | 'connect' | 'fastify' | 'hapi' | 'koa',
): void {
const client = getClient<NodeClient>();
const clientOptions = getClient<NodeClient>()?.getOptions();
if (
!client?.getOptions().disableInstrumentationWarnings &&
!clientOptions?.disableInstrumentationWarnings &&
!isWrapped(maybeWrappedFunction) &&
isEnabled() &&
hasTracingEnabled()
hasSpansEnabled(clientOptions)
) {
consoleSandbox(() => {
if (isCjs()) {
Expand Down
4 changes: 2 additions & 2 deletions packages/opentelemetry/src/sampler.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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,
Expand DownExpand Up@@ -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 });
}

Expand Down
Original file line numberDiff line numberDiff line change
@@ -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';
Expand DownExpand Up@@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/remix/src/utils/instrumentServer.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ import {
fill,
getClient,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
isNodeEnv,
loadModule,
logger,
Expand DownExpand Up@@ -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);
}

Expand Down
4 changes: 2 additions & 2 deletions packages/vercel-edge/src/sdk.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import {
functionToStringIntegration,
getCurrentScope,
getIntegrationsToSetup,
hasTracingEnabled,
hasSpansEnabled,
inboundFiltersIntegration,
linkedErrorsIntegration,
logger,
Expand DownExpand Up@@ -124,7 +124,7 @@ function validateOpenTelemetrySetup(): void {

const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];

if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
required.push('SentrySpanProcessor');
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/browser/src/tracing/request.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import {
getActiveSpan,
getLocationHref,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
instrumentFetchRequest,
parseUrl,
setHttpStatus,
Expand DownExpand Up@@ -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) {
Expand DownExpand Up@@ -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,
);
}

Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';

Expand DownExpand Up@@ -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;
Expand DownExpand Up@@ -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
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/tracing/dynamicSamplingContext.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';

Expand DownExpand Up@@ -118,10 +118,10 @@ export function getDynamicSamplingContextFromSpan(span: Span): Readonly<Partial<
dsc.transaction = name;
}

// How can we even land here with hasTracingEnabled() returning false?
// How can we even land here with hasSpansEnabled() returning false?
// Otel creates a Non-recording span in Tracing Without Performance mode when handling incoming requests
// So we end up with an active span that is not sampled (neither positively nor negatively)
if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
dsc.sampled = String(spanIsSampled(rootSpan));
dsc.sample_rand =
// In OTEL we store the sample rand on the trace state because we cannot access scopes for NonRecordingSpans
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/tracing/idleSpan.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ import { DEBUG_BUILD } from '../debug-build';
import { SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON } from '../semanticAttributes';
import { logger } from '../utils-hoist/logger';
import { timestampInSeconds } from '../utils-hoist/time';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { _setSpanForScope } from '../utils/spanOnScope';
import {
getActiveSpan,
Expand DownExpand Up@@ -109,7 +109,7 @@ export function startIdleSpan(startSpanOptions: StartSpanOptions, options: Parti

const client = getClient();

if (!client || !hasTracingEnabled()) {
if (!client || !hasSpansEnabled()) {
const span = new SentryNonRecordingSpan();

const dsc = {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/tracing/sampling.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,7 @@ import type { Options, SamplingContext } from '../types-hoist';

import { DEBUG_BUILD } from '../debug-build';
import { logger } from '../utils-hoist/logger';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { parseSampleRate } from '../utils/parseSampleRate';

/**
Expand All@@ -16,8 +16,8 @@ export function sampleSpan(
samplingContext: SamplingContext,
sampleRand: number,
): [sampled: boolean, sampleRate?: number, localSampleRateWasApplied?: boolean] {
// nothing to do if tracing is not enabled
if (!hasTracingEnabled(options)) {
// nothing to do if span recording is not enabled
if (!hasSpansEnabled(options)) {
return [false];
}

Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/tracing/trace.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ import { logger } from '../utils-hoist/logger';
import { generateTraceId } from '../utils-hoist/propagationContext';
import { propagationContextFromHeaders } from '../utils-hoist/tracing';
import { handleCallbackErrors } from '../utils/handleCallbackErrors';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { parseSampleRate } from '../utils/parseSampleRate';
import { _getSpanForScope, _setSpanForScope } from '../utils/spanOnScope';
import { addChildSpanToSpan, getRootSpan, spanIsSampled, spanTimeInputToSeconds, spanToJSON } from '../utils/spanUtils';
Expand DownExpand Up@@ -302,7 +302,7 @@ function createChildOrRootSpan({
forceTransaction?: boolean;
scope: Scope;
}): Span {
if (!hasTracingEnabled()) {
if (!hasSpansEnabled()) {
const span = new SentryNonRecordingSpan();

// If this is a root span, we ensure to freeze a DSC
Expand Down
44 changes: 44 additions & 0 deletions packages/core/src/utils/hasSpansEnabled.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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 span recording is currently enabled.
*
* Spans are recorded when at least one of `tracesSampleRate` and `tracesSampler`
* is defined in the SDK config. This function does not make any assumption about
* sampling decisions, it only checks if the SDK is configured to record spans.
*
* Important: This function only determines if span recording is enabled. Trace
* continuation and propagation is separately controlled and not covered by this function.
* If this function returns `false`, traces can still be propagated (which is what
* we refer to by "Tracing without Performance")
* @see https://develop.sentry.dev/sdk/telemetry/traces/tracing-without-performance/
*
* @param maybeOptions An SDK options object to be passed to this function.
* If this option is not provided, the function will use the current client's options.
*/
export function hasSpansEnabled(
maybeOptions?: Pick<Options, 'tracesSampleRate' | 'tracesSampler'> | 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;
26 changes: 0 additions & 26 deletions packages/core/src/utils/hasTracingEnabled.ts

This file was deleted.

14 changes: 7 additions & 7 deletions packages/core/test/lib/utils/hasTracingEnabled.test.ts
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
import { hasSpansEnabled } from '../../../src';
import { hasTracingEnabled } from '../../../src';

describe('hasTracingEnabled', () => {
describe('hasSpansEnabled', () => {
const tracesSampler = () => 1;
const tracesSampleRate = 1;
it.each([
Expand All@@ -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<typeof hasTracingEnabled>[0], output: ReturnType<typeof hasTracingEnabled>) => {
expect(hasTracingEnabled(input)).toBe(output);
},
);
])('%s', (_: string, input: Parameters<typeof hasSpansEnabled>[0], output: ReturnType<typeof hasSpansEnabled>) => {
expect(hasSpansEnabled(input)).toBe(output);
// eslint-disable-next-line deprecation/deprecation
expect(hasTracingEnabled(input)).toBe(output);
});
});
2 changes: 1 addition & 1 deletion packages/nextjs/test/config/wrappers.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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: () => ({}),
Expand Down
6 changes: 3 additions & 3 deletions packages/node/src/integrations/node-fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@ import {
getClient,
getSanitizedUrlString,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
parseUrl,
} from '@sentry/core';
import { shouldPropagateTraceForUrl } from '@sentry/opentelemetry';
Expand DownExpand Up@@ -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()
Expand Down
6 changes: 3 additions & 3 deletions packages/node/src/sdk/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ import {
functionToStringIntegration,
getCurrentScope,
getIntegrationsToSetup,
hasTracingEnabled,
hasSpansEnabled,
inboundFiltersIntegration,
linkedErrorsIntegration,
logger,
Expand DownExpand Up@@ -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() : []),
];
}

Expand DownExpand Up@@ -175,7 +175,7 @@ export function validateOpenTelemetrySetup(): void {

const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];

if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
required.push('SentrySpanProcessor');
}

Expand Down
8 changes: 4 additions & 4 deletions packages/node/src/utils/ensureIsWrapped.ts
Original file line numberDiff line numberDiff line change
@@ -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';
Expand All@@ -11,12 +11,12 @@ export function ensureIsWrapped(
maybeWrappedFunction: unknown,
name: 'express' | 'connect' | 'fastify' | 'hapi' | 'koa',
): void {
const client = getClient<NodeClient>();
const clientOptions = getClient<NodeClient>()?.getOptions();
if (
!client?.getOptions().disableInstrumentationWarnings &&
!clientOptions?.disableInstrumentationWarnings &&
!isWrapped(maybeWrappedFunction) &&
isEnabled() &&
hasTracingEnabled()
hasSpansEnabled(clientOptions)
) {
consoleSandbox(() => {
if (isCjs()) {
Expand Down
4 changes: 2 additions & 2 deletions packages/opentelemetry/src/sampler.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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,
Expand DownExpand Up@@ -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 });
}

Expand Down
Original file line numberDiff line numberDiff line change
@@ -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';
Expand DownExpand Up@@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/remix/src/utils/instrumentServer.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ import {
fill,
getClient,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
isNodeEnv,
loadModule,
logger,
Expand DownExpand Up@@ -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);
}

Expand Down
4 changes: 2 additions & 2 deletions packages/vercel-edge/src/sdk.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import {
functionToStringIntegration,
getCurrentScope,
getIntegrationsToSetup,
hasTracingEnabled,
hasSpansEnabled,
inboundFiltersIntegration,
linkedErrorsIntegration,
logger,
Expand DownExpand Up@@ -124,7 +124,7 @@ function validateOpenTelemetrySetup(): void {

const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];

if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
required.push('SentrySpanProcessor');
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/browser/src/tracing/request.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import {
getActiveSpan,
getLocationHref,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
instrumentFetchRequest,
parseUrl,
setHttpStatus,
Expand DownExpand Up@@ -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) {
Expand DownExpand Up@@ -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,
);
}

Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';

Expand DownExpand Up@@ -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;
Expand DownExpand Up@@ -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
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/tracing/dynamicSamplingContext.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';

Expand DownExpand Up@@ -118,10 +118,10 @@ export function getDynamicSamplingContextFromSpan(span: Span): Readonly<Partial<
dsc.transaction = name;
}

// How can we even land here with hasTracingEnabled() returning false?
// How can we even land here with hasSpansEnabled() returning false?
// Otel creates a Non-recording span in Tracing Without Performance mode when handling incoming requests
// So we end up with an active span that is not sampled (neither positively nor negatively)
if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
dsc.sampled = String(spanIsSampled(rootSpan));
dsc.sample_rand =
// In OTEL we store the sample rand on the trace state because we cannot access scopes for NonRecordingSpans
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/tracing/idleSpan.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ import { DEBUG_BUILD } from '../debug-build';
import { SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON } from '../semanticAttributes';
import { logger } from '../utils-hoist/logger';
import { timestampInSeconds } from '../utils-hoist/time';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { _setSpanForScope } from '../utils/spanOnScope';
import {
getActiveSpan,
Expand DownExpand Up@@ -109,7 +109,7 @@ export function startIdleSpan(startSpanOptions: StartSpanOptions, options: Parti

const client = getClient();

if (!client || !hasTracingEnabled()) {
if (!client || !hasSpansEnabled()) {
const span = new SentryNonRecordingSpan();

const dsc = {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/tracing/sampling.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,7 @@ import type { Options, SamplingContext } from '../types-hoist';

import { DEBUG_BUILD } from '../debug-build';
import { logger } from '../utils-hoist/logger';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { parseSampleRate } from '../utils/parseSampleRate';

/**
Expand All@@ -16,8 +16,8 @@ export function sampleSpan(
samplingContext: SamplingContext,
sampleRand: number,
): [sampled: boolean, sampleRate?: number, localSampleRateWasApplied?: boolean] {
// nothing to do if tracing is not enabled
if (!hasTracingEnabled(options)) {
// nothing to do if span recording is not enabled
if (!hasSpansEnabled(options)) {
return [false];
}

Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/tracing/trace.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ import { logger } from '../utils-hoist/logger';
import { generateTraceId } from '../utils-hoist/propagationContext';
import { propagationContextFromHeaders } from '../utils-hoist/tracing';
import { handleCallbackErrors } from '../utils/handleCallbackErrors';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { parseSampleRate } from '../utils/parseSampleRate';
import { _getSpanForScope, _setSpanForScope } from '../utils/spanOnScope';
import { addChildSpanToSpan, getRootSpan, spanIsSampled, spanTimeInputToSeconds, spanToJSON } from '../utils/spanUtils';
Expand DownExpand Up@@ -302,7 +302,7 @@ function createChildOrRootSpan({
forceTransaction?: boolean;
scope: Scope;
}): Span {
if (!hasTracingEnabled()) {
if (!hasSpansEnabled()) {
const span = new SentryNonRecordingSpan();

// If this is a root span, we ensure to freeze a DSC
Expand Down
44 changes: 44 additions & 0 deletions packages/core/src/utils/hasSpansEnabled.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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 span recording is currently enabled.
*
* Spans are recorded when at least one of `tracesSampleRate` and `tracesSampler`
* is defined in the SDK config. This function does not make any assumption about
* sampling decisions, it only checks if the SDK is configured to record spans.
*
* Important: This function only determines if span recording is enabled. Trace
* continuation and propagation is separately controlled and not covered by this function.
* If this function returns `false`, traces can still be propagated (which is what
* we refer to by "Tracing without Performance")
* @see https://develop.sentry.dev/sdk/telemetry/traces/tracing-without-performance/
*
* @param maybeOptions An SDK options object to be passed to this function.
* If this option is not provided, the function will use the current client's options.
*/
export function hasSpansEnabled(
maybeOptions?: Pick<Options, 'tracesSampleRate' | 'tracesSampler'> | 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;
26 changes: 0 additions & 26 deletions packages/core/src/utils/hasTracingEnabled.ts

This file was deleted.

14 changes: 7 additions & 7 deletions packages/core/test/lib/utils/hasTracingEnabled.test.ts
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
import { hasSpansEnabled } from '../../../src';
import { hasTracingEnabled } from '../../../src';

describe('hasTracingEnabled', () => {
describe('hasSpansEnabled', () => {
const tracesSampler = () => 1;
const tracesSampleRate = 1;
it.each([
Expand All@@ -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<typeof hasTracingEnabled>[0], output: ReturnType<typeof hasTracingEnabled>) => {
expect(hasTracingEnabled(input)).toBe(output);
},
);
])('%s', (_: string, input: Parameters<typeof hasSpansEnabled>[0], output: ReturnType<typeof hasSpansEnabled>) => {
expect(hasSpansEnabled(input)).toBe(output);
// eslint-disable-next-line deprecation/deprecation
expect(hasTracingEnabled(input)).toBe(output);
});
});
2 changes: 1 addition & 1 deletion packages/nextjs/test/config/wrappers.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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: () => ({}),
Expand Down
6 changes: 3 additions & 3 deletions packages/node/src/integrations/node-fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@ import {
getClient,
getSanitizedUrlString,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
parseUrl,
} from '@sentry/core';
import { shouldPropagateTraceForUrl } from '@sentry/opentelemetry';
Expand DownExpand Up@@ -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()
Expand Down
6 changes: 3 additions & 3 deletions packages/node/src/sdk/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ import {
functionToStringIntegration,
getCurrentScope,
getIntegrationsToSetup,
hasTracingEnabled,
hasSpansEnabled,
inboundFiltersIntegration,
linkedErrorsIntegration,
logger,
Expand DownExpand Up@@ -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() : []),
];
}

Expand DownExpand Up@@ -175,7 +175,7 @@ export function validateOpenTelemetrySetup(): void {

const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];

if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
required.push('SentrySpanProcessor');
}

Expand Down
8 changes: 4 additions & 4 deletions packages/node/src/utils/ensureIsWrapped.ts
Original file line numberDiff line numberDiff line change
@@ -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';
Expand All@@ -11,12 +11,12 @@ export function ensureIsWrapped(
maybeWrappedFunction: unknown,
name: 'express' | 'connect' | 'fastify' | 'hapi' | 'koa',
): void {
const client = getClient<NodeClient>();
const clientOptions = getClient<NodeClient>()?.getOptions();
if (
!client?.getOptions().disableInstrumentationWarnings &&
!clientOptions?.disableInstrumentationWarnings &&
!isWrapped(maybeWrappedFunction) &&
isEnabled() &&
hasTracingEnabled()
hasSpansEnabled(clientOptions)
) {
consoleSandbox(() => {
if (isCjs()) {
Expand Down
4 changes: 2 additions & 2 deletions packages/opentelemetry/src/sampler.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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,
Expand DownExpand Up@@ -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 });
}

Expand Down
Original file line numberDiff line numberDiff line change
@@ -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';
Expand DownExpand Up@@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/remix/src/utils/instrumentServer.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ import {
fill,
getClient,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
isNodeEnv,
loadModule,
logger,
Expand DownExpand Up@@ -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);
}

Expand Down
4 changes: 2 additions & 2 deletions packages/vercel-edge/src/sdk.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import {
functionToStringIntegration,
getCurrentScope,
getIntegrationsToSetup,
hasTracingEnabled,
hasSpansEnabled,
inboundFiltersIntegration,
linkedErrorsIntegration,
logger,
Expand DownExpand Up@@ -124,7 +124,7 @@ function validateOpenTelemetrySetup(): void {

const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];

if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
required.push('SentrySpanProcessor');
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/browser/src/tracing/request.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import {
getActiveSpan,
getLocationHref,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
instrumentFetchRequest,
parseUrl,
setHttpStatus,
Expand DownExpand Up@@ -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) {
Expand DownExpand Up@@ -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,
);
}

Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';

Expand DownExpand Up@@ -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;
Expand DownExpand Up@@ -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
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/tracing/dynamicSamplingContext.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';

Expand DownExpand Up@@ -118,10 +118,10 @@ export function getDynamicSamplingContextFromSpan(span: Span): Readonly<Partial<
dsc.transaction = name;
}

// How can we even land here with hasTracingEnabled() returning false?
// How can we even land here with hasSpansEnabled() returning false?
// Otel creates a Non-recording span in Tracing Without Performance mode when handling incoming requests
// So we end up with an active span that is not sampled (neither positively nor negatively)
if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
dsc.sampled = String(spanIsSampled(rootSpan));
dsc.sample_rand =
// In OTEL we store the sample rand on the trace state because we cannot access scopes for NonRecordingSpans
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/tracing/idleSpan.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ import { DEBUG_BUILD } from '../debug-build';
import { SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON } from '../semanticAttributes';
import { logger } from '../utils-hoist/logger';
import { timestampInSeconds } from '../utils-hoist/time';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { _setSpanForScope } from '../utils/spanOnScope';
import {
getActiveSpan,
Expand DownExpand Up@@ -109,7 +109,7 @@ export function startIdleSpan(startSpanOptions: StartSpanOptions, options: Parti

const client = getClient();

if (!client || !hasTracingEnabled()) {
if (!client || !hasSpansEnabled()) {
const span = new SentryNonRecordingSpan();

const dsc = {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/tracing/sampling.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,7 @@ import type { Options, SamplingContext } from '../types-hoist';

import { DEBUG_BUILD } from '../debug-build';
import { logger } from '../utils-hoist/logger';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { parseSampleRate } from '../utils/parseSampleRate';

/**
Expand All@@ -16,8 +16,8 @@ export function sampleSpan(
samplingContext: SamplingContext,
sampleRand: number,
): [sampled: boolean, sampleRate?: number, localSampleRateWasApplied?: boolean] {
// nothing to do if tracing is not enabled
if (!hasTracingEnabled(options)) {
// nothing to do if span recording is not enabled
if (!hasSpansEnabled(options)) {
return [false];
}

Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/tracing/trace.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ import { logger } from '../utils-hoist/logger';
import { generateTraceId } from '../utils-hoist/propagationContext';
import { propagationContextFromHeaders } from '../utils-hoist/tracing';
import { handleCallbackErrors } from '../utils/handleCallbackErrors';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { parseSampleRate } from '../utils/parseSampleRate';
import { _getSpanForScope, _setSpanForScope } from '../utils/spanOnScope';
import { addChildSpanToSpan, getRootSpan, spanIsSampled, spanTimeInputToSeconds, spanToJSON } from '../utils/spanUtils';
Expand DownExpand Up@@ -302,7 +302,7 @@ function createChildOrRootSpan({
forceTransaction?: boolean;
scope: Scope;
}): Span {
if (!hasTracingEnabled()) {
if (!hasSpansEnabled()) {
const span = new SentryNonRecordingSpan();

// If this is a root span, we ensure to freeze a DSC
Expand Down
44 changes: 44 additions & 0 deletions packages/core/src/utils/hasSpansEnabled.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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 span recording is currently enabled.
*
* Spans are recorded when at least one of `tracesSampleRate` and `tracesSampler`
* is defined in the SDK config. This function does not make any assumption about
* sampling decisions, it only checks if the SDK is configured to record spans.
*
* Important: This function only determines if span recording is enabled. Trace
* continuation and propagation is separately controlled and not covered by this function.
* If this function returns `false`, traces can still be propagated (which is what
* we refer to by "Tracing without Performance")
* @see https://develop.sentry.dev/sdk/telemetry/traces/tracing-without-performance/
*
* @param maybeOptions An SDK options object to be passed to this function.
* If this option is not provided, the function will use the current client's options.
*/
export function hasSpansEnabled(
maybeOptions?: Pick<Options, 'tracesSampleRate' | 'tracesSampler'> | 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;
26 changes: 0 additions & 26 deletions packages/core/src/utils/hasTracingEnabled.ts

This file was deleted.

14 changes: 7 additions & 7 deletions packages/core/test/lib/utils/hasTracingEnabled.test.ts
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
import { hasSpansEnabled } from '../../../src';
import { hasTracingEnabled } from '../../../src';

describe('hasTracingEnabled', () => {
describe('hasSpansEnabled', () => {
const tracesSampler = () => 1;
const tracesSampleRate = 1;
it.each([
Expand All@@ -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<typeof hasTracingEnabled>[0], output: ReturnType<typeof hasTracingEnabled>) => {
expect(hasTracingEnabled(input)).toBe(output);
},
);
])('%s', (_: string, input: Parameters<typeof hasSpansEnabled>[0], output: ReturnType<typeof hasSpansEnabled>) => {
expect(hasSpansEnabled(input)).toBe(output);
// eslint-disable-next-line deprecation/deprecation
expect(hasTracingEnabled(input)).toBe(output);
});
});
2 changes: 1 addition & 1 deletion packages/nextjs/test/config/wrappers.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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: () => ({}),
Expand Down
6 changes: 3 additions & 3 deletions packages/node/src/integrations/node-fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@ import {
getClient,
getSanitizedUrlString,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
parseUrl,
} from '@sentry/core';
import { shouldPropagateTraceForUrl } from '@sentry/opentelemetry';
Expand DownExpand Up@@ -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()
Expand Down
6 changes: 3 additions & 3 deletions packages/node/src/sdk/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ import {
functionToStringIntegration,
getCurrentScope,
getIntegrationsToSetup,
hasTracingEnabled,
hasSpansEnabled,
inboundFiltersIntegration,
linkedErrorsIntegration,
logger,
Expand DownExpand Up@@ -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() : []),
];
}

Expand DownExpand Up@@ -175,7 +175,7 @@ export function validateOpenTelemetrySetup(): void {

const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];

if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
required.push('SentrySpanProcessor');
}

Expand Down
8 changes: 4 additions & 4 deletions packages/node/src/utils/ensureIsWrapped.ts
Original file line numberDiff line numberDiff line change
@@ -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';
Expand All@@ -11,12 +11,12 @@ export function ensureIsWrapped(
maybeWrappedFunction: unknown,
name: 'express' | 'connect' | 'fastify' | 'hapi' | 'koa',
): void {
const client = getClient<NodeClient>();
const clientOptions = getClient<NodeClient>()?.getOptions();
if (
!client?.getOptions().disableInstrumentationWarnings &&
!clientOptions?.disableInstrumentationWarnings &&
!isWrapped(maybeWrappedFunction) &&
isEnabled() &&
hasTracingEnabled()
hasSpansEnabled(clientOptions)
) {
consoleSandbox(() => {
if (isCjs()) {
Expand Down
4 changes: 2 additions & 2 deletions packages/opentelemetry/src/sampler.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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,
Expand DownExpand Up@@ -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 });
}

Expand Down
Original file line numberDiff line numberDiff line change
@@ -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';
Expand DownExpand Up@@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/remix/src/utils/instrumentServer.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ import {
fill,
getClient,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
isNodeEnv,
loadModule,
logger,
Expand DownExpand Up@@ -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);
}

Expand Down
4 changes: 2 additions & 2 deletions packages/vercel-edge/src/sdk.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import {
functionToStringIntegration,
getCurrentScope,
getIntegrationsToSetup,
hasTracingEnabled,
hasSpansEnabled,
inboundFiltersIntegration,
linkedErrorsIntegration,
logger,
Expand DownExpand Up@@ -124,7 +124,7 @@ function validateOpenTelemetrySetup(): void {

const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];

if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
required.push('SentrySpanProcessor');
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/browser/src/tracing/request.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import {
getActiveSpan,
getLocationHref,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
instrumentFetchRequest,
parseUrl,
setHttpStatus,
Expand DownExpand Up@@ -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) {
Expand DownExpand Up@@ -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,
);
}

Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';

Expand DownExpand Up@@ -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;
Expand DownExpand Up@@ -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
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/tracing/dynamicSamplingContext.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';

Expand DownExpand Up@@ -118,10 +118,10 @@ export function getDynamicSamplingContextFromSpan(span: Span): Readonly<Partial<
dsc.transaction = name;
}

// How can we even land here with hasTracingEnabled() returning false?
// How can we even land here with hasSpansEnabled() returning false?
// Otel creates a Non-recording span in Tracing Without Performance mode when handling incoming requests
// So we end up with an active span that is not sampled (neither positively nor negatively)
if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
dsc.sampled = String(spanIsSampled(rootSpan));
dsc.sample_rand =
// In OTEL we store the sample rand on the trace state because we cannot access scopes for NonRecordingSpans
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/tracing/idleSpan.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ import { DEBUG_BUILD } from '../debug-build';
import { SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON } from '../semanticAttributes';
import { logger } from '../utils-hoist/logger';
import { timestampInSeconds } from '../utils-hoist/time';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { _setSpanForScope } from '../utils/spanOnScope';
import {
getActiveSpan,
Expand DownExpand Up@@ -109,7 +109,7 @@ export function startIdleSpan(startSpanOptions: StartSpanOptions, options: Parti

const client = getClient();

if (!client || !hasTracingEnabled()) {
if (!client || !hasSpansEnabled()) {
const span = new SentryNonRecordingSpan();

const dsc = {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/tracing/sampling.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,7 @@ import type { Options, SamplingContext } from '../types-hoist';

import { DEBUG_BUILD } from '../debug-build';
import { logger } from '../utils-hoist/logger';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { parseSampleRate } from '../utils/parseSampleRate';

/**
Expand All@@ -16,8 +16,8 @@ export function sampleSpan(
samplingContext: SamplingContext,
sampleRand: number,
): [sampled: boolean, sampleRate?: number, localSampleRateWasApplied?: boolean] {
// nothing to do if tracing is not enabled
if (!hasTracingEnabled(options)) {
// nothing to do if span recording is not enabled
if (!hasSpansEnabled(options)) {
return [false];
}

Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/tracing/trace.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ import { logger } from '../utils-hoist/logger';
import { generateTraceId } from '../utils-hoist/propagationContext';
import { propagationContextFromHeaders } from '../utils-hoist/tracing';
import { handleCallbackErrors } from '../utils/handleCallbackErrors';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { parseSampleRate } from '../utils/parseSampleRate';
import { _getSpanForScope, _setSpanForScope } from '../utils/spanOnScope';
import { addChildSpanToSpan, getRootSpan, spanIsSampled, spanTimeInputToSeconds, spanToJSON } from '../utils/spanUtils';
Expand DownExpand Up@@ -302,7 +302,7 @@ function createChildOrRootSpan({
forceTransaction?: boolean;
scope: Scope;
}): Span {
if (!hasTracingEnabled()) {
if (!hasSpansEnabled()) {
const span = new SentryNonRecordingSpan();

// If this is a root span, we ensure to freeze a DSC
Expand Down
44 changes: 44 additions & 0 deletions packages/core/src/utils/hasSpansEnabled.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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 span recording is currently enabled.
*
* Spans are recorded when at least one of `tracesSampleRate` and `tracesSampler`
* is defined in the SDK config. This function does not make any assumption about
* sampling decisions, it only checks if the SDK is configured to record spans.
*
* Important: This function only determines if span recording is enabled. Trace
* continuation and propagation is separately controlled and not covered by this function.
* If this function returns `false`, traces can still be propagated (which is what
* we refer to by "Tracing without Performance")
* @see https://develop.sentry.dev/sdk/telemetry/traces/tracing-without-performance/
*
* @param maybeOptions An SDK options object to be passed to this function.
* If this option is not provided, the function will use the current client's options.
*/
export function hasSpansEnabled(
maybeOptions?: Pick<Options, 'tracesSampleRate' | 'tracesSampler'> | 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;
26 changes: 0 additions & 26 deletions packages/core/src/utils/hasTracingEnabled.ts

This file was deleted.

14 changes: 7 additions & 7 deletions packages/core/test/lib/utils/hasTracingEnabled.test.ts
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
import { hasSpansEnabled } from '../../../src';
import { hasTracingEnabled } from '../../../src';

describe('hasTracingEnabled', () => {
describe('hasSpansEnabled', () => {
const tracesSampler = () => 1;
const tracesSampleRate = 1;
it.each([
Expand All@@ -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<typeof hasTracingEnabled>[0], output: ReturnType<typeof hasTracingEnabled>) => {
expect(hasTracingEnabled(input)).toBe(output);
},
);
])('%s', (_: string, input: Parameters<typeof hasSpansEnabled>[0], output: ReturnType<typeof hasSpansEnabled>) => {
expect(hasSpansEnabled(input)).toBe(output);
// eslint-disable-next-line deprecation/deprecation
expect(hasTracingEnabled(input)).toBe(output);
});
});
2 changes: 1 addition & 1 deletion packages/nextjs/test/config/wrappers.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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: () => ({}),
Expand Down
6 changes: 3 additions & 3 deletions packages/node/src/integrations/node-fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@ import {
getClient,
getSanitizedUrlString,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
parseUrl,
} from '@sentry/core';
import { shouldPropagateTraceForUrl } from '@sentry/opentelemetry';
Expand DownExpand Up@@ -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()
Expand Down
6 changes: 3 additions & 3 deletions packages/node/src/sdk/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ import {
functionToStringIntegration,
getCurrentScope,
getIntegrationsToSetup,
hasTracingEnabled,
hasSpansEnabled,
inboundFiltersIntegration,
linkedErrorsIntegration,
logger,
Expand DownExpand Up@@ -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() : []),
];
}

Expand DownExpand Up@@ -175,7 +175,7 @@ export function validateOpenTelemetrySetup(): void {

const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];

if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
required.push('SentrySpanProcessor');
}

Expand Down
8 changes: 4 additions & 4 deletions packages/node/src/utils/ensureIsWrapped.ts
Original file line numberDiff line numberDiff line change
@@ -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';
Expand All@@ -11,12 +11,12 @@ export function ensureIsWrapped(
maybeWrappedFunction: unknown,
name: 'express' | 'connect' | 'fastify' | 'hapi' | 'koa',
): void {
const client = getClient<NodeClient>();
const clientOptions = getClient<NodeClient>()?.getOptions();
if (
!client?.getOptions().disableInstrumentationWarnings &&
!clientOptions?.disableInstrumentationWarnings &&
!isWrapped(maybeWrappedFunction) &&
isEnabled() &&
hasTracingEnabled()
hasSpansEnabled(clientOptions)
) {
consoleSandbox(() => {
if (isCjs()) {
Expand Down
4 changes: 2 additions & 2 deletions packages/opentelemetry/src/sampler.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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,
Expand DownExpand Up@@ -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 });
}

Expand Down
Original file line numberDiff line numberDiff line change
@@ -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';
Expand DownExpand Up@@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/remix/src/utils/instrumentServer.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ import {
fill,
getClient,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
isNodeEnv,
loadModule,
logger,
Expand DownExpand Up@@ -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);
}

Expand Down
4 changes: 2 additions & 2 deletions packages/vercel-edge/src/sdk.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import {
functionToStringIntegration,
getCurrentScope,
getIntegrationsToSetup,
hasTracingEnabled,
hasSpansEnabled,
inboundFiltersIntegration,
linkedErrorsIntegration,
logger,
Expand DownExpand Up@@ -124,7 +124,7 @@ function validateOpenTelemetrySetup(): void {

const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];

if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
required.push('SentrySpanProcessor');
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/browser/src/tracing/request.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import {
getActiveSpan,
getLocationHref,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
instrumentFetchRequest,
parseUrl,
setHttpStatus,
Expand DownExpand Up@@ -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) {
Expand DownExpand Up@@ -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,
);
}

Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';

Expand DownExpand Up@@ -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;
Expand DownExpand Up@@ -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
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/tracing/dynamicSamplingContext.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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';

Expand DownExpand Up@@ -118,10 +118,10 @@ export function getDynamicSamplingContextFromSpan(span: Span): Readonly<Partial<
dsc.transaction = name;
}

// How can we even land here with hasTracingEnabled() returning false?
// How can we even land here with hasSpansEnabled() returning false?
// Otel creates a Non-recording span in Tracing Without Performance mode when handling incoming requests
// So we end up with an active span that is not sampled (neither positively nor negatively)
if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
dsc.sampled = String(spanIsSampled(rootSpan));
dsc.sample_rand =
// In OTEL we store the sample rand on the trace state because we cannot access scopes for NonRecordingSpans
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/tracing/idleSpan.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ import { DEBUG_BUILD } from '../debug-build';
import { SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON } from '../semanticAttributes';
import { logger } from '../utils-hoist/logger';
import { timestampInSeconds } from '../utils-hoist/time';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { _setSpanForScope } from '../utils/spanOnScope';
import {
getActiveSpan,
Expand DownExpand Up@@ -109,7 +109,7 @@ export function startIdleSpan(startSpanOptions: StartSpanOptions, options: Parti

const client = getClient();

if (!client || !hasTracingEnabled()) {
if (!client || !hasSpansEnabled()) {
const span = new SentryNonRecordingSpan();

const dsc = {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/tracing/sampling.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,7 @@ import type { Options, SamplingContext } from '../types-hoist';

import { DEBUG_BUILD } from '../debug-build';
import { logger } from '../utils-hoist/logger';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { parseSampleRate } from '../utils/parseSampleRate';

/**
Expand All@@ -16,8 +16,8 @@ export function sampleSpan(
samplingContext: SamplingContext,
sampleRand: number,
): [sampled: boolean, sampleRate?: number, localSampleRateWasApplied?: boolean] {
// nothing to do if tracing is not enabled
if (!hasTracingEnabled(options)) {
// nothing to do if span recording is not enabled
if (!hasSpansEnabled(options)) {
return [false];
}

Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/tracing/trace.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ import { logger } from '../utils-hoist/logger';
import { generateTraceId } from '../utils-hoist/propagationContext';
import { propagationContextFromHeaders } from '../utils-hoist/tracing';
import { handleCallbackErrors } from '../utils/handleCallbackErrors';
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
import { hasSpansEnabled } from '../utils/hasSpansEnabled';
import { parseSampleRate } from '../utils/parseSampleRate';
import { _getSpanForScope, _setSpanForScope } from '../utils/spanOnScope';
import { addChildSpanToSpan, getRootSpan, spanIsSampled, spanTimeInputToSeconds, spanToJSON } from '../utils/spanUtils';
Expand DownExpand Up@@ -302,7 +302,7 @@ function createChildOrRootSpan({
forceTransaction?: boolean;
scope: Scope;
}): Span {
if (!hasTracingEnabled()) {
if (!hasSpansEnabled()) {
const span = new SentryNonRecordingSpan();

// If this is a root span, we ensure to freeze a DSC
Expand Down
44 changes: 44 additions & 0 deletions packages/core/src/utils/hasSpansEnabled.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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 span recording is currently enabled.
*
* Spans are recorded when at least one of `tracesSampleRate` and `tracesSampler`
* is defined in the SDK config. This function does not make any assumption about
* sampling decisions, it only checks if the SDK is configured to record spans.
*
* Important: This function only determines if span recording is enabled. Trace
* continuation and propagation is separately controlled and not covered by this function.
* If this function returns `false`, traces can still be propagated (which is what
* we refer to by "Tracing without Performance")
* @see https://develop.sentry.dev/sdk/telemetry/traces/tracing-without-performance/
*
* @param maybeOptions An SDK options object to be passed to this function.
* If this option is not provided, the function will use the current client's options.
*/
export function hasSpansEnabled(
maybeOptions?: Pick<Options, 'tracesSampleRate' | 'tracesSampler'> | 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;
26 changes: 0 additions & 26 deletions packages/core/src/utils/hasTracingEnabled.ts

This file was deleted.

14 changes: 7 additions & 7 deletions packages/core/test/lib/utils/hasTracingEnabled.test.ts
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
import { hasSpansEnabled } from '../../../src';
import { hasTracingEnabled } from '../../../src';

describe('hasTracingEnabled', () => {
describe('hasSpansEnabled', () => {
const tracesSampler = () => 1;
const tracesSampleRate = 1;
it.each([
Expand All@@ -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<typeof hasTracingEnabled>[0], output: ReturnType<typeof hasTracingEnabled>) => {
expect(hasTracingEnabled(input)).toBe(output);
},
);
])('%s', (_: string, input: Parameters<typeof hasSpansEnabled>[0], output: ReturnType<typeof hasSpansEnabled>) => {
expect(hasSpansEnabled(input)).toBe(output);
// eslint-disable-next-line deprecation/deprecation
expect(hasTracingEnabled(input)).toBe(output);
});
});
2 changes: 1 addition & 1 deletion packages/nextjs/test/config/wrappers.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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: () => ({}),
Expand Down
6 changes: 3 additions & 3 deletions packages/node/src/integrations/node-fetch.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@ import {
getClient,
getSanitizedUrlString,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
parseUrl,
} from '@sentry/core';
import { shouldPropagateTraceForUrl } from '@sentry/opentelemetry';
Expand DownExpand Up@@ -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()
Expand Down
6 changes: 3 additions & 3 deletions packages/node/src/sdk/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ import {
functionToStringIntegration,
getCurrentScope,
getIntegrationsToSetup,
hasTracingEnabled,
hasSpansEnabled,
inboundFiltersIntegration,
linkedErrorsIntegration,
logger,
Expand DownExpand Up@@ -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() : []),
];
}

Expand DownExpand Up@@ -175,7 +175,7 @@ export function validateOpenTelemetrySetup(): void {

const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];

if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
required.push('SentrySpanProcessor');
}

Expand Down
8 changes: 4 additions & 4 deletions packages/node/src/utils/ensureIsWrapped.ts
Original file line numberDiff line numberDiff line change
@@ -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';
Expand All@@ -11,12 +11,12 @@ export function ensureIsWrapped(
maybeWrappedFunction: unknown,
name: 'express' | 'connect' | 'fastify' | 'hapi' | 'koa',
): void {
const client = getClient<NodeClient>();
const clientOptions = getClient<NodeClient>()?.getOptions();
if (
!client?.getOptions().disableInstrumentationWarnings &&
!clientOptions?.disableInstrumentationWarnings &&
!isWrapped(maybeWrappedFunction) &&
isEnabled() &&
hasTracingEnabled()
hasSpansEnabled(clientOptions)
) {
consoleSandbox(() => {
if (isCjs()) {
Expand Down
4 changes: 2 additions & 2 deletions packages/opentelemetry/src/sampler.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -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,
Expand DownExpand Up@@ -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 });
}

Expand Down
Original file line numberDiff line numberDiff line change
@@ -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';
Expand DownExpand Up@@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/remix/src/utils/instrumentServer.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ import {
fill,
getClient,
getTraceData,
hasTracingEnabled,
hasSpansEnabled,
isNodeEnv,
loadModule,
logger,
Expand DownExpand Up@@ -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);
}

Expand Down
4 changes: 2 additions & 2 deletions packages/vercel-edge/src/sdk.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import {
functionToStringIntegration,
getCurrentScope,
getIntegrationsToSetup,
hasTracingEnabled,
hasSpansEnabled,
inboundFiltersIntegration,
linkedErrorsIntegration,
logger,
Expand DownExpand Up@@ -124,7 +124,7 @@ function validateOpenTelemetrySetup(): void {

const required: ReturnType<typeof openTelemetrySetupCheck> = ['SentryContextManager', 'SentryPropagator'];

if (hasTracingEnabled()) {
if (hasSpansEnabled()) {
required.push('SentrySpanProcessor');
}

Expand Down
Loading