Skip to content
Open
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
16 changes: 15 additions & 1 deletion packages/cloudflare/src/opentelemetry/tracer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Context, Span, SpanOptions, Tracer, TracerProvider } from '@opentelemetry/api';
import type { Context, Link, Span, SpanOptions, Tracer, TracerProvider } from '@opentelemetry/api';
import { trace } from '@opentelemetry/api';
import { startInactiveSpan, startSpanManual } from '@sentry/core';
import type { SpanLink } from '@sentry/core';

/**
* Set up a mock OTEL tracer to allow inter-op with OpenTelemetry emitted spans.
Expand Down Expand Up @@ -28,6 +29,7 @@ class SentryCloudflareTracer implements Tracer {
public startSpan(name: string, options?: SpanOptions): Span {
return startInactiveSpan({
...options,
links: convertSpanLinkType(options?.links),
name,
attributes: {
...options?.attributes,
Expand Down Expand Up @@ -57,6 +59,7 @@ class SentryCloudflareTracer implements Tracer {

const spanOpts = {
...opts,
links: convertSpanLinkType(opts.links),
name,
attributes: {
...opts.attributes,
Expand All @@ -78,3 +81,14 @@ class SentryCloudflareTracer implements Tracer {
return startSpanManual(spanOpts, callback) as ReturnType<F>;
}
}

/**
* Converts OpenTelemetry span links to Sentry span links.
*
* Since `@opentelemetry/api` 1.10.0, link attribute values are typed as `unknown`.
* Sentry's `SpanLink` only accepts strings, numbers, booleans and arrays of these as attribute values,
* so OTel links do not match its type.
*/
function convertSpanLinkType(links: Link[] | undefined): SpanLink[] | undefined {
return links as SpanLink[] | undefined;
}
16 changes: 15 additions & 1 deletion packages/deno/src/opentelemetry/tracer.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { Context, Span, SpanOptions, Tracer, TracerProvider } from '@opentelemetry/api';
import type { Context, Link, Span, SpanOptions, Tracer, TracerProvider } from '@opentelemetry/api';
import { SpanKind, trace } from '@opentelemetry/api';
import {
SEMANTIC_ATTRIBUTE_SENTRY_OP,
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
startInactiveSpan,
startSpanManual,
} from '@sentry/core';
import type { SpanLink } from '@sentry/core';

/**
* Set up a mock OTEL tracer to allow inter-op with OpenTelemetry emitted spans.
Expand Down Expand Up @@ -39,6 +40,7 @@ class SentryDenoTracer implements Tracer {

return startInactiveSpan({
...options,
links: convertSpanLinkType(options?.links),
name,
attributes: {
...options?.attributes,
Expand Down Expand Up @@ -73,6 +75,7 @@ class SentryDenoTracer implements Tracer {

const spanOpts = {
...opts,
links: convertSpanLinkType(opts.links),
name,
attributes: {
...opts.attributes,
Expand Down Expand Up @@ -111,3 +114,14 @@ class SentryDenoTracer implements Tracer {
}
}
}

/**
* Converts OpenTelemetry span links to Sentry span links.
*
* Since `@opentelemetry/api` 1.10.0, link attribute values are typed as `unknown`.
* Sentry's `SpanLink` only accepts strings, numbers, booleans and arrays of these as attribute values,
* so OTel links do not match its type.
*/
function convertSpanLinkType(links: Link[] | undefined): SpanLink[] | undefined {
return links as SpanLink[] | undefined;
}
4 changes: 2 additions & 2 deletions packages/opentelemetry/src/resource.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Attributes, AttributeValue } from '@opentelemetry/api';
import type { Attributes } from '@opentelemetry/api';
import { SDK_INFO } from '@opentelemetry/core';
import { SERVICE_NAME, SERVICE_VERSION } from '@sentry/conventions/attributes';
import { SDK_VERSION } from '@sentry/core';
Expand All @@ -13,7 +13,7 @@ const ATTR_TELEMETRY_SDK_NAME = 'telemetry.sdk.name';
const ATTR_TELEMETRY_SDK_VERSION = 'telemetry.sdk.version';
const SEMRESATTRS_SERVICE_NAMESPACE = 'service.namespace';

type RawResourceAttribute = [string, AttributeValue | undefined];
type RawResourceAttribute = [string, Attributes[string]];

