Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 0 additions & 58 deletions packages/opentelemetry/src/custom/client.ts

This file was deleted.

3 changes: 0 additions & 3 deletions packages/opentelemetry/src/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ export { SEMANTIC_ATTRIBUTE_SENTRY_GRAPHQL_OPERATION } from './semanticAttribute

export { getRequestSpanData } from './utils/getRequestSpanData';

export type { OpenTelemetryClient } from './types';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Public API removed without deprecation

Medium Severity

Flagging because it was mentioned in the PR Review Guidelines: the Breaking Changes rules call out removing publicly exported functions or types without a deprecation notice. This drops wrapClientClass and OpenTelemetryClient from the @sentry/opentelemetry public entrypoint with no @deprecated period, unlike wrapContextManagerClass.

Additional Locations (1)
Fix in Cursor Fix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 950d15a. Configure here.

export { wrapClientClass } from './custom/client';

export { getScopesFromContext } from './utils/contextData';

export {
Expand Down
5 changes: 3 additions & 2 deletions packages/opentelemetry/src/trace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
spanToTraceContext,
} from '@sentry/core';
import { continueTraceAsRemoteSpan } from './propagator';
import type { OpenTelemetryClient, OpenTelemetrySpanContext } from './types';
import type { OpenTelemetrySpanContext } from './types';
import { getContextFromScope } from './utils/contextData';
import { getSamplingDecision } from './utils/getSamplingDecision';
import { makeTraceState } from './utils/makeTraceState';
Expand Down Expand Up @@ -189,7 +189,8 @@ export function withActiveSpan<T>(span: Span | null, callback: (scope: Scope) =>
}

function getTracer(): Tracer {
const client = getClient<Client & OpenTelemetryClient>();
// The node client has a `tracer` property, we use this if it exists, or else we use the global tracer
const client = getClient<Client & { tracer?: Tracer }>();
return client?.tracer || trace.getTracer('@sentry/opentelemetry', SDK_VERSION);
}

Expand Down
9 changes: 2 additions & 7 deletions packages/opentelemetry/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import type { Span as WriteableSpan, SpanKind, Tracer, TracerProvider } from '@opentelemetry/api';
import type { BasicTracerProvider, ReadableSpan } from '@opentelemetry/sdk-trace-base';
import type { Span as WriteableSpan, SpanKind, TracerProvider } from '@opentelemetry/api';
import type { ReadableSpan } from '@opentelemetry/sdk-trace-base';
import type { Scope, Span, StartSpanOptions } from '@sentry/core';

export interface OpenTelemetryTracerProvider extends TracerProvider {
forceFlush(): Promise<void>;
shutdown(): Promise<void>;
}

export interface OpenTelemetryClient {
tracer: Tracer;
traceProvider: BasicTracerProvider | OpenTelemetryTracerProvider | undefined;
}

