diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b780353a619a..f48cd5b3597a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -48,7 +48,7 @@ env: ${{ github.workspace }}/packages/utils/cjs ${{ github.workspace }}/packages/utils/esm - BUILD_CACHE_KEY: ${{ github.event.inputs.commit || github.sha }} + BUILD_CACHE_KEY: build-cache-${{ github.event.inputs.commit || github.sha }} BUILD_PROFILING_NODE_CACHE_TARBALL_KEY: profiling-node-tarball-${{ github.event.inputs.commit || github.sha }} # GH will use the first restore-key it finds that matches diff --git a/nx.json b/nx.json index e65250382e1c..d7c26c14ffa0 100644 --- a/nx.json +++ b/nx.json @@ -32,7 +32,7 @@ "build:types": { "inputs": ["production", "^production"], "dependsOn": ["^build:types"], - "outputs": ["{projectRoot}/build/**/*.d.ts", "{projectRoot}/build/**/*.d.ts.map"] + "outputs": ["{projectRoot}/build/{types,types-ts3.8}", "{projectRoot}/build/npm/{types,types-ts3.8}"] }, "lint": { "inputs": ["default"], diff --git a/packages/core/src/metrics/metric-summary.ts b/packages/core/src/metrics/metric-summary.ts index bf2e828dae1b..2be991297296 100644 --- a/packages/core/src/metrics/metric-summary.ts +++ b/packages/core/src/metrics/metric-summary.ts @@ -2,7 +2,7 @@ import type { MeasurementUnit, Span } from '@sentry/types'; import type { MetricSummary } from '@sentry/types'; import type { Primitive } from '@sentry/types'; import { dropUndefinedKeys } from '@sentry/utils'; -import { getActiveSpan } from '../tracing'; +import { getActiveSpan } from '../tracing/utils'; import type { MetricType } from './types'; /** diff --git a/packages/core/src/scope.ts b/packages/core/src/scope.ts index cb00f0bd1bbf..4646e5e5b015 100644 --- a/packages/core/src/scope.ts +++ b/packages/core/src/scope.ts @@ -25,9 +25,7 @@ import type { } from '@sentry/types'; import { dateTimestampInSeconds, isPlainObject, logger, uuid4 } from '@sentry/utils'; -import { getGlobalEventProcessors, notifyEventProcessors } from './eventProcessors'; import { updateSession } from './session'; -import { applyScopeDataToEvent } from './utils/applyScopeDataToEvent'; /** * Default value for maximum number of breadcrumbs added to an event. @@ -35,8 +33,7 @@ import { applyScopeDataToEvent } from './utils/applyScopeDataToEvent'; const DEFAULT_MAX_BREADCRUMBS = 100; /** - * Holds additional event information. {@link Scope.applyToEvent} will be - * called by the client before an event will be sent. + * Holds additional event information. */ export class Scope implements ScopeInterface { /** Flag if notifying is happening. */ @@ -45,7 +42,7 @@ export class Scope implements ScopeInterface { /** Callback for client to receive scope changes. */ protected _scopeListeners: Array<(scope: Scope) => void>; - /** Callback list that will be called after {@link applyToEvent}. */ + /** Callback list that will be called during event processing. */ protected _eventProcessors: EventProcessor[]; /** Array of breadcrumbs. */ @@ -538,32 +535,6 @@ export class Scope implements ScopeInterface { }; } - /** - * Applies data from the scope to the event and runs all event processors on it. - * - * @param event Event - * @param hint Object containing additional information about the original exception, for use by the event processors. - * @hidden - * @deprecated Use `applyScopeDataToEvent()` directly - */ - public applyToEvent( - event: Event, - hint: EventHint = {}, - additionalEventProcessors: EventProcessor[] = [], - ): PromiseLike { - applyScopeDataToEvent(event, this.getScopeData()); - - // TODO (v8): Update this order to be: Global > Client > Scope - const eventProcessors: EventProcessor[] = [ - ...additionalEventProcessors, - // eslint-disable-next-line deprecation/deprecation - ...getGlobalEventProcessors(), - ...this._eventProcessors, - ]; - - return notifyEventProcessors(eventProcessors, event, hint); - } - /** * Add data which will be accessible during event processing but won't get sent to Sentry */ diff --git a/packages/core/src/tracing/index.ts b/packages/core/src/tracing/index.ts index 1efa436f7548..f8284fe16e29 100644 --- a/packages/core/src/tracing/index.ts +++ b/packages/core/src/tracing/index.ts @@ -4,7 +4,7 @@ export type { BeforeFinishCallback } from './idletransaction'; export { SentrySpan } from './sentrySpan'; export { Transaction } from './transaction'; // eslint-disable-next-line deprecation/deprecation -export { getActiveTransaction } from './utils'; +export { getActiveTransaction, getActiveSpan } from './utils'; // eslint-disable-next-line deprecation/deprecation export { SpanStatus } from './spanstatus'; export { @@ -13,7 +13,6 @@ export { } from './spanstatus'; export type { SpanStatusType } from './spanstatus'; export { - getActiveSpan, startSpan, startInactiveSpan, startSpanManual, diff --git a/packages/core/src/tracing/sentrySpan.ts b/packages/core/src/tracing/sentrySpan.ts index 11ac96f2f266..b484e9c964ca 100644 --- a/packages/core/src/tracing/sentrySpan.ts +++ b/packages/core/src/tracing/sentrySpan.ts @@ -25,7 +25,7 @@ import { spanToTraceContext, } from '../utils/spanUtils'; import type { SpanStatusType } from './spanstatus'; -import { addChildSpanToSpan } from './trace'; +import { addChildSpanToSpan } from './utils'; /** * Keeps track of finished spans for a given transaction diff --git a/packages/core/src/tracing/trace.ts b/packages/core/src/tracing/trace.ts index c227dda5057a..a2030986616d 100644 --- a/packages/core/src/tracing/trace.ts +++ b/packages/core/src/tracing/trace.ts @@ -1,7 +1,7 @@ import type { Hub, Scope, Span, SpanTimeInput, StartSpanOptions, TransactionContext } from '@sentry/types'; -import { addNonEnumerableProperty, dropUndefinedKeys, logger, tracingContextFromHeaders } from '@sentry/utils'; -import { getDynamicSamplingContextFromSpan } from '.'; +import { dropUndefinedKeys, logger, tracingContextFromHeaders } from '@sentry/utils'; + import { getCurrentScope, getIsolationScope, withScope } from '../currentScopes'; import { DEBUG_BUILD } from '../debug-build'; @@ -9,6 +9,8 @@ import { getCurrentHub } from '../hub'; import { handleCallbackErrors } from '../utils/handleCallbackErrors'; import { hasTracingEnabled } from '../utils/hasTracingEnabled'; import { spanIsSampled, spanTimeInputToSeconds, spanToJSON } from '../utils/spanUtils'; +import { getDynamicSamplingContextFromSpan } from './dynamicSamplingContext'; +import { addChildSpanToSpan, getActiveSpan, setCapturedScopesOnSpan } from './utils'; /** * Wraps a function with a transaction/span and finishes the span after the function is done. @@ -152,14 +154,6 @@ export function startInactiveSpan(context: StartSpanOptions): Span | undefined { }); } -/** - * Returns the currently active span. - */ -export function getActiveSpan(): Span | undefined { - // eslint-disable-next-line deprecation/deprecation - return getCurrentScope().getSpan(); -} - interface ContinueTrace { /** * Continue a trace from `sentry-trace` and `baggage` values. @@ -353,70 +347,3 @@ function normalizeContext(context: StartSpanOptions): TransactionContext { return context; } - -const CHILD_SPANS_FIELD = '_sentryChildSpans'; - -type SpanWithPotentialChildren = Span & { - [CHILD_SPANS_FIELD]?: Set; -}; - -/** - * Adds an opaque child span reference to a span. - */ -export function addChildSpanToSpan(span: SpanWithPotentialChildren, childSpan: Span): void { - if (span[CHILD_SPANS_FIELD] && span[CHILD_SPANS_FIELD].size < 1000) { - span[CHILD_SPANS_FIELD].add(childSpan); - } else { - span[CHILD_SPANS_FIELD] = new Set([childSpan]); - } -} - -/** - * Obtains the entire span tree, meaning a span + all of its descendants for a particular span. - */ -export function getSpanTree(span: SpanWithPotentialChildren): Span[] { - const resultSet = new Set(); - - function addSpanChildren(span: SpanWithPotentialChildren): void { - // This exit condition is required to not infinitely loop in case of a circular dependency. - if (resultSet.has(span)) { - return; - } else { - resultSet.add(span); - const childSpans = span[CHILD_SPANS_FIELD] ? Array.from(span[CHILD_SPANS_FIELD]) : []; - for (const childSpan of childSpans) { - addSpanChildren(childSpan); - } - } - } - - addSpanChildren(span); - - return Array.from(resultSet); -} - -const SCOPE_ON_START_SPAN_FIELD = '_sentryScope'; -const ISOLATION_SCOPE_ON_START_SPAN_FIELD = '_sentryIsolationScope'; - -type SpanWithScopes = Span & { - [SCOPE_ON_START_SPAN_FIELD]?: Scope; - [ISOLATION_SCOPE_ON_START_SPAN_FIELD]?: Scope; -}; - -/** Store the scope & isolation scope for a span, which can the be used when it is finished. */ -function setCapturedScopesOnSpan(span: Span | undefined, scope: Scope, isolationScope: Scope): void { - if (span) { - addNonEnumerableProperty(span, ISOLATION_SCOPE_ON_START_SPAN_FIELD, isolationScope); - addNonEnumerableProperty(span, SCOPE_ON_START_SPAN_FIELD, scope); - } -} - -/** - * Grabs the scope and isolation scope off a span that were active when the span was started. - */ -export function getCapturedScopesOnSpan(span: Span): { scope?: Scope; isolationScope?: Scope } { - return { - scope: (span as SpanWithScopes)[SCOPE_ON_START_SPAN_FIELD], - isolationScope: (span as SpanWithScopes)[ISOLATION_SCOPE_ON_START_SPAN_FIELD], - }; -} diff --git a/packages/core/src/tracing/transaction.ts b/packages/core/src/tracing/transaction.ts index c1c567b68710..3c0c114f1061 100644 --- a/packages/core/src/tracing/transaction.ts +++ b/packages/core/src/tracing/transaction.ts @@ -21,7 +21,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE import { spanTimeInputToSeconds, spanToJSON, spanToTraceContext } from '../utils/spanUtils'; import { getDynamicSamplingContextFromSpan } from './dynamicSamplingContext'; import { SentrySpan, SpanRecorder } from './sentrySpan'; -import { getCapturedScopesOnSpan, getSpanTree } from './trace'; +import { getCapturedScopesOnSpan, getSpanTree } from './utils'; /** JSDoc */ export class Transaction extends SentrySpan implements TransactionInterface { diff --git a/packages/core/src/tracing/utils.ts b/packages/core/src/tracing/utils.ts index 78072fb48e48..e01f92a028ba 100644 --- a/packages/core/src/tracing/utils.ts +++ b/packages/core/src/tracing/utils.ts @@ -1,4 +1,7 @@ -import type { Transaction } from '@sentry/types'; +import type { Span, Transaction } from '@sentry/types'; +import type { Scope } from '@sentry/types'; +import { addNonEnumerableProperty } from '@sentry/utils'; +import { getCurrentScope } from '../currentScopes'; import type { Hub } from '../hub'; import { getCurrentHub } from '../hub'; @@ -19,3 +22,78 @@ export function getActiveTransaction(maybeHub?: Hub): T | // so it can be used in manual instrumentation without necessitating a hard dependency on @sentry/utils export { stripUrlQueryAndFragment } from '@sentry/utils'; + +/** + * Returns the currently active span. + */ +export function getActiveSpan(): Span | undefined { + // eslint-disable-next-line deprecation/deprecation + return getCurrentScope().getSpan(); +} + +const CHILD_SPANS_FIELD = '_sentryChildSpans'; + +type SpanWithPotentialChildren = Span & { + [CHILD_SPANS_FIELD]?: Set; +}; + +/** + * Adds an opaque child span reference to a span. + */ +export function addChildSpanToSpan(span: SpanWithPotentialChildren, childSpan: Span): void { + if (span[CHILD_SPANS_FIELD] && span[CHILD_SPANS_FIELD].size < 1000) { + span[CHILD_SPANS_FIELD].add(childSpan); + } else { + span[CHILD_SPANS_FIELD] = new Set([childSpan]); + } +} + +/** + * Obtains the entire span tree, meaning a span + all of its descendants for a particular span. + */ +export function getSpanTree(span: SpanWithPotentialChildren): Span[] { + const resultSet = new Set(); + + function addSpanChildren(span: SpanWithPotentialChildren): void { + // This exit condition is required to not infinitely loop in case of a circular dependency. + if (resultSet.has(span)) { + return; + } else { + resultSet.add(span); + const childSpans = span[CHILD_SPANS_FIELD] ? Array.from(span[CHILD_SPANS_FIELD]) : []; + for (const childSpan of childSpans) { + addSpanChildren(childSpan); + } + } + } + + addSpanChildren(span); + + return Array.from(resultSet); +} + +const SCOPE_ON_START_SPAN_FIELD = '_sentryScope'; +const ISOLATION_SCOPE_ON_START_SPAN_FIELD = '_sentryIsolationScope'; + +type SpanWithScopes = Span & { + [SCOPE_ON_START_SPAN_FIELD]?: Scope; + [ISOLATION_SCOPE_ON_START_SPAN_FIELD]?: Scope; +}; + +/** Store the scope & isolation scope for a span, which can the be used when it is finished. */ +export function setCapturedScopesOnSpan(span: Span | undefined, scope: Scope, isolationScope: Scope): void { + if (span) { + addNonEnumerableProperty(span, ISOLATION_SCOPE_ON_START_SPAN_FIELD, isolationScope); + addNonEnumerableProperty(span, SCOPE_ON_START_SPAN_FIELD, scope); + } +} + +/** + * Grabs the scope and isolation scope off a span that were active when the span was started. + */ +export function getCapturedScopesOnSpan(span: Span): { scope?: Scope; isolationScope?: Scope } { + return { + scope: (span as SpanWithScopes)[SCOPE_ON_START_SPAN_FIELD], + isolationScope: (span as SpanWithScopes)[ISOLATION_SCOPE_ON_START_SPAN_FIELD], + }; +} diff --git a/packages/types/src/scope.ts b/packages/types/src/scope.ts index 7a91741997b4..39e93f8ac1df 100644 --- a/packages/types/src/scope.ts +++ b/packages/types/src/scope.ts @@ -46,7 +46,7 @@ export interface ScopeData { } /** - * Holds additional event information. {@link Scope.applyToEvent} will be called by the client before an event is sent. + * Holds additional event information. */ export interface Scope { /** @@ -61,7 +61,7 @@ export interface Scope { */ getClient(): C | undefined; - /** Add new event processor that will be called after {@link applyToEvent}. */ + /** Add new event processor that will be called during event processing. */ addEventProcessor(callback: EventProcessor): this; /** Get the data of this scope, which is applied to an event during processing. */