Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"test:assert": "pnpm test"
},
"dependencies": {
"@opentelemetry/api": "1.9.0",
"@opentelemetry/api": "^1.10.0",
"@opentelemetry/sdk-trace-node": "2.6.1",
"@opentelemetry/exporter-trace-otlp-http": "0.214.0",
"@opentelemetry/instrumentation-undici": "0.24.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { exec } from 'child_process';
import { existsSync } from 'fs';
import { existsSync, readFileSync } from 'fs';
import { cp, mkdir, readFile, rm, writeFile } from 'fs/promises';
import { basename, join } from 'path';
import { basename, dirname, join } from 'path';
import { promisify } from 'util';
import { afterAll, beforeAll, test, type TestAPI } from 'vitest';
import { CLEANUP_STEPS, createRunner } from './createRunner';
Expand Down Expand Up @@ -292,6 +292,9 @@ experimentalUseDiagnosticsChannelInjection();`,
private: true,
version: '0.0.0',
dependencies: additionalDependencies,
// Packages like `ai` depend on `@opentelemetry/api` themselves. If npm resolves a newer minor than the SDK's
// copy, the newer copy refuses the globals registered by the older one and the package's spans are dropped.
overrides: additionalDependencies['@opentelemetry/api'] ? {} : { '@opentelemetry/api': getSdkOtelApiVersion() },

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this is weird, can we avoid this. either we bump the installed version locally (while keeping the version as ^1.9.0) or something else, if needed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Tried the lockfile route: resolving the monorepo's @opentelemetry/api@^1.9.x to 1.10.0 (ranges unchanged) and dropping this override. It's not a drop-in on v10: 1.10 widens Attributes/AnyValue and the SDK's own build:types starts failing, e.g.

  • @sentry/opentelemetry: mapStatus.ts, parseSpanDescription.ts (Attributes → SpanAttributes), spanExporter.ts (TimedEvent[], Link[] → SpanLink[])
  • @sentry/deno / @sentry/cloudflare: opentelemetry/tracer.ts (StartSpanOptions)

So bumping locally means a type migration across several packages on v10, which feels out of scope for unblocking CI (and the OTel 2.x SDK packages still declare @opentelemetry/api <1.10.0 as peer).

Alternative that avoids the runner magic: drop the override here and instead pin '@opentelemetry/api': '~1.9.0' explicitly in the Vercel AI v6 tests' additionalDependencies, scoped to the only suites affected (ai@6 is the only additionalDependency pulling its own copy; ai@7 has none). Happy to go with either that or the full 1.10 migration — which do you prefer?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we still need this now that we bumped the node-otel-without-tracing app to ^1.10.0?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, they're independent:

  • node-otel-without-tracing is an E2E app. It has its own pnpm install with the packed tarballs, so bumping its range only affects that app.
  • This override is for the node-integration-tests. They run the SDK from the monorepo's yarn install, which is still on @opentelemetry/api@1.9.1. Only the ai@6 tmp install pulls in 1.10.0 here, and that bump doesn't change it.

Locally, span-streaming-v6 fails 6/6 without this change (the main span container has no AI spans) and passes 6/6 with it.

The open question is still mydea's, above: keep this generic pin, or replace it with an explicit '@opentelemetry/api': '~1.9.0' in the Vercel AI v6 tests' additionalDependencies. Bumping the monorepo to 1.10 instead would also break the SDK's build:types.

} as const;

await writeFile(join(tmpDirPath, 'package.json'), JSON.stringify(packageJson, null, 2));
Expand Down Expand Up @@ -369,6 +372,22 @@ function convertEsmToCjs(content: string): string {
return newContent;
}

function getSdkOtelApiVersion(): string {
const otelApiEntry = require.resolve('@opentelemetry/api', { paths: [dirname(require.resolve('@sentry/node'))] });
let dir = dirname(otelApiEntry);
while (dir !== dirname(dir)) {
const packageJsonPath = join(dir, 'package.json');
if (existsSync(packageJsonPath)) {
const { name, version } = JSON.parse(readFileSync(packageJsonPath, 'utf8')) as { name?: string; version: string };
if (name === '@opentelemetry/api') {
return version;
}
}
dir = dirname(dir);
}
throw new Error(`Could not find the @opentelemetry/api version used by @sentry/node (resolved ${otelApiEntry})`);
}

const NPM_INSTALL_MAX_RETRIES = 3;
const NPM_INSTALL_RETRY_DELAY_MS = 2_000;

Expand Down
8 changes: 5 additions & 3 deletions packages/opentelemetry/src/sampler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable complexity */
import type { Context, Span, TraceState as TraceStateInterface } from '@opentelemetry/api';
import type { Attributes, Context, Span, TraceState as TraceStateInterface } from '@opentelemetry/api';
import { isSpanContextValid, SpanKind, trace } from '@opentelemetry/api';
import { TraceState } from './utils/TraceState';
import type { Sampler, SamplingResult } from '@opentelemetry/sdk-trace-base';
Expand Down Expand Up @@ -277,7 +277,9 @@ export function wrapSamplingDecision({
}: {
decision: SamplingDecision | undefined;
context: Context;
spanAttributes: SpanAttributes;
// Typed as OTel `Attributes` so custom samplers can pass their `shouldSample` attributes through,
// whichever `@opentelemetry/api` version they use (1.10 widened attribute values to `AnyValue`).
spanAttributes: Attributes;
sampleRand?: number;
downstreamTraceSampleRate?: number;
// flags for ignored streamed spans (only set for span streaming)
Expand Down Expand Up @@ -319,7 +321,7 @@ export function wrapSamplingDecision({
return { decision, traceState };
}

function getBaseTraceState(context: Context, spanAttributes: SpanAttributes): TraceStateInterface {
function getBaseTraceState(context: Context, spanAttributes: Attributes): TraceStateInterface {
const parentSpan = trace.getSpan(context);
const parentContext = parentSpan?.spanContext();

Expand Down
Loading