export interface OpenTelemetrySpanContext extends StartSpanOptions {
// Additional otel-only option, for now...?
kind?: SpanKind;
Expand Down
43 changes: 34 additions & 9 deletions packages/opentelemetry/test/helpers/TestClient.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,41 @@
import { trace, type Tracer } from '@opentelemetry/api';
import type { ClientOptions, Event, Options, SeverityLevel } from '@sentry/core';
import { Client, createTransport, getCurrentScope, resolvedSyncPromise } from '@sentry/core';
import { wrapClientClass } from '../../src/custom/client';
import type { OpenTelemetryClient } from '../../src/types';
import { Client, createTransport, getCurrentScope, resolvedSyncPromise, SDK_VERSION } from '@sentry/core';
import type { SentrySpanProcessor } from '../../src/spanProcessor';
import type { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';

export class TestClient extends Client<ClientOptions> {
public traceProvider: BasicTracerProvider | undefined;
public spanProcessor: SentrySpanProcessor | undefined;
private _tracer: Tracer | undefined;

class BaseTestClient extends Client<ClientOptions> {
public constructor(options: ClientOptions) {
super(options);
}

/** Get the OTEL tracer. */
public get tracer(): Tracer {
if (this._tracer) {
return this._tracer;
}

const name = '@sentry/opentelemetry';
const version = SDK_VERSION;
const tracer = (this.traceProvider || trace)?.getTracer(name, version);
this._tracer = tracer;

return tracer;
}

/**
* @inheritDoc
*/
public async flush(timeout?: number): Promise<boolean> {
const provider = this.traceProvider;
await provider?.forceFlush();
return super.flush(timeout);
}

public eventFromException(exception: any): PromiseLike<Event> {
return resolvedSyncPromise({
exception: {
Expand All @@ -26,16 +54,13 @@ class BaseTestClient extends Client<ClientOptions> {
}
}

export const TestClient = wrapClientClass(BaseTestClient);

export type TestClientInterface = Client & OpenTelemetryClient;

export function init(options: Partial<Options> = {}): void {
export function init(options: Partial<Options> = {}): Client {
const client = new TestClient(getDefaultTestClientOptions({ tracesSampleRate: 1, ...options }));

// The client is on the current scope, from where it generally is inherited
getCurrentScope().setClient(client);
client.init();
return client;
}

export function getDefaultTestClientOptions(options: Partial<Options> = {}): ClientOptions {
Expand Down
7 changes: 4 additions & 3 deletions packages/opentelemetry/test/helpers/initOtel.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { context, diag, DiagLogLevel, propagation, trace } from '@opentelemetry/api';
import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';
import type { Client } from '@sentry/core';
import { debug, getClient } from '@sentry/core';
import { SentryAsyncLocalStorageContextManager } from '../../src/asyncLocalStorageContextManager';
import { DEBUG_BUILD } from '../../src/debug-build';
Expand All @@ -9,13 +10,13 @@ import { SentrySampler } from '../../src/sampler';
import { setupEventContextTrace } from '../../src/setupEventContextTrace';
import { SentrySpanProcessor } from '../../src/spanProcessor';
import { enhanceDscWithOpenTelemetryRootSpanName } from '../../src/utils/enhanceDscWithOpenTelemetryRootSpanName';
import type { TestClientInterface } from './TestClient';
import type { TestClient } from './TestClient';

/**
* Initialize OpenTelemetry for Node.
*/
export function initOtel(): void {
const client = getClient<TestClientInterface>();
const client = getClient<TestClient>();

if (!client) {
DEBUG_BUILD &&
Expand Down Expand Up @@ -49,7 +50,7 @@ export function initOtel(): void {
}

/** Just exported for tests. */
export function setupOtel(client: TestClientInterface): [BasicTracerProvider, SentrySpanProcessor] {
export function setupOtel(client: Client): [BasicTracerProvider, SentrySpanProcessor] {
const spanProcessor = new SentrySpanProcessor();
// Create and configure NodeTracerProvider
const provider = new BasicTracerProvider({
Expand Down
13 changes: 7 additions & 6 deletions packages/opentelemetry/test/helpers/mockSdkInit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@ import type { ClientOptions, Options } from '@sentry/core';
import { flush, getClient, getCurrentScope, getGlobalScope, getIsolationScope } from '@sentry/core';
import { setOpenTelemetryContextAsyncContextStrategy } from '../../src/asyncContextStrategy';
import { SentrySpanProcessor } from '../../src/spanProcessor';
import type { OpenTelemetryClient } from '../../src/types';
import { clearOpenTelemetrySetupCheck } from '../../src/utils/setupCheck';
import { initOtel } from './initOtel';
import type { TestClient } from './TestClient';
import { init as initTestClient } from './TestClient';

const PUBLIC_DSN = 'https://username@domain/123';

/**
* Initialize Sentry for Node.
*/
function init(options: Partial<Options> | undefined = {}): void {
function init(options: Partial<Options> | undefined = {}): TestClient {
setOpenTelemetryContextAsyncContextStrategy();
initTestClient(options);
const client = initTestClient(options);
initOtel();
return client;
}

function resetGlobals(): void {
Expand All @@ -28,10 +29,10 @@ function resetGlobals(): void {
delete (global as any).__SENTRY__;
}

export function mockSdkInit(options?: Partial<ClientOptions>) {
export function mockSdkInit(options?: Partial<ClientOptions>): TestClient {
resetGlobals();

init({ dsn: PUBLIC_DSN, ...options });
return init({ dsn: PUBLIC_DSN, ...options })!;
}

export async function cleanupOtel(_provider?: BasicTracerProvider): Promise<void> {
Expand All @@ -53,7 +54,7 @@ export async function cleanupOtel(_provider?: BasicTracerProvider): Promise<void
}

export function getSpanProcessor(): SentrySpanProcessor | undefined {
const client = getClient<OpenTelemetryClient>();
const client = getClient();
if (!client) {
return undefined;
}
Expand Down
31 changes: 8 additions & 23 deletions packages/opentelemetry/test/integration/breadcrumbs.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { addBreadcrumb, captureException, getClient, withIsolationScope, withScope } from '@sentry/core';
import { addBreadcrumb, captureException, withIsolationScope, withScope } from '@sentry/core';
import { afterEach, describe, expect, it, vi } from 'vitest';
import { startSpan } from '../../src/trace';
import { cleanupOtel, mockSdkInit } from '../helpers/mockSdkInit';
import type { TestClientInterface } from '../helpers/TestClient';

describe('Integration | breadcrumbs', () => {
const beforeSendTransaction = vi.fn(() => null);
Expand All @@ -16,9 +15,7 @@ describe('Integration | breadcrumbs', () => {
const beforeSend = vi.fn(() => null);
const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb);

mockSdkInit({ beforeSend, beforeBreadcrumb });

const client = getClient() as TestClientInterface;
const client = mockSdkInit({ beforeSend, beforeBreadcrumb });

addBreadcrumb({ timestamp: 123456, message: 'test1' });
addBreadcrumb({ timestamp: 123457, message: 'test2', data: { nested: 'yes' } });
Expand Down Expand Up @@ -52,9 +49,7 @@ describe('Integration | breadcrumbs', () => {
const beforeSend = vi.fn(() => null);
const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb);

mockSdkInit({ beforeSend, beforeBreadcrumb });

const client = getClient() as TestClientInterface;
const client = mockSdkInit({ beforeSend, beforeBreadcrumb });

const error = new Error('test');

Expand Down Expand Up @@ -98,9 +93,7 @@ describe('Integration | breadcrumbs', () => {
const beforeSend = vi.fn(() => null);
const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb);

mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });

const client = getClient() as TestClientInterface;
const client = mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });

const error = new Error('test');

Expand Down Expand Up @@ -143,9 +136,7 @@ describe('Integration | breadcrumbs', () => {
const beforeSend = vi.fn(() => null);
const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb);

mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });

const client = getClient() as TestClientInterface;
const client = mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });

const error = new Error('test');

Expand Down Expand Up @@ -195,9 +186,7 @@ describe('Integration | breadcrumbs', () => {
const beforeSend = vi.fn(() => null);
const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb);

mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });

const client = getClient() as TestClientInterface;
const client = mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });
Comment thread
cursor[bot] marked this conversation as resolved.

const error = new Error('test');

Expand Down Expand Up @@ -236,9 +225,7 @@ describe('Integration | breadcrumbs', () => {
const beforeSend = vi.fn(() => null);
const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb);

mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });

const client = getClient() as TestClientInterface;
const client = mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });

const error = new Error('test');

Expand Down Expand Up @@ -294,9 +281,7 @@ describe('Integration | breadcrumbs', () => {
const beforeSend = vi.fn(() => null);
const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb);

mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });

const client = getClient() as TestClientInterface;
const client = mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 });

const error = new Error('test');

Expand Down
13 changes: 3 additions & 10 deletions packages/opentelemetry/test/integration/scope.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
captureException,
getCapturedScopesOnSpan,
getClient,
getCurrentScope,
getIsolationScope,
setTag,
Expand All @@ -11,7 +10,6 @@ import {
import { afterEach, describe, expect, it, vi } from 'vitest';
import { startSpan } from '../../src/trace';
import { cleanupOtel, mockSdkInit } from '../helpers/mockSdkInit';
import type { TestClientInterface } from '../helpers/TestClient';

describe('Integration | Scope', () => {
afterEach(async () => {
Expand All @@ -26,14 +24,12 @@ describe('Integration | Scope', () => {
const beforeSend = vi.fn(() => null);
const beforeSendTransaction = vi.fn(() => null);

mockSdkInit({
const client = mockSdkInit({
tracesSampleRate: tracingEnabled ? 1 : 0,
beforeSend,
beforeSendTransaction,
});

const client = getClient() as TestClientInterface;

const rootScope = getCurrentScope();

const error = new Error('test error');
Expand Down Expand Up @@ -144,9 +140,7 @@ describe('Integration | Scope', () => {
const beforeSend = vi.fn(() => null);
const beforeSendTransaction = vi.fn(() => null);

mockSdkInit({ tracesSampleRate: tracingEnabled ? 1 : 0, beforeSend, beforeSendTransaction });

const client = getClient() as TestClientInterface;
const client = mockSdkInit({ tracesSampleRate: tracingEnabled ? 1 : 0, beforeSend, beforeSendTransaction });
const rootScope = getCurrentScope();

const error1 = new Error('test error 1');
Expand Down Expand Up @@ -262,9 +256,8 @@ describe('Integration | Scope', () => {
const beforeSend = vi.fn(() => null);
const beforeSendTransaction = vi.fn(() => null);

mockSdkInit({ tracesSampleRate: tracingEnabled ? 1 : 0, beforeSend, beforeSendTransaction });
const client = mockSdkInit({ tracesSampleRate: tracingEnabled ? 1 : 0, beforeSend, beforeSendTransaction });

const client = getClient() as TestClientInterface;
const rootScope = getCurrentScope();

const error1 = new Error('test error 1');
Expand Down
Loading
Loading