/**
* Minimal Resource implementation that satisfies the OpenTelemetry Resource interface
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;
Comment thread
andreiborza marked this conversation as resolved.
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
10 changes: 6 additions & 4 deletions packages/opentelemetry/src/spanExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import { HTTP_RESPONSE_STATUS_CODE, HTTP_STATUS_CODE } from '@sentry/conventions
import type {
SpanAttributes,
SpanJSON,
SpanLink,
SpanOrigin,
TimedEvent,
TraceContext,
TransactionEvent,
TransactionSource,
Expand Down Expand Up @@ -222,7 +224,7 @@ export class SentrySpanExporter {
};
}

const measurements = timedEventsToMeasurements(span.events);
const measurements = timedEventsToMeasurements(span.events as TimedEvent[]);
if (measurements) {
transactionEvent.measurements = measurements;
}
Expand Down Expand Up @@ -292,7 +294,7 @@ export function createTransactionForOtelSpan(span: ReadableSpan): TransactionEve
origin,
op,
status: getStatusMessage(status), // As per protocol, span status is allowed to be undefined
links: convertSpanLinksForEnvelope(links),
links: convertSpanLinksForEnvelope(links as SpanLink[]),
};

const statusCode = attributes[HTTP_RESPONSE_STATUS_CODE];
Expand Down Expand Up @@ -378,8 +380,8 @@ function createAndFinishSpanForOtelSpan(node: SpanNode, spans: SpanJSON[], sentS
status: getStatusMessage(status), // As per protocol, span status is allowed to be undefined
op,
origin,
measurements: timedEventsToMeasurements(span.events),
links: convertSpanLinksForEnvelope(links),
measurements: timedEventsToMeasurements(span.events as TimedEvent[]),
links: convertSpanLinksForEnvelope(links as SpanLink[]),
};

spans.push(spanJSON);
Expand Down
7 changes: 3 additions & 4 deletions packages/opentelemetry/src/tracerProvider.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import type { Tracer, TracerOptions, TracerProvider } from '@opentelemetry/api';
import type { SpanAttributes } from '@sentry/core';
import type { Attributes, Tracer, TracerOptions, TracerProvider } from '@opentelemetry/api';
import { SentryTracer } from './tracer';

/**
* A minimal OpenTelemetry TracerProvider which creates native Sentry spans.
*/
export class SentryTracerProvider implements TracerProvider {
public readonly resource?: { attributes: SpanAttributes };
public readonly resource?: { attributes: Attributes };

private readonly _tracers = new Map<string, SentryTracer>();

public constructor(options: { resource?: { attributes: SpanAttributes } } = {}) {
public constructor(options: { resource?: { attributes: Attributes } } = {}) {
this.resource = options.resource;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/opentelemetry/src/utils/mapStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const isStatusErrorMessageValid = (message: string): boolean => {
* Get a Sentry span status from an otel span.
*/
export function mapStatus(span: AbstractSpan): SpanStatus {
const attributes = spanHasAttributes(span) ? span.attributes : {};
const attributes = (spanHasAttributes(span) ? span.attributes : {}) as SpanAttributes;
const status = spanHasStatus(span) ? span.status : undefined;

if (status) {
Expand Down
8 changes: 4 additions & 4 deletions packages/opentelemetry/src/utils/parseSpanDescription.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Attributes, AttributeValue } from '@opentelemetry/api';
import type { Attributes } from '@opentelemetry/api';
import { SpanKind } from '@opentelemetry/api';
import {
DB_STATEMENT,
Expand Down Expand Up @@ -123,7 +123,7 @@ export function parseSpanDescription(span: AbstractSpan): SpanDescription {
}

const kind = getSpanKind(span);
return inferSpanData(name, attributes, kind);
return inferSpanData(name, attributes as SpanAttributes, kind);
}

function descriptionForDbSystem({ attributes, name }: { attributes: Attributes; name: string }): SpanDescription {
Expand Down Expand Up @@ -154,7 +154,7 @@ function descriptionForDbSystem({ attributes, name }: { attributes: Attributes;
/** Only exported for tests. */
export function descriptionForHttpMethod(
{ name, kind, attributes }: { name: string; attributes: Attributes; kind: SpanKind },
httpMethod: AttributeValue,
httpMethod: NonNullable<Attributes[string]>,
): SpanDescription {
const opParts = ['http'];

Expand Down Expand Up @@ -238,7 +238,7 @@ export function descriptionForHttpMethod(
};
}

function getGraphqlOperationNamesFromAttribute(attr: AttributeValue): string {
function getGraphqlOperationNamesFromAttribute(attr: NonNullable<Attributes[string]>): string {
if (Array.isArray(attr)) {
// oxlint-disable-next-line typescript/require-array-sort-compare
const sorted = attr.slice().sort();
Expand Down
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5907,9 +5907,9 @@
integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==

"@opentelemetry/api@^1.3.0", "@opentelemetry/api@^1.9.0", "@opentelemetry/api@^1.9.1":
version "1.9.1"
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.1.tgz#c1b0346de336ba55af2d5a7970882037baedec05"
integrity sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==
version "1.10.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.10.0.tgz#31d2e3d36ffc6cdd5ce165251e7fa13bbad0fd8a"
integrity sha512-lMkyes8iHrG+mk6WH7X70MdCLI2RS0FwNBY1PyQ8UemaijE2m5mv5A0Niy3HtbYTFrgkUEQjFMXmSAk2hQDuPQ==

"@opentelemetry/core@2.9.0", "@opentelemetry/core@^2.9.0":
version "2.9.0"
Expand Down
Loading