Skip to content

Commit e1e6a38

Browse files
authored
feat(v8/core): Remove span.instrumenter and instrumenter option (#10769)
ref #10677 Removes `instrumenter` from the span interface, and removes the `instrumenter` option from client options accordingly.
1 parent d8d4cf1 commit e1e6a38

38 files changed

+44
-273
lines changed

packages/bun/test/helpers.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ export function getDefaultBunClientOptions(options: Partial<BunClientOptions> =
88
integrations: [],
99
transport: () => createTransport({ recordDroppedEvent: () => undefined }, _ => resolvedSyncPromise({})),
1010
stackParser: () => [],
11-
instrumenter: 'sentry',
1211
...options,
1312
};
1413
}

packages/core/src/tracing/hubextensions.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import type { ClientOptions, CustomSamplingContext, Hub, TransactionContext } from '@sentry/types';
2-
import { logger } from '@sentry/utils';
32
import { getMainCarrier } from '../asyncContext';
43

5-
import { DEBUG_BUILD } from '../debug-build';
64
import { registerErrorInstrumentation } from './errors';
75
import { IdleTransaction } from './idletransaction';
86
import { sampleTransaction } from './sampling';
@@ -32,19 +30,6 @@ function _startTransaction(
3230
const client = this.getClient();
3331
const options: Partial<ClientOptions> = (client && client.getOptions()) || {};
3432

35-
const configInstrumenter = options.instrumenter || 'sentry';
36-
const transactionInstrumenter = transactionContext.instrumenter || 'sentry';
37-
38-
if (configInstrumenter !== transactionInstrumenter) {
39-
DEBUG_BUILD &&
40-
logger.error(
41-
`A transaction was started with instrumenter=\`${transactionInstrumenter}\`, but the SDK is configured with the \`${configInstrumenter}\` instrumenter.
42-
The transaction will not be sampled. Please use the ${configInstrumenter} instrumentation to start transactions.`,
43-
);
44-
45-
transactionContext.sampled = false;
46-
}
47-
4833
// eslint-disable-next-line deprecation/deprecation
4934
let transaction = new Transaction(transactionContext, this);
5035
transaction = sampleTransaction(transaction, options, {

packages/core/src/tracing/sentrySpan.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import type {
2-
Instrumenter,
32
Primitive,
43
Span as SpanInterface,
54
SpanAttributeValue,
@@ -90,18 +89,6 @@ export class SentrySpan implements SpanInterface {
9089
* @deprecated Use top level `Sentry.getRootSpan()` instead
9190
*/
9291
public transaction?: Transaction;
93-
94-
/**
95-
* The instrumenter that created this span.
96-
*
97-
* TODO (v8): This can probably be replaced by an `instanceOf` check of the span class.
98-
* the instrumenter can only be sentry or otel so we can check the span instance
99-
* to verify which one it is and remove this field entirely.
100-
*
101-
* @deprecated This field will be removed.
102-
*/
103-
public instrumenter: Instrumenter;
104-
10592
protected _traceId: string;
10693
protected _spanId: string;
10794
protected _parentSpanId?: string | undefined;
@@ -132,8 +119,6 @@ export class SentrySpan implements SpanInterface {
132119
this.tags = spanContext.tags ? { ...spanContext.tags } : {};
133120
// eslint-disable-next-line deprecation/deprecation
134121
this.data = spanContext.data ? { ...spanContext.data } : {};
135-
// eslint-disable-next-line deprecation/deprecation
136-
this.instrumenter = spanContext.instrumenter || 'sentry';
137122

138123
this._attributes = {};
139124
this.setAttributes({

packages/core/test/lib/serverruntimeclient.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ function getDefaultClientOptions(options: Partial<ServerRuntimeClientOptions> =
1111
integrations: [],
1212
transport: () => createTransport({ recordDroppedEvent: () => undefined }, _ => Promise.resolve({})),
1313
stackParser: () => [],
14-
instrumenter: 'sentry',
1514
...options,
1615
};
1716
}

packages/nextjs/src/common/wrapAppGetInitialPropsWithSentry.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
addTracingExtensions,
33
getActiveSpan,
4-
getClient,
54
getDynamicSamplingContextFromSpan,
65
getRootSpan,
76
spanToTraceHeader,
@@ -35,13 +34,11 @@ export function wrapAppGetInitialPropsWithSentry(origAppGetInitialProps: AppGetI
3534
const { req, res } = context.ctx;
3635

3736
const errorWrappedAppGetInitialProps = withErrorInstrumentation(wrappingTarget);
38-
const options = getClient()?.getOptions();
39-
4037
// Generally we can assume that `req` and `res` are always defined on the server:
4138
// https://nextjs.org/docs/api-reference/data-fetching/get-initial-props#context-object
4239
// This does not seem to be the case in dev mode. Because we have no clean way of associating the the data fetcher
4340
// span with each other when there are no req or res objects, we simply do not trace them at all here.
44-
if (req && res && options?.instrumenter === 'sentry') {
41+
if (req && res) {
4542
const tracedGetInitialProps = withTracedServerSideDataFetcher(errorWrappedAppGetInitialProps, req, res, {
4643
dataFetcherRouteName: '/_app',
4744
requestedRouteName: context.ctx.pathname,

packages/nextjs/src/common/wrapDocumentGetInitialPropsWithSentry.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { addTracingExtensions, getClient } from '@sentry/core';
1+
import { addTracingExtensions } from '@sentry/core';
22
import type Document from 'next/document';
33

44
import { isBuild } from './utils/isBuild';
@@ -29,13 +29,11 @@ export function wrapDocumentGetInitialPropsWithSentry(
2929
const { req, res } = context;
3030

3131
const errorWrappedGetInitialProps = withErrorInstrumentation(wrappingTarget);
32-
const options = getClient()?.getOptions();
33-
3432
// Generally we can assume that `req` and `res` are always defined on the server:
3533
// https://nextjs.org/docs/api-reference/data-fetching/get-initial-props#context-object
3634
// This does not seem to be the case in dev mode. Because we have no clean way of associating the the data fetcher
3735
// span with each other when there are no req or res objects, we simply do not trace them at all here.
38-
if (req && res && options?.instrumenter === 'sentry') {
36+
if (req && res) {
3937
const tracedGetInitialProps = withTracedServerSideDataFetcher(errorWrappedGetInitialProps, req, res, {
4038
dataFetcherRouteName: '/_document',
4139
requestedRouteName: context.pathname,

packages/nextjs/src/common/wrapErrorGetInitialPropsWithSentry.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
addTracingExtensions,
33
getActiveSpan,
4-
getClient,
54
getDynamicSamplingContextFromSpan,
65
getRootSpan,
76
spanToTraceHeader,
@@ -38,13 +37,11 @@ export function wrapErrorGetInitialPropsWithSentry(
3837
const { req, res } = context;
3938

4039
const errorWrappedGetInitialProps = withErrorInstrumentation(wrappingTarget);
41-
const options = getClient()?.getOptions();
42-
4340
// Generally we can assume that `req` and `res` are always defined on the server:
4441
// https://nextjs.org/docs/api-reference/data-fetching/get-initial-props#context-object
4542
// This does not seem to be the case in dev mode. Because we have no clean way of associating the the data fetcher
4643
// span with each other when there are no req or res objects, we simply do not trace them at all here.
47-
if (req && res && options?.instrumenter === 'sentry') {
44+
if (req && res) {
4845
const tracedGetInitialProps = withTracedServerSideDataFetcher(errorWrappedGetInitialProps, req, res, {
4946
dataFetcherRouteName: '/_error',
5047
requestedRouteName: context.pathname,

packages/nextjs/src/common/wrapGetInitialPropsWithSentry.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
addTracingExtensions,
33
getActiveSpan,
4-
getClient,
54
getDynamicSamplingContextFromSpan,
65
getRootSpan,
76
spanToTraceHeader,
@@ -34,13 +33,11 @@ export function wrapGetInitialPropsWithSentry(origGetInitialProps: GetInitialPro
3433
const { req, res } = context;
3534

3635
const errorWrappedGetInitialProps = withErrorInstrumentation(wrappingTarget);
37-
const options = getClient()?.getOptions();
38-
3936
// Generally we can assume that `req` and `res` are always defined on the server:
4037
// https://nextjs.org/docs/api-reference/data-fetching/get-initial-props#context-object
4138
// This does not seem to be the case in dev mode. Because we have no clean way of associating the the data fetcher
4239
// span with each other when there are no req or res objects, we simply do not trace them at all here.
43-
if (req && res && options?.instrumenter === 'sentry') {
40+
if (req && res) {
4441
const tracedGetInitialProps = withTracedServerSideDataFetcher(errorWrappedGetInitialProps, req, res, {
4542
dataFetcherRouteName: context.pathname,
4643
requestedRouteName: context.pathname,
Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
addTracingExtensions,
33
getActiveSpan,
4-
getClient,
54
getDynamicSamplingContextFromSpan,
65
getRootSpan,
76
spanToTraceHeader,
@@ -35,34 +34,28 @@ export function wrapGetServerSidePropsWithSentry(
3534
const { req, res } = context;
3635

3736
const errorWrappedGetServerSideProps = withErrorInstrumentation(wrappingTarget);
38-
const options = getClient()?.getOptions();
39-
40-
if (options?.instrumenter === 'sentry') {
41-
const tracedGetServerSideProps = withTracedServerSideDataFetcher(errorWrappedGetServerSideProps, req, res, {
42-
dataFetcherRouteName: parameterizedRoute,
43-
requestedRouteName: parameterizedRoute,
44-
dataFetchingMethodName: 'getServerSideProps',
45-
});
46-
47-
const serverSideProps = await (tracedGetServerSideProps.apply(thisArg, args) as ReturnType<
48-
typeof tracedGetServerSideProps
49-
>);
50-
51-
if (serverSideProps && 'props' in serverSideProps) {
52-
const activeSpan = getActiveSpan();
53-
const requestTransaction = getSpanFromRequest(req) ?? (activeSpan ? getRootSpan(activeSpan) : undefined);
54-
if (requestTransaction) {
55-
serverSideProps.props._sentryTraceData = spanToTraceHeader(requestTransaction);
56-
57-
const dynamicSamplingContext = getDynamicSamplingContextFromSpan(requestTransaction);
58-
serverSideProps.props._sentryBaggage = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext);
59-
}
37+
const tracedGetServerSideProps = withTracedServerSideDataFetcher(errorWrappedGetServerSideProps, req, res, {
38+
dataFetcherRouteName: parameterizedRoute,
39+
requestedRouteName: parameterizedRoute,
40+
dataFetchingMethodName: 'getServerSideProps',
41+
});
42+
43+
const serverSideProps = await (tracedGetServerSideProps.apply(thisArg, args) as ReturnType<
44+
typeof tracedGetServerSideProps
45+
>);
46+
47+
if (serverSideProps && 'props' in serverSideProps) {
48+
const activeSpan = getActiveSpan();
49+
const requestTransaction = getSpanFromRequest(req) ?? (activeSpan ? getRootSpan(activeSpan) : undefined);
50+
if (requestTransaction) {
51+
serverSideProps.props._sentryTraceData = spanToTraceHeader(requestTransaction);
52+
53+
const dynamicSamplingContext = getDynamicSamplingContextFromSpan(requestTransaction);
54+
serverSideProps.props._sentryBaggage = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext);
6055
}
61-
62-
return serverSideProps;
63-
} else {
64-
return errorWrappedGetServerSideProps.apply(thisArg, args);
6556
}
57+
58+
return serverSideProps;
6659
},
6760
});
6861
}

packages/nextjs/src/common/wrapGetStaticPropsWithSentry.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { addTracingExtensions, getClient } from '@sentry/core';
1+
import { addTracingExtensions } from '@sentry/core';
22
import type { GetStaticProps } from 'next';
33

44
import { isBuild } from './utils/isBuild';
@@ -26,14 +26,10 @@ export function wrapGetStaticPropsWithSentry(
2626
addTracingExtensions();
2727

2828
const errorWrappedGetStaticProps = withErrorInstrumentation(wrappingTarget);
29-
const options = getClient()?.getOptions();
30-
31-
if (options?.instrumenter === 'sentry') {
32-
return callDataFetcherTraced(errorWrappedGetStaticProps, args, {
33-
parameterizedRoute,
34-
dataFetchingMethodName: 'getStaticProps',
35-
});
36-
}
29+
return callDataFetcherTraced(errorWrappedGetStaticProps, args, {
30+
parameterizedRoute,
31+
dataFetchingMethodName: 'getStaticProps',
32+
});
3733

3834
return errorWrappedGetStaticProps.apply(thisArg, args);
3935
},

packages/nextjs/test/config/wrappers.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe('data-fetching function wrappers should create spans', () => {
2323
jest.spyOn(SentryCore, 'hasTracingEnabled').mockReturnValue(true);
2424
jest.spyOn(SentryCore, 'getClient').mockImplementation(() => {
2525
return {
26-
getOptions: () => ({ instrumenter: 'sentry' }),
26+
getOptions: () => ({}),
2727
getDsn: () => {},
2828
} as Client;
2929
});

packages/node-experimental/src/sdk/init.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ function getClientOptions(options: NodeOptions): NodeClientOptions {
153153
...baseOptions,
154154
...options,
155155
...overwriteOptions,
156-
instrumenter: 'otel',
157156
stackParser: stackParserFromStackParserOptions(options.stackParser || defaultStackParser),
158157
integrations: getIntegrationsToSetup({
159158
defaultIntegrations: options.defaultIntegrations,

packages/node/src/handlers.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,7 @@ export function tracingHandler(): (
4848
): void {
4949
const options = getClient()?.getOptions();
5050

51-
if (
52-
!options ||
53-
options.instrumenter !== 'sentry' ||
54-
req.method?.toUpperCase() === 'OPTIONS' ||
55-
req.method?.toUpperCase() === 'HEAD'
56-
) {
51+
if (req.method?.toUpperCase() === 'OPTIONS' || req.method?.toUpperCase() === 'HEAD') {
5752
return next();
5853
}
5954

packages/node/src/integrations/http.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,6 @@ export class Http implements Integration {
185185
return;
186186
}
187187

188-
// Do not auto-instrument for other instrumenter
189-
if (clientOptions && clientOptions.instrumenter !== 'sentry') {
190-
DEBUG_BUILD && logger.log('HTTP Integration is skipped because of instrumenter configuration.');
191-
return;
192-
}
193-
194188
const shouldCreateSpanForRequest = _getShouldCreateSpanForRequest(shouldCreateSpans, this._tracing, clientOptions);
195189

196190
// eslint-disable-next-line deprecation/deprecation

packages/node/src/sdk.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,6 @@ export function init(options: NodeOptions = {}): void {
147147
options.autoSessionTracking = true;
148148
}
149149

150-
if (options.instrumenter === undefined) {
151-
options.instrumenter = 'sentry';
152-
}
153-
154150
// TODO(v7): Refactor this to reduce the logic above
155151
const clientOptions: NodeClientOptions = {
156152
...options,

packages/node/test/helper/node-client-options.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ export function getDefaultNodeClientOptions(options: Partial<NodeClientOptions>
88
integrations: [],
99
transport: () => createTransport({ recordDroppedEvent: () => undefined }, _ => resolvedSyncPromise({})),
1010
stackParser: () => [],
11-
instrumenter: 'sentry',
1211
...options,
1312
};
1413
}

packages/node/test/index.test.ts

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import {
2626
import { setNodeAsyncContextStrategy } from '../src/async';
2727
import { ContextLines } from '../src/integrations';
2828
import { defaultStackParser, getDefaultIntegrations } from '../src/sdk';
29-
import type { NodeClientOptions } from '../src/types';
3029
import { getDefaultNodeClientOptions } from './helper/node-client-options';
3130

3231
jest.mock('@sentry/core', () => {
@@ -487,24 +486,6 @@ describe('SentryNode initialization', () => {
487486
});
488487
});
489488

490-
describe('instrumenter', () => {
491-
it('defaults to sentry instrumenter', () => {
492-
init({ dsn });
493-
494-
const instrumenter = (getClient()?.getOptions() as NodeClientOptions).instrumenter;
495-
496-
expect(instrumenter).toEqual('sentry');
497-
});
498-
499-
it('allows to set instrumenter', () => {
500-
init({ dsn, instrumenter: 'otel' });
501-
502-
const instrumenter = (getClient()?.getOptions() as NodeClientOptions).instrumenter;
503-
504-
expect(instrumenter).toEqual('otel');
505-
});
506-
});
507-
508489
describe('propagation context', () => {
509490
beforeEach(() => {
510491
process.env.SENTRY_TRACE = '12312012123120121231201212312012-1121201211212012-0';

packages/node/test/integrations/http.test.ts

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Transaction } from '@sentry/core';
77
import { getCurrentScope, setUser, spanToJSON, startInactiveSpan } from '@sentry/core';
88
import { addTracingExtensions } from '@sentry/core';
99
import type { TransactionContext } from '@sentry/types';
10-
import { TRACEPARENT_REGEXP, logger } from '@sentry/utils';
10+
import { TRACEPARENT_REGEXP } from '@sentry/utils';
1111
import * as nock from 'nock';
1212
import { HttpsProxyAgent } from '../../src/proxy';
1313

@@ -259,33 +259,6 @@ describe('tracing', () => {
259259
expect(baggage).not.toBeDefined();
260260
});
261261

262-
it("doesn't attach when using otel instrumenter", () => {
263-
const loggerLogSpy = jest.spyOn(logger, 'log');
264-
265-
const options = getDefaultNodeClientOptions({
266-
dsn: 'https://[email protected]/12312012',
267-
tracesSampleRate: 1.0,
268-
// eslint-disable-next-line deprecation/deprecation
269-
integrations: [new HttpIntegration({ tracing: true })],
270-
release: '1.0.0',
271-
environment: 'production',
272-
instrumenter: 'otel',
273-
});
274-
const client = new NodeClient(options);
275-
setCurrentClient(client);
276-
// eslint-disable-next-line deprecation/deprecation
277-
const hub = getCurrentHub();
278-
279-
// eslint-disable-next-line deprecation/deprecation
280-
const integration = new HttpIntegration();
281-
integration.setupOnce(
282-
() => {},
283-
() => hub as Hub,
284-
);
285-
286-
expect(loggerLogSpy).toBeCalledWith('HTTP Integration is skipped because of instrumenter configuration.');
287-
});
288-
289262
it('omits query and fragment from description and adds to span data instead', () => {
290263
nock('http://dogs.are.great').get('/spaniel?tail=wag&cute=true#learn-more').reply(200);
291264

0 commit comments

Comments
 (0)