Skip to content

Commit 725d4b9

Browse files
committed
Remove auto-otel init and fix unit tests
1 parent 880ac13 commit 725d4b9

File tree

14 files changed

+119
-469
lines changed

14 files changed

+119
-469
lines changed

packages/node-core/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ export { SentryContextManager } from './otel/contextManager';
1919
export { generateInstrumentOnce } from './otel/instrument';
2020

2121
export { init, getDefaultIntegrations, initWithoutDefaultIntegrations, validateOpenTelemetrySetup } from './sdk';
22-
export { initOpenTelemetry } from './sdk/initOtel';
2322
export { getSentryRelease, defaultStackParser } from './sdk/api';
2423
export { createGetModuleFromFilename } from './utils/module';
2524
export { makeNodeTransport } from './transports';

packages/node-core/src/otel/resources.ts

Lines changed: 0 additions & 46 deletions
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { consoleSandbox, GLOBAL_OBJ, logger } from '@sentry/core';
2+
import { createAddHookMessageChannel } from 'import-in-the-middle';
3+
import moduleModule from 'module';
4+
5+
/** Initialize the ESM loader. */
6+
export function maybeInitializeEsmLoader(): void {
7+
const [nodeMajor = 0, nodeMinor = 0] = process.versions.node.split('.').map(Number);
8+
9+
// Register hook was added in v20.6.0 and v18.19.0
10+
if (nodeMajor >= 21 || (nodeMajor === 20 && nodeMinor >= 6) || (nodeMajor === 18 && nodeMinor >= 19)) {
11+
if (!GLOBAL_OBJ._sentryEsmLoaderHookRegistered) {
12+
try {
13+
const { addHookMessagePort } = createAddHookMessageChannel();
14+
// @ts-expect-error register is available in these versions
15+
moduleModule.register('import-in-the-middle/hook.mjs', import.meta.url, {
16+
data: { addHookMessagePort, include: [] },
17+
transferList: [addHookMessagePort],
18+
});
19+
} catch (error) {
20+
logger.warn('Failed to register ESM hook', error);
21+
}
22+
}
23+
} else {
24+
consoleSandbox(() => {
25+
// eslint-disable-next-line no-console
26+
console.warn(
27+
`[Sentry] You are using Node.js v${process.versions.node} in ESM mode ("import syntax"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS ("require() syntax"), or upgrade your Node.js version.`,
28+
);
29+
});
30+
}
31+
}

