diff --git a/CHANGELOG.md b/CHANGELOG.md index eb13795aae..740b27365c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,22 @@ ## Unreleased +### Features + +- Add `tracePropagationTargets` option ([#3230](https://github.com/getsentry/sentry-react-native/pull/3230)) + + This release adds support for [distributed tracing](https://docs.sentry.io/platforms/react-native/usage/distributed-tracing/) + without requiring performance monitoring to be active on the React Native SDK. + This means even if there is no sampled transaction/span, the SDK will still propagate traces to downstream services. + Distributed Tracing can be configured with the `tracePropagationTargets` option, + which controls what requests to attach the `sentry-trace` and `baggage` HTTP headers to (which is what propagates tracing information). + + ```javascript + Sentry.init({ + tracePropagationTargets: ["third-party-site.com", /^https:\/\/yourserver\.io\/api/], + }); + ``` + ### Fixes - `Sentry.init` must be called before `Sentry.wrap`([#3227](https://github.com/getsentry/sentry-react-native/pull/3227)) diff --git a/sample-new-architecture/src/App.tsx b/sample-new-architecture/src/App.tsx index d3b535d1c8..ab74583719 100644 --- a/sample-new-architecture/src/App.tsx +++ b/sample-new-architecture/src/App.tsx @@ -45,7 +45,6 @@ Sentry.init({ // The time to wait in ms until the transaction will be finished, For testing, default is 1000 ms idleTimeout: 5000, routingInstrumentation: reactNavigationInstrumentation, - tracingOrigins: ['localhost', /^\//, /^https:\/\//], enableUserInteractionTracing: true, beforeNavigate: (context: Sentry.ReactNavigationTransactionContext) => { // Example of not sending a transaction for the screen with the name "Manual Tracker" @@ -75,6 +74,7 @@ Sentry.init({ // This will capture ALL TRACES and likely use up all your quota enableTracing: true, tracesSampleRate: 1.0, + tracePropagationTargets: ['localhost', /^\//, /^https:\/\//, /^http:\/\//], attachStacktrace: true, // Attach screenshots to events. attachScreenshot: true, diff --git a/src/js/tracing/reactnativetracing.ts b/src/js/tracing/reactnativetracing.ts index 276a605371..5155f61bee 100644 --- a/src/js/tracing/reactnativetracing.ts +++ b/src/js/tracing/reactnativetracing.ts @@ -165,6 +165,10 @@ export class ReactNativeTracing implements Integration { addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub, ): void { + const hub = getCurrentHub(); + const client = hub.getClient(); + const clientOptions = client && client.getOptions(); + // eslint-disable-next-line @typescript-eslint/unbound-method const { traceFetch, @@ -173,7 +177,7 @@ export class ReactNativeTracing implements Integration { tracingOrigins, // @ts-ignore TODO shouldCreateSpanForRequest, - tracePropagationTargets, + tracePropagationTargets: thisOptionsTracePropagationTargets, routingInstrumentation, enableAppStartTracking, enableNativeFramesTracking, @@ -182,6 +186,23 @@ export class ReactNativeTracing implements Integration { this._getCurrentHub = getCurrentHub; + const clientOptionsTracePropagationTargets = clientOptions && clientOptions.tracePropagationTargets; + // There are three ways to configure tracePropagationTargets: + // 1. via top level client option `tracePropagationTargets` + // 2. via ReactNativeTracing option `tracePropagationTargets` + // 3. via ReactNativeTracing option `tracingOrigins` (deprecated) + // + // To avoid confusion, favour top level client option `tracePropagationTargets`, and fallback to + // ReactNativeTracing option `tracePropagationTargets` and then `tracingOrigins` (deprecated). + // + // If both 1 and either one of 2 or 3 are set (from above), we log out a warning. + const tracePropagationTargets = clientOptionsTracePropagationTargets || thisOptionsTracePropagationTargets; + if (__DEV__ && (thisOptionsTracePropagationTargets || tracingOrigins) && clientOptionsTracePropagationTargets) { + logger.warn( + '[ReactNativeTracing] The `tracePropagationTargets` option was set in the ReactNativeTracing integration and top level `Sentry.init`. The top level `Sentry.init` value is being used.', + ); + } + if (enableAppStartTracking) { void this._instrumentAppStart(); }