diff --git a/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/package.json b/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/package.json index c5fe928a931e..fab00c1feeba 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/package.json +++ b/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/package.json @@ -12,7 +12,7 @@ }, "dependencies": { "@opentelemetry/api": "^1.9.0", - "@opentelemetry/sdk-trace-node": "^1.25.1", + "@opentelemetry/sdk-trace-node": "^2.0.0", "@sentry/node": "latest || *", "@sentry/opentelemetry": "latest || *", "@types/express": "4.17.17", diff --git a/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/package.json b/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/package.json index efb74e7346ad..92ec78f47837 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/package.json +++ b/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/package.json @@ -11,8 +11,8 @@ "test:assert": "pnpm test" }, "dependencies": { - "@opentelemetry/sdk-node": "0.52.1", - "@opentelemetry/exporter-trace-otlp-http": "0.52.1", + "@opentelemetry/sdk-node": "0.200.0", + "@opentelemetry/exporter-trace-otlp-http": "0.200.0", "@sentry/core": "latest || *", "@sentry/node": "latest || *", "@sentry/opentelemetry": "latest || *", diff --git a/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/package.json b/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/package.json index b097e5b91930..73bd0240c5a2 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/package.json +++ b/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/package.json @@ -11,11 +11,11 @@ "test:assert": "pnpm test" }, "dependencies": { - "@opentelemetry/sdk-trace-node": "1.26.0", - "@opentelemetry/exporter-trace-otlp-http": "0.53.0", + "@opentelemetry/sdk-trace-node": "2.0.0", + "@opentelemetry/exporter-trace-otlp-http": "0.200.0", "@opentelemetry/instrumentation-undici": "0.6.0", - "@opentelemetry/instrumentation-http": "0.53.0", - "@opentelemetry/instrumentation": "0.53.0", + "@opentelemetry/instrumentation-http": "0.200.0", + "@opentelemetry/instrumentation": "0.200.0", "@sentry/core": "latest || *", "@sentry/node": "latest || *", "@sentry/opentelemetry": "latest || *", diff --git a/dev-packages/e2e-tests/test-applications/node-otel/package.json b/dev-packages/e2e-tests/test-applications/node-otel/package.json index 3112ce669479..9aee4f42a043 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel/package.json +++ b/dev-packages/e2e-tests/test-applications/node-otel/package.json @@ -11,8 +11,8 @@ "test:assert": "pnpm test" }, "dependencies": { - "@opentelemetry/sdk-node": "0.52.1", - "@opentelemetry/exporter-trace-otlp-http": "0.52.1", + "@opentelemetry/sdk-node": "0.200.0", + "@opentelemetry/exporter-trace-otlp-http": "0.200.0", "@sentry/core": "latest || *", "@sentry/node": "latest || *", "@sentry/opentelemetry": "latest || *", diff --git a/packages/aws-serverless/package.json b/packages/aws-serverless/package.json index 14844c374819..9bdff7eb58b2 100644 --- a/packages/aws-serverless/package.json +++ b/packages/aws-serverless/package.json @@ -65,7 +65,7 @@ }, "dependencies": { "@opentelemetry/api": "^1.9.0", - "@opentelemetry/instrumentation": "^0.57.2", + "@opentelemetry/instrumentation": "^0.200.0", "@opentelemetry/instrumentation-aws-lambda": "0.50.3", "@opentelemetry/instrumentation-aws-sdk": "0.49.1", "@sentry/core": "9.10.1", diff --git a/packages/core/src/utils/spanUtils.ts b/packages/core/src/utils/spanUtils.ts index cbfcde2a2576..fb683d0111c5 100644 --- a/packages/core/src/utils/spanUtils.ts +++ b/packages/core/src/utils/spanUtils.ts @@ -17,6 +17,7 @@ import type { SpanOrigin, SpanStatus, SpanTimeInput, + SpanContextData, TraceContext, } from '../types-hoist'; import type { SpanLink, SpanLinkJSON } from '../types-hoist/link'; @@ -145,14 +146,15 @@ export function spanToJSON(span: Span): SpanJSON { // Handle a span from @opentelemetry/sdk-base-trace's `Span` class if (spanIsOpenTelemetrySdkTraceBaseSpan(span)) { - const { attributes, startTime, name, endTime, parentSpanId, status, links } = span; + const { attributes, startTime, name, endTime, status, links } = span; + const parent_span_id = span.parentSpanContext?.spanId; return { span_id, trace_id, data: attributes, description: name, - parent_span_id: parentSpanId, + parent_span_id, start_timestamp: spanTimeInputToSeconds(startTime), // This is [0,0] by default in OTEL, in which case we want to interpret this as no end time timestamp: spanTimeInputToSeconds(endTime) || undefined, @@ -185,7 +187,7 @@ export interface OpenTelemetrySdkTraceBaseSpan extends Span { name: string; status: SpanStatus; endTime: SpanTimeInput; - parentSpanId?: string; + parentSpanContext?: SpanContextData; links?: SpanLink[]; } diff --git a/packages/nestjs/package.json b/packages/nestjs/package.json index 3e67a79c1546..f60877c2efea 100644 --- a/packages/nestjs/package.json +++ b/packages/nestjs/package.json @@ -45,8 +45,8 @@ }, "dependencies": { "@opentelemetry/api": "^1.9.0", - "@opentelemetry/core": "^1.30.1", - "@opentelemetry/instrumentation": "0.57.2", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "0.200.0", "@opentelemetry/instrumentation-nestjs-core": "0.44.1", "@opentelemetry/semantic-conventions": "^1.30.0", "@sentry/core": "9.10.1", diff --git a/packages/nestjs/src/integrations/sentry-nest-event-instrumentation.ts b/packages/nestjs/src/integrations/sentry-nest-event-instrumentation.ts index 0e3d077ddbb6..210aa807c415 100644 --- a/packages/nestjs/src/integrations/sentry-nest-event-instrumentation.ts +++ b/packages/nestjs/src/integrations/sentry-nest-event-instrumentation.ts @@ -1,9 +1,9 @@ -import { isWrapped } from '@opentelemetry/core'; import type { InstrumentationConfig } from '@opentelemetry/instrumentation'; import { InstrumentationBase, InstrumentationNodeModuleDefinition, InstrumentationNodeModuleFile, + isWrapped, } from '@opentelemetry/instrumentation'; import { SDK_VERSION, captureException, startSpan } from '@sentry/core'; import { getEventSpanOptions } from './helpers'; diff --git a/packages/nestjs/src/integrations/sentry-nest-instrumentation.ts b/packages/nestjs/src/integrations/sentry-nest-instrumentation.ts index 58060f844888..a1bf3ecff687 100644 --- a/packages/nestjs/src/integrations/sentry-nest-instrumentation.ts +++ b/packages/nestjs/src/integrations/sentry-nest-instrumentation.ts @@ -1,9 +1,9 @@ -import { isWrapped } from '@opentelemetry/core'; import type { InstrumentationConfig } from '@opentelemetry/instrumentation'; import { InstrumentationBase, InstrumentationNodeModuleDefinition, InstrumentationNodeModuleFile, + isWrapped, } from '@opentelemetry/instrumentation'; import type { Span } from '@sentry/core'; import { diff --git a/packages/node/package.json b/packages/node/package.json index 866a2810db0e..3dd5082f124b 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -66,9 +66,9 @@ }, "dependencies": { "@opentelemetry/api": "^1.9.0", - "@opentelemetry/context-async-hooks": "^1.30.1", - "@opentelemetry/core": "^1.30.1", - "@opentelemetry/instrumentation": "^0.57.2", + "@opentelemetry/context-async-hooks": "^2.0.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.200.0", "@opentelemetry/instrumentation-amqplib": "^0.46.1", "@opentelemetry/instrumentation-connect": "0.43.1", "@opentelemetry/instrumentation-dataloader": "0.16.1", @@ -78,7 +78,7 @@ "@opentelemetry/instrumentation-generic-pool": "0.43.1", "@opentelemetry/instrumentation-graphql": "0.47.1", "@opentelemetry/instrumentation-hapi": "0.45.2", - "@opentelemetry/instrumentation-http": "0.57.2", + "@opentelemetry/instrumentation-http": "0.200.0", "@opentelemetry/instrumentation-ioredis": "0.47.1", "@opentelemetry/instrumentation-kafkajs": "0.7.1", "@opentelemetry/instrumentation-knex": "0.44.1", @@ -92,8 +92,8 @@ "@opentelemetry/instrumentation-redis-4": "0.46.1", "@opentelemetry/instrumentation-tedious": "0.18.1", "@opentelemetry/instrumentation-undici": "0.10.1", - "@opentelemetry/resources": "^1.30.1", - "@opentelemetry/sdk-trace-base": "^1.30.1", + "@opentelemetry/resources": "^2.0.0", + "@opentelemetry/sdk-trace-base": "^2.0.0", "@opentelemetry/semantic-conventions": "^1.30.0", "@prisma/instrumentation": "6.5.0", "@sentry/core": "9.10.1", diff --git a/packages/node/src/integrations/http/SentryHttpInstrumentation.ts b/packages/node/src/integrations/http/SentryHttpInstrumentation.ts index aa1f0157f2cf..14031fdd536e 100644 --- a/packages/node/src/integrations/http/SentryHttpInstrumentation.ts +++ b/packages/node/src/integrations/http/SentryHttpInstrumentation.ts @@ -1,6 +1,5 @@ /* eslint-disable max-lines */ import { context, propagation } from '@opentelemetry/api'; -import { VERSION } from '@opentelemetry/core'; import type { InstrumentationConfig } from '@opentelemetry/instrumentation'; import { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation'; import type { AggregationCounts, Client, RequestEventData, SanitizedRequestData, Scope } from '@sentry/core'; @@ -92,7 +91,7 @@ const MAX_BODY_BYTE_LENGTH = 1024 * 1024; */ export class SentryHttpInstrumentation extends InstrumentationBase { public constructor(config: SentryHttpInstrumentationOptions = {}) { - super('@sentry/instrumentation-http', VERSION, config); + super('@sentry/instrumentation-http', '2.0.0', config); } /** @inheritdoc */ diff --git a/packages/node/src/integrations/node-fetch/SentryNodeFetchInstrumentation.ts b/packages/node/src/integrations/node-fetch/SentryNodeFetchInstrumentation.ts index f7327b095359..02d6ed6f6752 100644 --- a/packages/node/src/integrations/node-fetch/SentryNodeFetchInstrumentation.ts +++ b/packages/node/src/integrations/node-fetch/SentryNodeFetchInstrumentation.ts @@ -1,4 +1,3 @@ -import { VERSION } from '@opentelemetry/core'; import type { InstrumentationConfig } from '@opentelemetry/instrumentation'; import { InstrumentationBase } from '@opentelemetry/instrumentation'; import type { SanitizedRequestData } from '@sentry/core'; @@ -56,7 +55,7 @@ export class SentryNodeFetchInstrumentation extends InstrumentationBase; public constructor(config: SentryNodeFetchInstrumentationOptions = {}) { - super('@sentry/instrumentation-node-fetch', VERSION, config); + super('@sentry/instrumentation-node-fetch', '2.0.0', config); this._channelSubs = []; this._propagationDecisionMap = new LRUMap(100); } diff --git a/packages/node/src/sdk/client.ts b/packages/node/src/sdk/client.ts index 74f509ac42e7..8e317c2bd6b0 100644 --- a/packages/node/src/sdk/client.ts +++ b/packages/node/src/sdk/client.ts @@ -60,10 +60,9 @@ export class NodeClient extends ServerRuntimeClient { // eslint-disable-next-line jsdoc/require-jsdoc public async flush(timeout?: number): Promise { const provider = this.traceProvider; - const spanProcessor = provider?.activeSpanProcessor; - if (spanProcessor) { - await spanProcessor.forceFlush(); + if (provider) { + await provider.forceFlush(); } if (this.getOptions().sendClientReports) { diff --git a/packages/node/src/sdk/initOtel.ts b/packages/node/src/sdk/initOtel.ts index 5cd50e2711c1..e59f3879948f 100644 --- a/packages/node/src/sdk/initOtel.ts +++ b/packages/node/src/sdk/initOtel.ts @@ -1,6 +1,6 @@ import moduleModule from 'module'; import { DiagLogLevel, context, diag, propagation, trace } from '@opentelemetry/api'; -import { Resource } from '@opentelemetry/resources'; +import { defaultResource, resourceFromAttributes } from '@opentelemetry/resources'; import type { SpanProcessor } from '@opentelemetry/sdk-trace-base'; import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base'; import { @@ -112,12 +112,14 @@ export function setupOtel(client: NodeClient, options: AdditionalOpenTelemetryOp // Create and configure NodeTracerProvider const provider = new BasicTracerProvider({ sampler: new SentrySampler(client), - resource: new Resource({ - [ATTR_SERVICE_NAME]: 'node', - // eslint-disable-next-line deprecation/deprecation - [SEMRESATTRS_SERVICE_NAMESPACE]: 'sentry', - [ATTR_SERVICE_VERSION]: SDK_VERSION, - }), + resource: defaultResource().merge( + resourceFromAttributes({ + [ATTR_SERVICE_NAME]: 'node', + // eslint-disable-next-line deprecation/deprecation + [SEMRESATTRS_SERVICE_NAMESPACE]: 'sentry', + [ATTR_SERVICE_VERSION]: SDK_VERSION, + }), + ), forceFlushTimeoutMillis: 500, spanProcessors: [ new SentrySpanProcessor({ diff --git a/packages/node/src/utils/ensureIsWrapped.ts b/packages/node/src/utils/ensureIsWrapped.ts index 3a6518e7ec14..70253d9debb7 100644 --- a/packages/node/src/utils/ensureIsWrapped.ts +++ b/packages/node/src/utils/ensureIsWrapped.ts @@ -1,4 +1,4 @@ -import { isWrapped } from '@opentelemetry/core'; +import { isWrapped } from '@opentelemetry/instrumentation'; import { consoleSandbox, getClient, getGlobalScope, hasSpansEnabled, isEnabled } from '@sentry/core'; import type { NodeClient } from '../sdk/client'; import { isCjs } from './commonjs'; diff --git a/packages/opentelemetry/package.json b/packages/opentelemetry/package.json index a9460e20c248..716df2c26d20 100644 --- a/packages/opentelemetry/package.json +++ b/packages/opentelemetry/package.json @@ -43,18 +43,18 @@ }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", - "@opentelemetry/context-async-hooks": "^1.30.1", - "@opentelemetry/core": "^1.30.1", - "@opentelemetry/instrumentation": "^0.57.1", - "@opentelemetry/sdk-trace-base": "^1.30.1", + "@opentelemetry/context-async-hooks": "^2.0.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.200.0", + "@opentelemetry/sdk-trace-base": "^2.0.0", "@opentelemetry/semantic-conventions": "^1.28.0" }, "devDependencies": { "@opentelemetry/api": "^1.9.0", - "@opentelemetry/context-async-hooks": "^1.30.1", - "@opentelemetry/core": "^1.30.1", - "@opentelemetry/instrumentation": "^0.57.2", - "@opentelemetry/sdk-trace-base": "^1.30.1", + "@opentelemetry/context-async-hooks": "^2.0.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.200.0", + "@opentelemetry/sdk-trace-base": "^2.0.0", "@opentelemetry/semantic-conventions": "^1.30.0" }, "scripts": { diff --git a/packages/opentelemetry/src/custom/client.ts b/packages/opentelemetry/src/custom/client.ts index 70afb6f10752..533146263220 100644 --- a/packages/opentelemetry/src/custom/client.ts +++ b/packages/opentelemetry/src/custom/client.ts @@ -10,7 +10,7 @@ import type { OpenTelemetryClient as OpenTelemetryClientInterface } from '../typ /* eslint-disable @typescript-eslint/no-explicit-any */ /** - * Wrap an Client class with things we need for OpenTelemetry support. + * Wrap a Client class with things we need for OpenTelemetry support. * Make sure that the Client class passed in is non-abstract! * * Usage: @@ -49,10 +49,9 @@ export function wrapClientClass< */ public async flush(timeout?: number): Promise { const provider = this.traceProvider; - const spanProcessor = provider?.activeSpanProcessor; - if (spanProcessor) { - await spanProcessor.forceFlush(); + if (provider) { + await provider.forceFlush(); } return super.flush(timeout); diff --git a/packages/opentelemetry/src/spanExporter.ts b/packages/opentelemetry/src/spanExporter.ts index 90a3d890a959..799b48a72e7c 100644 --- a/packages/opentelemetry/src/spanExporter.ts +++ b/packages/opentelemetry/src/spanExporter.ts @@ -255,7 +255,7 @@ export function createTransactionForOtelSpan(span: ReadableSpan): TransactionEve // even if `span.parentSpanId` is set // this is the case when we are starting a new trace, where we have a virtual span based on the propagationContext // We only want to continue the traceId in this case, but ignore the parent span - const parent_span_id = span.parentSpanId; + const parent_span_id = span.parentSpanContext?.spanId; const status = mapStatus(span); @@ -321,8 +321,9 @@ function createAndFinishSpanForOtelSpan(node: SpanNode, spans: SpanJSON[], sentS const span_id = span.spanContext().spanId; const trace_id = span.spanContext().traceId; + const parent_span_id = span.parentSpanContext?.spanId; - const { attributes, startTime, endTime, parentSpanId, links } = span; + const { attributes, startTime, endTime, links } = span; const { op, description, data, origin = 'manual' } = getSpanData(span); const allData = { @@ -339,7 +340,7 @@ function createAndFinishSpanForOtelSpan(node: SpanNode, spans: SpanJSON[], sentS trace_id, data: allData, description, - parent_span_id: parentSpanId, + parent_span_id, start_timestamp: spanTimeInputToSeconds(startTime), // This is [0,0] by default in OTEL, in which case we want to interpret this as no end time timestamp: spanTimeInputToSeconds(endTime) || undefined, diff --git a/packages/opentelemetry/src/utils/groupSpansWithParents.ts b/packages/opentelemetry/src/utils/groupSpansWithParents.ts index ddc779e9f760..0d0daf112493 100644 --- a/packages/opentelemetry/src/utils/groupSpansWithParents.ts +++ b/packages/opentelemetry/src/utils/groupSpansWithParents.ts @@ -33,7 +33,7 @@ export function getLocalParentId(span: ReadableSpan): string | undefined { const parentIsRemote = span.attributes[SEMANTIC_ATTRIBUTE_SENTRY_PARENT_IS_REMOTE] === true; // If the parentId is the trace parent ID, we pretend it's undefined // As this means the parent exists somewhere else - return !parentIsRemote ? span.parentSpanId : undefined; + return !parentIsRemote ? span.parentSpanContext?.spanId : undefined; } function createOrUpdateSpanNodeAndRefs(nodeMap: SpanMap, span: ReadableSpan): void { diff --git a/packages/opentelemetry/src/utils/spanTypes.ts b/packages/opentelemetry/src/utils/spanTypes.ts index 39c62219d2ad..c9036d930720 100644 --- a/packages/opentelemetry/src/utils/spanTypes.ts +++ b/packages/opentelemetry/src/utils/spanTypes.ts @@ -52,11 +52,9 @@ export function spanHasName(span: SpanType): span * This is necessary because the base `Span` type does not have a kind, * so in places where we are passed a generic span, we need to check if we want to access it. */ -export function spanHasParentId( - span: SpanType, -): span is SpanType & { parentSpanId: string } { +export function spanHasParentId(span: SpanType): span is SpanType { const castSpan = span as ReadableSpan; - return !!castSpan.parentSpanId; + return !!castSpan.parentSpanContext?.spanId; } /** diff --git a/packages/opentelemetry/test/helpers/initOtel.ts b/packages/opentelemetry/test/helpers/initOtel.ts index 121ca0181892..b94d778d59f5 100644 --- a/packages/opentelemetry/test/helpers/initOtel.ts +++ b/packages/opentelemetry/test/helpers/initOtel.ts @@ -1,6 +1,6 @@ import { DiagLogLevel, context, diag, propagation, trace } from '@opentelemetry/api'; import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks'; -import { Resource } from '@opentelemetry/resources'; +import { defaultResource, resourceFromAttributes } from '@opentelemetry/resources'; import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base'; import { ATTR_SERVICE_NAME, @@ -56,12 +56,14 @@ export function setupOtel(client: TestClientInterface): BasicTracerProvider { // Create and configure NodeTracerProvider const provider = new BasicTracerProvider({ sampler: new SentrySampler(client), - resource: new Resource({ - [ATTR_SERVICE_NAME]: 'opentelemetry-test', - // eslint-disable-next-line deprecation/deprecation - [SEMRESATTRS_SERVICE_NAMESPACE]: 'sentry', - [ATTR_SERVICE_VERSION]: SDK_VERSION, - }), + resource: defaultResource().merge( + resourceFromAttributes({ + [ATTR_SERVICE_NAME]: 'opentelemetry-test', + // eslint-disable-next-line deprecation/deprecation + [SEMRESATTRS_SERVICE_NAMESPACE]: 'sentry', + [ATTR_SERVICE_VERSION]: SDK_VERSION, + }), + ), forceFlushTimeoutMillis: 500, spanProcessors: [new SentrySpanProcessor()], }); diff --git a/packages/opentelemetry/test/helpers/isSpan.ts b/packages/opentelemetry/test/helpers/isSpan.ts new file mode 100644 index 000000000000..3146551e3da7 --- /dev/null +++ b/packages/opentelemetry/test/helpers/isSpan.ts @@ -0,0 +1,12 @@ +import type { Span } from '@opentelemetry/api'; +import { INVALID_TRACEID, INVALID_SPANID, type SpanContext } from '@opentelemetry/api'; + +export const isSpan = (value: unknown): value is Span => { + return ( + typeof value === 'object' && + value !== null && + 'spanContext' in value && + (value.spanContext as () => SpanContext)().traceId !== INVALID_TRACEID && + (value.spanContext as () => SpanContext)().spanId !== INVALID_SPANID + ); +}; diff --git a/packages/opentelemetry/test/helpers/mockSdkInit.ts b/packages/opentelemetry/test/helpers/mockSdkInit.ts index 0bcf1b101896..c5787296953b 100644 --- a/packages/opentelemetry/test/helpers/mockSdkInit.ts +++ b/packages/opentelemetry/test/helpers/mockSdkInit.ts @@ -7,8 +7,8 @@ import { getCurrentScope, getGlobalScope, getIsolationScope, flush } from '@sent import { setOpenTelemetryContextAsyncContextStrategy } from '../../src/asyncContextStrategy'; import { clearOpenTelemetrySetupCheck } from '../../src/utils/setupCheck'; import { init as initTestClient } from './TestClient'; +import type { TestClientInterface } from './TestClient'; import { initOtel } from './initOtel'; -import type { OpenTelemetryClient } from '../../src/types'; const PUBLIC_DSN = 'https://username@domain/123'; @@ -54,7 +54,7 @@ export async function cleanupOtel(_provider?: BasicTracerProvider): Promise()?.traceProvider || trace.getTracerProvider(); + let provider = _provider || getClient()?.traceProvider || trace.getTracerProvider(); if (provider instanceof ProxyTracerProvider) { provider = provider.getDelegate(); diff --git a/packages/opentelemetry/test/trace.test.ts b/packages/opentelemetry/test/trace.test.ts index a820e7502929..daca1df6f15c 100644 --- a/packages/opentelemetry/test/trace.test.ts +++ b/packages/opentelemetry/test/trace.test.ts @@ -4,7 +4,6 @@ import { ROOT_CONTEXT } from '@opentelemetry/api'; import { SpanKind } from '@opentelemetry/api'; import { TraceFlags, context, trace } from '@opentelemetry/api'; import type { ReadableSpan } from '@opentelemetry/sdk-trace-base'; -import { Span as SpanClass } from '@opentelemetry/sdk-trace-base'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, @@ -32,6 +31,7 @@ import { getSpanKind } from '../src/utils/getSpanKind'; import { makeTraceState } from '../src/utils/makeTraceState'; import { spanHasAttributes, spanHasName } from '../src/utils/spanTypes'; import { cleanupOtel, mockSdkInit } from './helpers/mockSdkInit'; +import { isSpan } from './helpers/isSpan'; describe('trace', () => { beforeEach(() => { @@ -537,7 +537,7 @@ describe('trace', () => { return span; }); - expect(span).not.toBeInstanceOf(SpanClass); + expect(isSpan(span)).toEqual(false); }); it('creates a span if there is a parent', () => { @@ -549,7 +549,7 @@ describe('trace', () => { return span; }); - expect(span).toBeInstanceOf(SpanClass); + expect(isSpan(span)).toEqual(true); }); }); }); @@ -829,7 +829,7 @@ describe('trace', () => { it('does not create a span if there is no parent', () => { const span = startInactiveSpan({ name: 'test span', onlyIfParent: true }); - expect(span).not.toBeInstanceOf(SpanClass); + expect(isSpan(span)).toEqual(false); }); it('creates a span if there is a parent', () => { @@ -839,7 +839,7 @@ describe('trace', () => { return span; }); - expect(span).toBeInstanceOf(SpanClass); + expect(isSpan(span)).toEqual(true); }); }); @@ -1199,7 +1199,7 @@ describe('trace', () => { return span; }); - expect(span).not.toBeInstanceOf(SpanClass); + expect(isSpan(span)).toEqual(false); }); it('creates a span if there is a parent', () => { @@ -1211,7 +1211,7 @@ describe('trace', () => { return span; }); - expect(span).toBeInstanceOf(SpanClass); + expect(isSpan(span)).toEqual(true); }); }); }); @@ -1928,5 +1928,5 @@ function getSpanAttributes(span: AbstractSpan): Record | undefi } function getSpanParentSpanId(span: AbstractSpan): string | undefined { - return (span as ReadableSpan).parentSpanId; + return (span as ReadableSpan).parentSpanContext?.spanId; } diff --git a/packages/opentelemetry/test/utils/setupCheck.test.ts b/packages/opentelemetry/test/utils/setupCheck.test.ts index 53d8437e119a..bc66c2eebaa2 100644 --- a/packages/opentelemetry/test/utils/setupCheck.test.ts +++ b/packages/opentelemetry/test/utils/setupCheck.test.ts @@ -36,10 +36,8 @@ describe('openTelemetrySetupCheck', () => { const client = new TestClient(getDefaultTestClientOptions()); provider = new BasicTracerProvider({ sampler: new SentrySampler(client), + spanProcessors: [new SentrySpanProcessor()], }); - // We want to test this deprecated case also works - // eslint-disable-next-line deprecation/deprecation - provider.addSpanProcessor(new SentrySpanProcessor()); const setup = openTelemetrySetupCheck(); expect(setup).toEqual(['SentrySampler', 'SentrySpanProcessor']); diff --git a/packages/opentelemetry/test/utils/spanTypes.test.ts b/packages/opentelemetry/test/utils/spanTypes.test.ts index 1849f24ce412..7eedd3d68a81 100644 --- a/packages/opentelemetry/test/utils/spanTypes.test.ts +++ b/packages/opentelemetry/test/utils/spanTypes.test.ts @@ -43,8 +43,8 @@ describe('spanTypes', () => { describe('spanHasParentId', () => { it.each([ [{}, false], - [{ parentSpanId: null }, false], - [{ parentSpanId: 'TEST_PARENT_ID' }, true], + [{ parentSpanContext: { spanId: null } }, false], + [{ parentSpanContext: { spanId: 'TEST_PARENT_ID' } }, true], ])('works with %p', (span, expected) => { const castSpan = span as unknown as Span; const actual = spanHasParentId(castSpan); @@ -52,7 +52,7 @@ describe('spanTypes', () => { expect(actual).toBe(expected); if (actual) { - expect(castSpan.parentSpanId).toBeDefined(); + expect(castSpan.parentSpanContext?.spanId).toBeDefined(); } }); }); diff --git a/packages/vercel-edge/package.json b/packages/vercel-edge/package.json index c3c9f8b7a967..6d8fb786d7be 100644 --- a/packages/vercel-edge/package.json +++ b/packages/vercel-edge/package.json @@ -44,9 +44,9 @@ }, "devDependencies": { "@edge-runtime/types": "3.0.1", - "@opentelemetry/core": "^1.30.1", - "@opentelemetry/resources": "^1.30.1", - "@opentelemetry/sdk-trace-base": "^1.30.1", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0", + "@opentelemetry/sdk-trace-base": "^2.0.0", "@opentelemetry/semantic-conventions": "^1.28.0", "@sentry/opentelemetry": "9.10.1" }, diff --git a/packages/vercel-edge/src/client.ts b/packages/vercel-edge/src/client.ts index 09987eacd030..469ed82b3da8 100644 --- a/packages/vercel-edge/src/client.ts +++ b/packages/vercel-edge/src/client.ts @@ -41,10 +41,9 @@ export class VercelEdgeClient extends ServerRuntimeClient { const provider = this.traceProvider; - const spanProcessor = provider?.activeSpanProcessor; - if (spanProcessor) { - await spanProcessor.forceFlush(); + if (provider) { + await provider.forceFlush(); } if (this.getOptions().sendClientReports) { diff --git a/packages/vercel-edge/src/sdk.ts b/packages/vercel-edge/src/sdk.ts index 8c3939d26cba..b327ee8b8fc1 100644 --- a/packages/vercel-edge/src/sdk.ts +++ b/packages/vercel-edge/src/sdk.ts @@ -1,5 +1,5 @@ import { DiagLogLevel, context, diag, propagation, trace } from '@opentelemetry/api'; -import { Resource } from '@opentelemetry/resources'; +import { defaultResource, resourceFromAttributes } from '@opentelemetry/resources'; import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base'; import { ATTR_SERVICE_NAME, @@ -155,12 +155,14 @@ export function setupOtel(client: VercelEdgeClient): void { // Create and configure NodeTracerProvider const provider = new BasicTracerProvider({ sampler: new SentrySampler(client), - resource: new Resource({ - [ATTR_SERVICE_NAME]: 'edge', - // eslint-disable-next-line deprecation/deprecation - [SEMRESATTRS_SERVICE_NAMESPACE]: 'sentry', - [ATTR_SERVICE_VERSION]: SDK_VERSION, - }), + resource: defaultResource().merge( + resourceFromAttributes({ + [ATTR_SERVICE_NAME]: 'edge', + // eslint-disable-next-line deprecation/deprecation + [SEMRESATTRS_SERVICE_NAMESPACE]: 'sentry', + [ATTR_SERVICE_VERSION]: SDK_VERSION, + }), + ), forceFlushTimeoutMillis: 500, spanProcessors: [ new SentrySpanProcessor({ diff --git a/yarn.lock b/yarn.lock index 27c0b61bb063..202e7d9d5a8a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5420,6 +5420,13 @@ dependencies: "@octokit/openapi-types" "^18.0.0" +"@opentelemetry/api-logs@0.200.0": + version "0.200.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.200.0.tgz#f9015fd844920c13968715b3cdccf5a4d4ff907e" + integrity sha512-IKJBQxh91qJ+3ssRly5hYEJ8NDHu9oY/B1PXVSCWf7zytmYO9RNLB0Ox9XQ/fJ8m6gY6Q6NtBWlmXfaXt5Uc4Q== + dependencies: + "@opentelemetry/api" "^1.3.0" + "@opentelemetry/api-logs@0.52.1": version "0.52.1" resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.52.1.tgz#52906375da4d64c206b0c4cb8ffa209214654ecc" @@ -5439,12 +5446,19 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe" integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg== -"@opentelemetry/context-async-hooks@^1.30.1": - version "1.30.1" - resolved "https://registry.yarnpkg.com/@opentelemetry/context-async-hooks/-/context-async-hooks-1.30.1.tgz#4f76280691a742597fd0bf682982126857622948" - integrity sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA== +"@opentelemetry/context-async-hooks@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/context-async-hooks/-/context-async-hooks-2.0.0.tgz#c98a727238ca199cda943780acf6124af8d8cd80" + integrity sha512-IEkJGzK1A9v3/EHjXh3s2IiFc6L4jfK+lNgKVgUjeUJQRRhnVFMIO3TAvKwonm9O1HebCuoOt98v8bZW7oVQHA== + +"@opentelemetry/core@2.0.0", "@opentelemetry/core@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-2.0.0.tgz#37e9f0e9ddec4479b267aca6f32d88757c941b3a" + integrity sha512-SLX36allrcnVaPYG3R78F/UZZsBsvbc7lMCLx37LyH5MJ1KAAZ2E3mW9OAD3zGz0G8q/BtoS5VUrjzDydhD6LQ== + dependencies: + "@opentelemetry/semantic-conventions" "^1.29.0" -"@opentelemetry/core@1.30.1", "@opentelemetry/core@^1.1.0", "@opentelemetry/core@^1.26.0", "@opentelemetry/core@^1.30.1", "@opentelemetry/core@^1.8.0": +"@opentelemetry/core@^1.1.0", "@opentelemetry/core@^1.26.0", "@opentelemetry/core@^1.8.0": version "1.30.1" resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.30.1.tgz#a0b468bb396358df801881709ea38299fc30ab27" integrity sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ== @@ -5545,16 +5559,15 @@ "@opentelemetry/instrumentation" "^0.57.1" "@opentelemetry/semantic-conventions" "^1.27.0" -"@opentelemetry/instrumentation-http@0.57.2": - version "0.57.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-http/-/instrumentation-http-0.57.2.tgz#f425eda67b6241c3abe08e4ea972169b85ef3064" - integrity sha512-1Uz5iJ9ZAlFOiPuwYg29Bf7bJJc/GeoeJIFKJYQf67nTVKFe8RHbEtxgkOmK4UGZNHKXcpW4P8cWBYzBn1USpg== +"@opentelemetry/instrumentation-http@0.200.0": + version "0.200.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-http/-/instrumentation-http-0.200.0.tgz#b5bda869afad4e6933120c34c98e201d5b6e0a24" + integrity sha512-9tqGbCJikhYU68y3k9mi6yWsMyMeCcwoQuHvIXan5VvvPPQ5WIZaV6Mxu/MCVe4swRNoFs8Th+qyj0TZV5ELvw== dependencies: - "@opentelemetry/core" "1.30.1" - "@opentelemetry/instrumentation" "0.57.2" - "@opentelemetry/semantic-conventions" "1.28.0" + "@opentelemetry/core" "2.0.0" + "@opentelemetry/instrumentation" "0.200.0" + "@opentelemetry/semantic-conventions" "^1.29.0" forwarded-parse "2.1.2" - semver "^7.5.2" "@opentelemetry/instrumentation-ioredis@0.47.1": version "0.47.1" @@ -5678,7 +5691,18 @@ "@opentelemetry/core" "^1.8.0" "@opentelemetry/instrumentation" "^0.57.1" -"@opentelemetry/instrumentation@0.57.2", "@opentelemetry/instrumentation@^0.52.0 || ^0.53.0 || ^0.54.0 || ^0.55.0 || ^0.56.0 || ^0.57.0", "@opentelemetry/instrumentation@^0.57.1", "@opentelemetry/instrumentation@^0.57.2": +"@opentelemetry/instrumentation@0.200.0", "@opentelemetry/instrumentation@^0.200.0": + version "0.200.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.200.0.tgz#29d1d4f70cbf0cb1ca9f2f78966379b0be96bddc" + integrity sha512-pmPlzfJd+vvgaZd/reMsC8RWgTXn2WY1OWT5RT42m3aOn5532TozwXNDhg1vzqJ+jnvmkREcdLr27ebJEQt0Jg== + dependencies: + "@opentelemetry/api-logs" "0.200.0" + "@types/shimmer" "^1.2.0" + import-in-the-middle "^1.8.1" + require-in-the-middle "^7.1.1" + shimmer "^1.2.1" + +"@opentelemetry/instrumentation@^0.52.0 || ^0.53.0 || ^0.54.0 || ^0.55.0 || ^0.56.0 || ^0.57.0", "@opentelemetry/instrumentation@^0.57.1": version "0.57.2" resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz#8924549d7941ba1b5c6f04d5529cf48330456d1d" integrity sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg== @@ -5712,29 +5736,29 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/redis-common/-/redis-common-0.36.2.tgz#906ac8e4d804d4109f3ebd5c224ac988276fdc47" integrity sha512-faYX1N0gpLhej/6nyp6bgRjzAKXn5GOEMYY7YhciSfCoITAktLUtQ36d24QEWNA1/WA1y6qQunCe0OhHRkVl9g== -"@opentelemetry/resources@1.30.1", "@opentelemetry/resources@^1.30.1": - version "1.30.1" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.30.1.tgz#a4eae17ebd96947fdc7a64f931ca4b71e18ce964" - integrity sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA== +"@opentelemetry/resources@2.0.0", "@opentelemetry/resources@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-2.0.0.tgz#15c04794c32b7d0b3c7589225ece6ae9bba25989" + integrity sha512-rnZr6dML2z4IARI4zPGQV4arDikF/9OXZQzrC01dLmn0CZxU5U5OLd/m1T7YkGRj5UitjeoCtg/zorlgMQcdTg== dependencies: - "@opentelemetry/core" "1.30.1" - "@opentelemetry/semantic-conventions" "1.28.0" + "@opentelemetry/core" "2.0.0" + "@opentelemetry/semantic-conventions" "^1.29.0" -"@opentelemetry/sdk-trace-base@^1.30.1": - version "1.30.1" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.30.1.tgz#41a42234096dc98e8f454d24551fc80b816feb34" - integrity sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg== +"@opentelemetry/sdk-trace-base@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.0.0.tgz#ebc06ea7537dea62f3882f8236c1234f4faf6b23" + integrity sha512-qQnYdX+ZCkonM7tA5iU4fSRsVxbFGml8jbxOgipRGMFHKaXKHQ30js03rTobYjKjIfnOsZSbHKWF0/0v0OQGfw== dependencies: - "@opentelemetry/core" "1.30.1" - "@opentelemetry/resources" "1.30.1" - "@opentelemetry/semantic-conventions" "1.28.0" + "@opentelemetry/core" "2.0.0" + "@opentelemetry/resources" "2.0.0" + "@opentelemetry/semantic-conventions" "^1.29.0" "@opentelemetry/semantic-conventions@1.28.0": version "1.28.0" resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz#337fb2bca0453d0726696e745f50064411f646d6" integrity sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA== -"@opentelemetry/semantic-conventions@^1.25.1", "@opentelemetry/semantic-conventions@^1.27.0", "@opentelemetry/semantic-conventions@^1.28.0", "@opentelemetry/semantic-conventions@^1.30.0": +"@opentelemetry/semantic-conventions@^1.25.1", "@opentelemetry/semantic-conventions@^1.27.0", "@opentelemetry/semantic-conventions@^1.28.0", "@opentelemetry/semantic-conventions@^1.29.0", "@opentelemetry/semantic-conventions@^1.30.0": version "1.30.0" resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.30.0.tgz#3a42c4c475482f2ec87c12aad98832dc0087dc9a" integrity sha512-4VlGgo32k2EQ2wcCY3vEU28A0O13aOtHz3Xt2/2U5FAh9EfhD6t6DqL5Z6yAnRCntbTFDU4YfbpyzSlHNWycPw==