packages/node-core/src/sdk/index.ts

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { diag, DiagLogLevel } from '@opentelemetry/api';
12
import type { Integration, Options } from '@sentry/core';
23
import {
34
consoleIntegration,
@@ -37,7 +38,7 @@ import { isCjs } from '../utils/commonjs';
3738
import { envToBool } from '../utils/envToBool';
3839
import { defaultStackParser, getSentryRelease } from './api';
3940
import { NodeClient } from './client';
40-
import { initOpenTelemetry, maybeInitializeEsmLoader } from './initOtel';
41+
import { maybeInitializeEsmLoader } from './esmLoader';
4142

4243
function getCjsOnlyIntegrations(): Integration[] {
4344
return isCjs() ? [modulesIntegration()] : [];
@@ -136,14 +137,7 @@ function _init(
136137

137138
updateScopeFromEnvVariables();
138139

139-
// If users opt-out of this, they _have_ to set up OpenTelemetry themselves
140-
// There is no way to use this SDK without OpenTelemetry!
141-
if (!options.skipOpenTelemetrySetup) {
142-
initOpenTelemetry(client, {
143-
spanProcessors: options.openTelemetrySpanProcessors,
144-
});
145-
validateOpenTelemetrySetup();
146-
}
140+
setupOpenTelemetryLogger();
147141

148142
enhanceDscWithOpenTelemetryRootSpanName(client);
149143
setupEventContextTrace(client);
@@ -257,3 +251,19 @@ function updateScopeFromEnvVariables(): void {
257251
getCurrentScope().setPropagationContext(propagationContext);
258252
}
259253
}
254+
255+
/**
256+
* Setup the OTEL logger to use our own logger.
257+
*/
258+
function setupOpenTelemetryLogger(): void {
259+
const otelLogger = new Proxy(logger as typeof logger & { verbose: (typeof logger)['debug'] }, {
260+
get(target, prop, receiver) {
261+
const actualProp = prop === 'verbose' ? 'debug' : prop;
262+
return Reflect.get(target, actualProp, receiver);
263+
},
264+
});
265+
266+
// Disable diag, to ensure this works even if called multiple times
267+
diag.disable();
268+
diag.setLogger(otelLogger, DiagLogLevel.DEBUG);
269+
}

packages/node-core/src/sdk/initOtel.ts

Lines changed: 0 additions & 128 deletions
This file was deleted.

packages/node-core/src/types.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,6 @@ export interface BaseNodeOptions {
8383
*/
8484
spotlight?: boolean | string;
8585

86-
/**
87-
* If this is set to true, the SDK will not set up OpenTelemetry automatically.
88-
* In this case, you _have_ to ensure to set it up correctly yourself, including:
89-
* * The `SentrySpanProcessor`
90-
* * The `SentryPropagator`
91-
* * The `SentryContextManager`
92-
* * The `SentrySampler`
93-
*
94-
* If you are registering your own OpenTelemetry Loader Hooks (or `import-in-the-middle` hooks), it is also recommended to set the `registerEsmLoaderHooks` option to false.
95-
*/
96-
skipOpenTelemetrySetup?: boolean;
97-
9886
/**
9987
* Provide an array of OpenTelemetry Instrumentations that should be registered.
10088
*

packages/node-core/test/helpers/mockSdkInit.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { context, propagation, ProxyTracerProvider, trace } from '@opentelemetry/api';
22
import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';
33
import { getClient, getCurrentScope, getGlobalScope, getIsolationScope } from '@sentry/core';
4+
import { SentryPropagator, SentrySampler, SentrySpanProcessor } from '@sentry/opentelemetry';
45
import type { NodeClient } from '../../src';
5-
import { init } from '../../src/sdk';
6+
import { SentryContextManager } from '../../src/otel/contextManager';
7+
import { init, validateOpenTelemetrySetup } from '../../src/sdk';
68
import type { NodeClientOptions } from '../../src/types';
79

810
const PUBLIC_DSN = 'https://username@domain/123';
@@ -16,14 +18,28 @@ export function resetGlobals(): void {
1618

1719
export function mockSdkInit(options?: Partial<NodeClientOptions>) {
1820
resetGlobals();
19-
init({
21+
const client = init({
2022
dsn: PUBLIC_DSN,
2123
defaultIntegrations: false,
2224
// We are disabling client reports because we would be acquiring resources with every init call and that would leak
2325
// memory every time we call init in the tests
2426
sendClientReports: false,
2527
...options,
2628
});
29+
30+
const provider = new BasicTracerProvider({
31+
sampler: client ? new SentrySampler(client) : undefined,
32+
spanProcessors: [new SentrySpanProcessor()],
33+
});
34+
35+
provider.register({
36+
propagator: new SentryPropagator(),
37+
contextManager: new SentryContextManager(),
38+
});
39+
40+
validateOpenTelemetrySetup();
41+
42+
return provider;
2743
}
2844

2945
export function cleanupOtel(_provider?: BasicTracerProvider): void {

packages/node-core/test/integration/breadcrumbs.test.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';
12
import { addBreadcrumb, captureException, withIsolationScope, withScope } from '@sentry/core';
23
import { startSpan } from '@sentry/opentelemetry';
34
import { afterEach, describe, expect, it, vi } from 'vitest';
@@ -8,16 +9,18 @@ import { cleanupOtel, mockSdkInit } from '../helpers/mockSdkInit';
89
describe('Integration | breadcrumbs', () => {
910
const beforeSendTransaction = vi.fn(() => null);
1011

12+
let provider: BasicTracerProvider | undefined;
13+
1114
afterEach(() => {
12-
cleanupOtel();
15+
cleanupOtel(provider);
1316
});
1417

1518
describe('without tracing', () => {
1619
it('correctly adds & retrieves breadcrumbs', async () => {
1720
const beforeSend = vi.fn(() => null);
1821
const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb);
1922

20-
mockSdkInit({ beforeSend, beforeBreadcrumb });
23+
provider = mockSdkInit({ beforeSend, beforeBreadcrumb });
2124

2225
const client = getClient() as NodeClient;
2326

@@ -53,7 +56,7 @@ describe('Integration | breadcrumbs', () => {
5356
const beforeSend = vi.fn(() => null);
5457
const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb);
5558

56-
mockSdkInit({ beforeSend, beforeBreadcrumb });
59+
provider = mockSdkInit({ beforeSend, beforeBreadcrumb });
5760

5861
const client = getClient();
5962

@@ -99,7 +102,7 @@ describe('Integration | breadcrumbs', () => {
99102
const beforeSend = vi.fn(() => null);
100103
const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb);
101104

102-
mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });
105+
provider = mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });
103106

104107
const client = getClient() as NodeClient;
105108

@@ -144,7 +147,7 @@ describe('Integration | breadcrumbs', () => {
144147
const beforeSend = vi.fn(() => null);
145148
const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb);
146149

147-
mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });
150+
provider = mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });
148151

149152
const client = getClient() as NodeClient;
150153

@@ -196,7 +199,7 @@ describe('Integration | breadcrumbs', () => {
196199
const beforeSend = vi.fn(() => null);
197200
const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb);
198201

199-
mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });
202+
provider = mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });
200203

201204
const client = getClient() as NodeClient;
202205

@@ -237,7 +240,7 @@ describe('Integration | breadcrumbs', () => {
237240
const beforeSend = vi.fn(() => null);
238241
const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb);
239242

240-
mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });
243+
provider = mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });
241244

242245
const client = getClient() as NodeClient;
243246

0 commit comments

Comments
 (0)