From 4e33c466cad8fae524ca869a9cd722cc61f3e56c Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 4 Aug 2022 07:41:11 +0000 Subject: [PATCH 1/6] feat(node): Add tracePropagationTargets option --- .../tracePropagationTargets/scenario.ts | 26 +++++ .../tracing/tracePropagationTargets/test.ts | 37 ++++++ .../node-integration-tests/utils/index.ts | 21 +++- packages/node/src/integrations/http.ts | 81 +++++++++---- packages/node/src/types.ts | 13 +++ packages/node/test/integrations/http.test.ts | 107 ++++++++++++++++++ 6 files changed, 262 insertions(+), 23 deletions(-) create mode 100644 packages/node-integration-tests/suites/tracing/tracePropagationTargets/scenario.ts create mode 100644 packages/node-integration-tests/suites/tracing/tracePropagationTargets/test.ts diff --git a/packages/node-integration-tests/suites/tracing/tracePropagationTargets/scenario.ts b/packages/node-integration-tests/suites/tracing/tracePropagationTargets/scenario.ts new file mode 100644 index 000000000000..a4d5e84484a5 --- /dev/null +++ b/packages/node-integration-tests/suites/tracing/tracePropagationTargets/scenario.ts @@ -0,0 +1,26 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import '@sentry/tracing'; + +import * as Sentry from '@sentry/node'; +import * as http from 'http'; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + release: '1.0', + tracesSampleRate: 1.0, + tracePropagationTargets: [/\/v0/, 'v1'], + integrations: [new Sentry.Integrations.Http({ tracing: true })], +}); + +const transaction = Sentry.startTransaction({ name: 'test_transaction' }); + +Sentry.configureScope(scope => { + scope.setSpan(transaction); +}); + +http.get('http://match-this-url.com/api/v0'); +http.get('http://match-this-url.com/api/v1'); +http.get('http://dont-match-this-url.com/api/v2'); +http.get('http://dont-match-this-url.com/api/v3'); + +transaction.finish(); diff --git a/packages/node-integration-tests/suites/tracing/tracePropagationTargets/test.ts b/packages/node-integration-tests/suites/tracing/tracePropagationTargets/test.ts new file mode 100644 index 000000000000..1ab85bf859c7 --- /dev/null +++ b/packages/node-integration-tests/suites/tracing/tracePropagationTargets/test.ts @@ -0,0 +1,37 @@ +import nock from 'nock'; + +import { runScenario, runServer } from '../../../utils'; + +test('HttpIntegration should instrument correct requests when tracePropagationTargets option is provided', async () => { + const match1 = nock('http://match-this-url.com') + .get('/api/v0') + .matchHeader('baggage', val => typeof val === 'string') + .matchHeader('sentry-trace', val => typeof val === 'string') + .reply(200); + + const match2 = nock('http://match-this-url.com') + .get('/api/v1') + .matchHeader('baggage', val => typeof val === 'string') + .matchHeader('sentry-trace', val => typeof val === 'string') + .reply(200); + + const match3 = nock('http://dont-match-this-url.com') + .get('/api/v2') + .matchHeader('baggage', val => val === undefined) + .matchHeader('sentry-trace', val => val === undefined) + .reply(200); + + const match4 = nock('http://dont-match-this-url.com') + .get('/api/v3') + .matchHeader('baggage', val => val === undefined) + .matchHeader('sentry-trace', val => val === undefined) + .reply(200); + + const serverUrl = await runServer(__dirname); + await runScenario(serverUrl); + + expect(match1.isDone()).toBe(true); + expect(match2.isDone()).toBe(true); + expect(match3.isDone()).toBe(true); + expect(match4.isDone()).toBe(true); +}); diff --git a/packages/node-integration-tests/utils/index.ts b/packages/node-integration-tests/utils/index.ts index 872c9d72521d..3ceb89cc3cb8 100644 --- a/packages/node-integration-tests/utils/index.ts +++ b/packages/node-integration-tests/utils/index.ts @@ -152,12 +152,16 @@ export async function runServer(testDir: string, serverPath?: string, scenarioPa const url = `http://localhost:${port}/test`; const defaultServerPath = path.resolve(process.cwd(), 'utils', 'defaults', 'server'); - await new Promise(resolve => { + await new Promise(resolve => { // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access const app = require(serverPath || defaultServerPath).default as Express; - app.get('/test', async () => { - require(scenarioPath || `${testDir}/scenario`); + app.get('/test', (_req, res) => { + try { + require(scenarioPath || `${testDir}/scenario`); + } finally { + res.status(200).end(); + } }); const server = app.listen(port, () => { @@ -170,3 +174,14 @@ export async function runServer(testDir: string, serverPath?: string, scenarioPa return url; } + +export async function runScenario(serverUrl: string): Promise { + return new Promise(resolve => { + http + .get(serverUrl, res => { + res.on('data', () => undefined); + res.on('end', resolve); + }) + .end(); + }); +} diff --git a/packages/node/src/integrations/http.ts b/packages/node/src/integrations/http.ts index aa52f0fae323..2a9c4bc7cb54 100644 --- a/packages/node/src/integrations/http.ts +++ b/packages/node/src/integrations/http.ts @@ -1,9 +1,10 @@ -import { getCurrentHub } from '@sentry/core'; -import { Integration, Span } from '@sentry/types'; -import { fill, logger, mergeAndSerializeBaggage, parseSemver } from '@sentry/utils'; +import { getCurrentHub, Hub } from '@sentry/core'; +import { EventProcessor, Integration, Span } from '@sentry/types'; +import { fill, isMatchingPattern, logger, mergeAndSerializeBaggage, parseSemver } from '@sentry/utils'; import * as http from 'http'; import * as https from 'https'; +import { NodeClientOptions } from '../types'; import { cleanSpanDescription, extractUrl, @@ -15,7 +16,10 @@ import { const NODE_VERSION = parseSemver(process.versions.node); -/** http module integration */ +/** + * The http module integration instruments nodes internal http module. It creates breadcrumbs, transactions for outgoing + * http requests and attaches trace data when tracing is enabled via its `tracing` option. + */ export class Http implements Integration { /** * @inheritDoc @@ -48,13 +52,22 @@ export class Http implements Integration { /** * @inheritDoc */ - public setupOnce(): void { + public setupOnce( + _addGlobalEventProcessor: (callback: EventProcessor) => void, + setupOnceGetCurrentHub: () => Hub, + ): void { // No need to instrument if we don't want to track anything if (!this._breadcrumbs && !this._tracing) { return; } - const wrappedHandlerMaker = _createWrappedRequestMethodFactory(this._breadcrumbs, this._tracing); + const clientOptions = setupOnceGetCurrentHub().getClient()?.getOptions() as NodeClientOptions | undefined; + + const wrappedHandlerMaker = _createWrappedRequestMethodFactory( + this._breadcrumbs, + this._tracing, + clientOptions?.tracePropagationTargets, + ); // eslint-disable-next-line @typescript-eslint/no-var-requires const httpModule = require('http'); @@ -90,7 +103,26 @@ type WrappedRequestMethodFactory = (original: OriginalRequestMethod) => WrappedR function _createWrappedRequestMethodFactory( breadcrumbsEnabled: boolean, tracingEnabled: boolean, + tracePropagationTargets: (string | RegExp)[] | undefined, ): WrappedRequestMethodFactory { + // We're caching results so we dont have to recompute regexp everytime we create a request. + const urlMap: Record = {}; + const shouldAttachTraceData = (url: string): boolean => { + if (tracePropagationTargets === undefined) { + return true; + } + + if (urlMap[url]) { + return urlMap[url]; + } + + urlMap[url] = tracePropagationTargets.some(tracePropagationTarget => + isMatchingPattern(url, tracePropagationTarget), + ); + + return urlMap[url]; + }; + return function wrappedRequestMethodFactory(originalRequestMethod: OriginalRequestMethod): WrappedRequestMethod { return function wrappedMethod(this: typeof http | typeof https, ...args: RequestMethodArgs): http.ClientRequest { // eslint-disable-next-line @typescript-eslint/no-this-alias @@ -109,28 +141,37 @@ function _createWrappedRequestMethodFactory( let parentSpan: Span | undefined; const scope = getCurrentHub().getScope(); + if (scope && tracingEnabled) { parentSpan = scope.getSpan(); + if (parentSpan) { span = parentSpan.startChild({ description: `${requestOptions.method || 'GET'} ${requestUrl}`, op: 'http.client', }); - const sentryTraceHeader = span.toTraceparent(); - __DEBUG_BUILD__ && - logger.log( - `[Tracing] Adding sentry-trace header ${sentryTraceHeader} to outgoing request to ${requestUrl}: `, - ); - - const baggage = parentSpan.transaction && parentSpan.transaction.getBaggage(); - const headerBaggageString = requestOptions.headers && requestOptions.headers.baggage; - - requestOptions.headers = { - ...requestOptions.headers, - 'sentry-trace': sentryTraceHeader, - baggage: mergeAndSerializeBaggage(baggage, headerBaggageString), - }; + if (shouldAttachTraceData(requestUrl)) { + const sentryTraceHeader = span.toTraceparent(); + __DEBUG_BUILD__ && + logger.log( + `[Tracing] Adding sentry-trace header ${sentryTraceHeader} to outgoing request to "${requestUrl}": `, + ); + + const baggage = parentSpan.transaction && parentSpan.transaction.getBaggage(); + const headerBaggageString = requestOptions.headers && requestOptions.headers.baggage; + + requestOptions.headers = { + ...requestOptions.headers, + 'sentry-trace': sentryTraceHeader, + baggage: mergeAndSerializeBaggage(baggage, headerBaggageString), + }; + } else { + __DEBUG_BUILD__ && + logger.log( + `[Tracing] Not adding sentry-trace header to outgoing request (${requestUrl}) due to mismatching tracePropagationTargets option.`, + ); + } } } diff --git a/packages/node/src/types.ts b/packages/node/src/types.ts index 57b19dcd1820..34d7c2f2731f 100644 --- a/packages/node/src/types.ts +++ b/packages/node/src/types.ts @@ -6,6 +6,19 @@ export interface BaseNodeOptions { /** Sets an optional server name (device name) */ serverName?: string; + // We have this option seperately in both the node options and the browser options, so that we can have different JSDoc + // comments, since this has different behaviour in the Browser and Node SDKs. + /** + * List of strings/regex controlling to which outgoing requests + * the SDK will attach tracing headers. + * + * By default the SDK will attach those headers to all outgoing + * requests. If this option is provided, the SDK will match the + * request URL of outgoing requests against the items in this + * array, and only attach tracing headers if a match was found. + */ + tracePropagationTargets?: (string | RegExp)[]; + /** Callback that is executed when a fatal global error occurs. */ onFatalError?(error: Error): void; } diff --git a/packages/node/test/integrations/http.test.ts b/packages/node/test/integrations/http.test.ts index 0c72efdced6c..72164153bedf 100644 --- a/packages/node/test/integrations/http.test.ts +++ b/packages/node/test/integrations/http.test.ts @@ -17,6 +17,9 @@ import { getDefaultNodeClientOptions } from '../helper/node-client-options'; const NODE_VERSION = parseSemver(process.versions.node); +const originalHttpGet = http.get; +const originalHttpRequest = http.request; + describe('tracing', () => { function createTransactionOnScope( customOptions: Partial = {}, @@ -168,6 +171,110 @@ describe('tracing', () => { expect(baggage).not.toBeDefined(); }); + + describe('tracePropagationTargets option', () => { + beforeEach(() => { + // hacky way of restoring monkey patched functions + // @ts-ignore TS doesn't let us assign to this but we want to + http.get = originalHttpGet; + // @ts-ignore TS doesn't let us assign to this but we want to + http.request = originalHttpRequest; + }); + + function createHub(customOptions: Partial = {}) { + const options = getDefaultNodeClientOptions({ + dsn: 'https://dogsarebadatkeepingsecrets@squirrelchasers.ingest.sentry.io/12312012', + tracesSampleRate: 1.0, + release: '1.0.0', + environment: 'production', + ...customOptions, + }); + + const hub = new Hub(); + + // we need to mock both of these because the tracing handler relies on `@sentry/core` while the sampler relies on + // `@sentry/hub`, and mocking breaks the link between the two + jest.spyOn(sentryCore, 'getCurrentHub').mockImplementation(() => hub); + jest.spyOn(hubModule, 'getCurrentHub').mockImplementation(() => hub); + + const client = new NodeClient(options); + jest.spyOn(hub, 'getClient').mockImplementation(() => client); + hub.bindClient(client); + + return hub; + } + + function createTransactionAndPutOnScope(hub: Hub) { + addExtensionMethods(); + const transaction = hub.startTransaction({ name: 'dogpark' }); + hub.getScope()?.setSpan(transaction); + } + + it.each([ + ['http://dogs.are.great/api/v1/index/', [/.*/]], + ['http://dogs.are.great/api/v1/index/', [/\/api/]], + ['http://dogs.are.great/api/v1/index/', [/\/(v1|v2)/]], + ['http://dogs.are.great/api/v1/index/', [/dogs\.are\.great/, /dogs\.are\.not\.great/]], + ['http://dogs.are.great/api/v1/index/', [/http:/]], + ['http://dogs.are.great/api/v1/index/', ['dogs.are.great']], + ['http://dogs.are.great/api/v1/index/', ['/api/v1']], + ['http://dogs.are.great/api/v1/index/', ['http://']], + ['http://dogs.are.great/api/v1/index/', ['']], + ])( + 'attaches trace inforation to header of outgoing requests when url matches tracePropagationTargets (url="%s", tracePropagationTargets=%p)', + (url, tracePropagationTargets) => { + nock(url).get(/.*/).reply(200); + + const httpIntegration = new HttpIntegration({ tracing: true }); + + const hub = createHub({ tracePropagationTargets }); + + httpIntegration.setupOnce( + () => undefined, + () => hub, + ); + + createTransactionAndPutOnScope(hub); + + const request = http.get(url); + + expect(request.getHeader('sentry-trace')).toBeDefined(); + expect(request.getHeader('baggage')).toBeDefined(); + }, + ); + + it.each([ + ['http://dogs.are.great/api/v1/index/', []], + ['http://cats.are.great/api/v1/index/', [/\/v2/]], + ['http://cats.are.great/api/v1/index/', [/\/(v2|v3)/]], + ['http://cats.are.great/api/v1/index/', [/dogs\.are\.great/, /dogs\.are\.not\.great/]], + ['http://cats.are.great/api/v1/index/', [/https:/]], + ['http://cats.are.great/api/v1/index/', ['dogs.are.great']], + ['http://cats.are.great/api/v1/index/', ['/api/v2']], + ['http://cats.are.great/api/v1/index/', ['https://']], + ])( + 'doesn\'t attach trace inforation to header of outgoing requests when url doesn\'t match tracePropagationTargets (url="%s", tracePropagationTargets=%p)', + (url, tracePropagationTargets) => { + nock(url).get(/.*/).reply(200); + + const httpIntegration = new HttpIntegration({ tracing: true }); + + const hub = createHub({ tracePropagationTargets }); + + httpIntegration.setupOnce( + () => undefined, + () => hub, + ); + + createTransactionAndPutOnScope(hub); + + const request = http.get(url); + + expect(request.getHeader('sentry-trace')).not.toBeDefined(); + expect(request.getHeader('baggage')).not.toBeDefined(); + }, + ); + }); }); describe('default protocols', () => { From b29938d623446a30b9ad200c82d055e67910be52 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 4 Aug 2022 09:38:46 +0000 Subject: [PATCH 2/6] Attempt to fix nextjs integration tests --- .../test/integration/test/utils/server.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/nextjs/test/integration/test/utils/server.js b/packages/nextjs/test/integration/test/utils/server.js index 8c38446e3f41..d29a4961d2e8 100644 --- a/packages/nextjs/test/integration/test/utils/server.js +++ b/packages/nextjs/test/integration/test/utils/server.js @@ -1,3 +1,4 @@ +// @ts-check const { get } = require('http'); const nock = require('nock'); const nodeSDK = require('@sentry/node'); @@ -132,14 +133,16 @@ function ensureWrappedGet(importedGet, url) { // As of Next 12.1, creating a `NextServer` instance (which we do immediately upon starting this test runner) loads // `_app`, which has the effect of initializing the SDK. So, unless something's gone wrong, we should always be able // to find the integration - let httpIntegration; - try { - httpIntegration = nodeSDK.getCurrentHub().getClient().getIntegration(nodeSDK.Integrations.Http); - } catch (err) { + const hub = nodeSDK.getCurrentHub(); + const client = hub.getClient(); + + if (!client) { console.warn(`Warning: Sentry SDK not set up at \`NextServer\` initialization. Request URL: ${url}`); return importedGet; } + const httpIntegration = client.getIntegration(nodeSDK.Integrations.Http); + // This rewraps `http.get` and `http.request`, which, at this point, look like `nockWrapper(sentryWrapper(get))` and // `nockWrapper(sentryWrapper(request))`. By the time we're done with this function, they'll look like // `sentryWrapper(nockWrapper(sentryWrapper(get)))` and `sentryWrapper(nockWrapper(sentryWrapper(request)))`, @@ -160,7 +163,12 @@ function ensureWrappedGet(importedGet, url) { // // TODO: add in a "don't do this twice" check (in `fill`, maybe moved from `wrap`), so that we don't wrap the outer // wrapper with a third wrapper - httpIntegration.setupOnce(); + if (httpIntegration) { + httpIntegration.setupOnce( + () => undefined, + () => hub, + ); + } // now that we've rewrapped it, grab the correct version of `get` for use in our tests const httpModule = require('http'); From 1bc4912b27983a959d43a6c082c6e3d433df7704 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 4 Aug 2022 13:06:42 +0200 Subject: [PATCH 3/6] Apply typo suggestion Co-authored-by: Lukas Stracke --- packages/node/src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node/src/types.ts b/packages/node/src/types.ts index 34d7c2f2731f..eda7761a6ffe 100644 --- a/packages/node/src/types.ts +++ b/packages/node/src/types.ts @@ -6,7 +6,7 @@ export interface BaseNodeOptions { /** Sets an optional server name (device name) */ serverName?: string; - // We have this option seperately in both the node options and the browser options, so that we can have different JSDoc + // We have this option separately in both, the node options and the browser options, so that we can have different JSDoc // comments, since this has different behaviour in the Browser and Node SDKs. /** * List of strings/regex controlling to which outgoing requests From 2756cfeaff56391a62a43c6fd75d61e6cfc82af9 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 4 Aug 2022 13:07:02 +0200 Subject: [PATCH 4/6] Apply wording suggestion Co-authored-by: Lukas Stracke --- packages/node/src/integrations/http.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node/src/integrations/http.ts b/packages/node/src/integrations/http.ts index 2a9c4bc7cb54..6c777bf51acd 100644 --- a/packages/node/src/integrations/http.ts +++ b/packages/node/src/integrations/http.ts @@ -17,7 +17,7 @@ import { const NODE_VERSION = parseSemver(process.versions.node); /** - * The http module integration instruments nodes internal http module. It creates breadcrumbs, transactions for outgoing + * The http module integration instruments Node's internal http module. It creates breadcrumbs, transactions for outgoing * http requests and attaches trace data when tracing is enabled via its `tracing` option. */ export class Http implements Integration { From 0aa153f929321dbc0a591c9a3c5c67ee0b4f76d5 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 4 Aug 2022 11:19:50 +0000 Subject: [PATCH 5/6] Extract TracePropagationTargets type --- packages/node/src/integrations/http.ts | 4 ++-- packages/node/src/types.ts | 4 ++-- packages/types/src/index.ts | 2 +- packages/types/src/options.ts | 2 ++ 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/node/src/integrations/http.ts b/packages/node/src/integrations/http.ts index 6c777bf51acd..9edd5d8c3d34 100644 --- a/packages/node/src/integrations/http.ts +++ b/packages/node/src/integrations/http.ts @@ -1,5 +1,5 @@ import { getCurrentHub, Hub } from '@sentry/core'; -import { EventProcessor, Integration, Span } from '@sentry/types'; +import { EventProcessor, Integration, Span, TracePropagationTargets } from '@sentry/types'; import { fill, isMatchingPattern, logger, mergeAndSerializeBaggage, parseSemver } from '@sentry/utils'; import * as http from 'http'; import * as https from 'https'; @@ -103,7 +103,7 @@ type WrappedRequestMethodFactory = (original: OriginalRequestMethod) => WrappedR function _createWrappedRequestMethodFactory( breadcrumbsEnabled: boolean, tracingEnabled: boolean, - tracePropagationTargets: (string | RegExp)[] | undefined, + tracePropagationTargets: TracePropagationTargets | undefined, ): WrappedRequestMethodFactory { // We're caching results so we dont have to recompute regexp everytime we create a request. const urlMap: Record = {}; diff --git a/packages/node/src/types.ts b/packages/node/src/types.ts index eda7761a6ffe..4d890d8e10b8 100644 --- a/packages/node/src/types.ts +++ b/packages/node/src/types.ts @@ -1,4 +1,4 @@ -import { ClientOptions, Options } from '@sentry/types'; +import { ClientOptions, Options, TracePropagationTargets } from '@sentry/types'; import { NodeTransportOptions } from './transports'; @@ -17,7 +17,7 @@ export interface BaseNodeOptions { * request URL of outgoing requests against the items in this * array, and only attach tracing headers if a match was found. */ - tracePropagationTargets?: (string | RegExp)[]; + tracePropagationTargets?: TracePropagationTargets; /** Callback that is executed when a fatal global error occurs. */ onFatalError?(error: Error): void; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 32b2d077a74c..76e94bc750df 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -37,7 +37,7 @@ export type { Hub } from './hub'; export type { Integration, IntegrationClass } from './integration'; export type { Mechanism } from './mechanism'; export type { ExtractedNodeRequestData, HttpHeaderValue, Primitive, WorkerLocation } from './misc'; -export type { ClientOptions, Options } from './options'; +export type { ClientOptions, Options, TracePropagationTargets } from './options'; export type { Package } from './package'; export type { PolymorphicEvent } from './polymorphics'; export type { QueryParams, Request } from './request'; diff --git a/packages/types/src/options.ts b/packages/types/src/options.ts index 077b49e4105f..0eea88a6556b 100644 --- a/packages/types/src/options.ts +++ b/packages/types/src/options.ts @@ -7,6 +7,8 @@ import { StackLineParser, StackParser } from './stacktrace'; import { SamplingContext } from './transaction'; import { BaseTransportOptions, Transport } from './transport'; +export type TracePropagationTargets = (string | RegExp)[]; + export interface ClientOptions { /** * Enable debug functionality in the SDK itself From 02da46098cb7fd28fd78b57b6948222e3531175d Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 4 Aug 2022 13:13:54 +0000 Subject: [PATCH 6/6] Add TracePropagationTargets to tracing.ts file --- packages/types/src/index.ts | 3 ++- packages/types/src/options.ts | 2 -- packages/types/src/tracing.ts | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 packages/types/src/tracing.ts diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 76e94bc750df..80b7fd82a612 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -37,7 +37,7 @@ export type { Hub } from './hub'; export type { Integration, IntegrationClass } from './integration'; export type { Mechanism } from './mechanism'; export type { ExtractedNodeRequestData, HttpHeaderValue, Primitive, WorkerLocation } from './misc'; -export type { ClientOptions, Options, TracePropagationTargets } from './options'; +export type { ClientOptions, Options } from './options'; export type { Package } from './package'; export type { PolymorphicEvent } from './polymorphics'; export type { QueryParams, Request } from './request'; @@ -63,6 +63,7 @@ export type { Span, SpanContext } from './span'; export type { StackFrame } from './stackframe'; export type { Stacktrace, StackParser, StackLineParser, StackLineParserFn } from './stacktrace'; export type { TextEncoderInternal } from './textencoder'; +export type { TracePropagationTargets } from './tracing'; export type { CustomSamplingContext, SamplingContext, diff --git a/packages/types/src/options.ts b/packages/types/src/options.ts index 0eea88a6556b..077b49e4105f 100644 --- a/packages/types/src/options.ts +++ b/packages/types/src/options.ts @@ -7,8 +7,6 @@ import { StackLineParser, StackParser } from './stacktrace'; import { SamplingContext } from './transaction'; import { BaseTransportOptions, Transport } from './transport'; -export type TracePropagationTargets = (string | RegExp)[]; - export interface ClientOptions { /** * Enable debug functionality in the SDK itself diff --git a/packages/types/src/tracing.ts b/packages/types/src/tracing.ts new file mode 100644 index 000000000000..d11db382e2ed --- /dev/null +++ b/packages/types/src/tracing.ts @@ -0,0 +1 @@ +export type TracePropagationTargets = (string | RegExp)[];