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
1 change: 0 additions & 1 deletion packages/opentelemetry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ Note that `@sentry/opentelemetry` depends on the following peer dependencies:

- `@opentelemetry/api` version `1.0.0` or greater
- `@opentelemetry/core` version `1.0.0` or greater
- `@opentelemetry/semantic-conventions` version `1.0.0` or greater
- `@opentelemetry/sdk-trace-base` version `1.0.0` or greater, or a package that implements that, like
`@opentelemetry/sdk-node`.

Expand Down
7 changes: 3 additions & 4 deletions packages/opentelemetry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,18 @@
"access": "public"
},
"dependencies": {
"@sentry/conventions": "^0.12.0",
"@sentry/core": "10.58.0"
},
"peerDependencies": {
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/core": "^1.30.1 || ^2.1.0",
"@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0",
"@opentelemetry/semantic-conventions": "^1.39.0"
"@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0"
},
"devDependencies": {
"@opentelemetry/api": "^1.9.1",
"@opentelemetry/core": "^2.6.1",
"@opentelemetry/sdk-trace-base": "^2.6.1",
"@opentelemetry/semantic-conventions": "^1.40.0"
"@opentelemetry/sdk-trace-base": "^2.6.1"
},
"scripts": {
"build": "run-p build:transpile build:types",
Expand Down
6 changes: 3 additions & 3 deletions packages/opentelemetry/src/propagator.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Baggage, Context, Span, SpanContext, TextMapGetter, TextMapSetter } from '@opentelemetry/api';
import { context, INVALID_TRACEID, propagation, trace, TraceFlags } from '@opentelemetry/api';
import { isTracingSuppressed, W3CBaggagePropagator } from '@opentelemetry/core';
import { ATTR_URL_FULL, SEMATTRS_HTTP_URL } from '@opentelemetry/semantic-conventions';
import { HTTP_URL, URL_FULL } from '@sentry/conventions/attributes';
import type { Client, continueTrace, DynamicSamplingContext, Scope } from '@sentry/core';
import {
baggageHeaderToDynamicSamplingContext,
Expand Down Expand Up @@ -275,9 +275,9 @@ function getExistingSentryTrace(carrier: unknown): string | string[] | undefined
*/
function getCurrentURL(span: Span): string | undefined {
const spanData = spanToJSON(span).data;
// `ATTR_URL_FULL` is the new attribute, but we still support the old one, `SEMATTRS_HTTP_URL`, for now.
// `URL_FULL` is the new attribute, but we still support the old one, `HTTP_URL`, for now.
// eslint-disable-next-line typescript/no-deprecated
const urlAttribute = spanData[SEMATTRS_HTTP_URL] || spanData[ATTR_URL_FULL];
const urlAttribute = spanData[HTTP_URL] || spanData[URL_FULL];
if (typeof urlAttribute === 'string') {
return urlAttribute;
}
Expand Down
25 changes: 14 additions & 11 deletions packages/opentelemetry/src/resource.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import type { Attributes, AttributeValue } from '@opentelemetry/api';
import { SDK_INFO } from '@opentelemetry/core';
import {
ATTR_SERVICE_NAME,
ATTR_SERVICE_VERSION,
ATTR_TELEMETRY_SDK_LANGUAGE,
ATTR_TELEMETRY_SDK_NAME,
ATTR_TELEMETRY_SDK_VERSION,
SEMRESATTRS_SERVICE_NAMESPACE,
} from '@opentelemetry/semantic-conventions';
import { SERVICE_NAME, SERVICE_VERSION } from '@sentry/conventions/attributes';
import { SDK_VERSION } from '@sentry/core';

// These resource attributes are not part of `@sentry/conventions`, so we inline the
// stable OTel attribute keys here as plain strings rather than depending on
// `@opentelemetry/semantic-conventions`. The string values must match exactly, as
// `SDK_INFO` (from `@opentelemetry/core`) is keyed by them.
// This is OTEL-specific and not relevant for Sentry, and will eventually go away.
const ATTR_TELEMETRY_SDK_LANGUAGE = 'telemetry.sdk.language';
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];

/**
Expand Down Expand Up @@ -85,13 +88,13 @@ export function getSentryResource(serviceNameFallback: string): SentryResource {
// Lowest priority: Sentry defaults
// eslint-disable-next-line typescript/no-deprecated
[SEMRESATTRS_SERVICE_NAMESPACE]: 'sentry',
[ATTR_SERVICE_NAME]: serviceNameFallback,
[SERVICE_NAME]: serviceNameFallback,
// OTEL_RESOURCE_ATTRIBUTES overrides defaults (including service.name and service.namespace)
...otelResourceAttrs,
// OTEL_SERVICE_NAME explicitly overrides service.name
...(otelServiceName ? { [ATTR_SERVICE_NAME]: otelServiceName } : {}),
...(otelServiceName ? { [SERVICE_NAME]: otelServiceName } : {}),
// Highest priority: Sentry SDK telemetry attrs (cannot be overridden by env vars)
[ATTR_SERVICE_VERSION]: SDK_VERSION,
[SERVICE_VERSION]: SDK_VERSION,
[ATTR_TELEMETRY_SDK_LANGUAGE]: SDK_INFO[ATTR_TELEMETRY_SDK_LANGUAGE],
[ATTR_TELEMETRY_SDK_NAME]: SDK_INFO[ATTR_TELEMETRY_SDK_NAME],
[ATTR_TELEMETRY_SDK_VERSION]: SDK_INFO[ATTR_TELEMETRY_SDK_VERSION],
Expand Down
15 changes: 5 additions & 10 deletions packages/opentelemetry/src/sampler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,7 @@ import { isSpanContextValid, SpanKind, trace } from '@opentelemetry/api';
import { TraceState } from './utils/TraceState';
import type { Sampler, SamplingResult } from '@opentelemetry/sdk-trace-base';
import { SamplingDecision } from '@opentelemetry/sdk-trace-base';
import {
ATTR_HTTP_REQUEST_METHOD,
ATTR_URL_FULL,
SEMATTRS_HTTP_METHOD,
SEMATTRS_HTTP_URL,
} from '@opentelemetry/semantic-conventions';
import { HTTP_METHOD, HTTP_REQUEST_METHOD, HTTP_URL, URL_FULL } from '@sentry/conventions/attributes';
import type { Client, SpanAttributes } from '@sentry/core';
import {
_INTERNAL_safeMathRandom,
Expand Down Expand Up @@ -70,9 +65,9 @@ export class SentrySampler implements Sampler {
return wrapSamplingDecision({ decision: undefined, context, spanAttributes });
}

// `ATTR_HTTP_REQUEST_METHOD` is the new attribute, but we still support the old one, `SEMATTRS_HTTP_METHOD`, for now.
// `HTTP_REQUEST_METHOD` is the new attribute, but we still support the old one, `HTTP_METHOD`, for now.
// eslint-disable-next-line typescript/no-deprecated
const maybeSpanHttpMethod = spanAttributes[SEMATTRS_HTTP_METHOD] || spanAttributes[ATTR_HTTP_REQUEST_METHOD];
const maybeSpanHttpMethod = spanAttributes[HTTP_METHOD] || spanAttributes[HTTP_REQUEST_METHOD];

// If we have a http.client span that has no local parent, we never want to sample it
// but we want to leave downstream sampling decisions up to the server.
Expand Down Expand Up @@ -331,9 +326,9 @@ function getBaseTraceState(context: Context, spanAttributes: SpanAttributes): Tr
let traceState = parentContext?.traceState || new TraceState();

// We always keep the URL on the trace state, so we can access it in the propagator
// `ATTR_URL_FULL` is the new attribute, but we still support the old one, `ATTR_HTTP_URL`, for now.
// `URL_FULL` is the new attribute, but we still support the old one, `HTTP_URL`, for now.
// eslint-disable-next-line typescript/no-deprecated
const url = spanAttributes[SEMATTRS_HTTP_URL] || spanAttributes[ATTR_URL_FULL];
const url = spanAttributes[HTTP_URL] || spanAttributes[URL_FULL];
if (url && typeof url === 'string') {
traceState = traceState.set(SENTRY_TRACE_STATE_URL, url);
}
Expand Down
8 changes: 4 additions & 4 deletions packages/opentelemetry/src/spanExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import type { Span } from '@opentelemetry/api';
import { SpanKind } from '@opentelemetry/api';
import type { ReadableSpan } from '@opentelemetry/sdk-trace-base';
import { ATTR_HTTP_RESPONSE_STATUS_CODE, SEMATTRS_HTTP_STATUS_CODE } from '@opentelemetry/semantic-conventions';
import { HTTP_RESPONSE_STATUS_CODE, HTTP_STATUS_CODE } from '@sentry/conventions/attributes';
import type {
SpanAttributes,
SpanJSON,
Expand Down Expand Up @@ -295,7 +295,7 @@ export function createTransactionForOtelSpan(span: ReadableSpan): TransactionEve
links: convertSpanLinksForEnvelope(links),
};

const statusCode = attributes[ATTR_HTTP_RESPONSE_STATUS_CODE];
const statusCode = attributes[HTTP_RESPONSE_STATUS_CODE];
const responseContext = typeof statusCode === 'number' ? { response: { status_code: statusCode } } : undefined;

const transactionEvent: TransactionEvent = {
Expand Down Expand Up @@ -442,9 +442,9 @@ function getData(span: ReadableSpan): Record<string, unknown> {
}

// eslint-disable-next-line typescript/no-deprecated
const maybeHttpStatusCodeAttribute = attributes[SEMATTRS_HTTP_STATUS_CODE];
const maybeHttpStatusCodeAttribute = attributes[HTTP_STATUS_CODE];
if (maybeHttpStatusCodeAttribute) {
data[ATTR_HTTP_RESPONSE_STATUS_CODE] = maybeHttpStatusCodeAttribute as string;
data[HTTP_RESPONSE_STATUS_CODE] = maybeHttpStatusCodeAttribute as string;
}

const requestData = getRequestSpanData(span);
Expand Down
15 changes: 3 additions & 12 deletions packages/opentelemetry/src/utils/getRequestSpanData.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import type { Span } from '@opentelemetry/api';
import type { ReadableSpan } from '@opentelemetry/sdk-trace-base';
import {
ATTR_HTTP_REQUEST_METHOD,
ATTR_URL_FULL,
SEMATTRS_HTTP_METHOD,
SEMATTRS_HTTP_URL,
} from '@opentelemetry/semantic-conventions';
import { HTTP_METHOD, HTTP_REQUEST_METHOD, HTTP_URL, URL_FULL } from '@sentry/conventions/attributes';
import type { SanitizedRequestData } from '@sentry/core';
import { getSanitizedUrlString, parseUrl } from '@sentry/core';
import { spanHasAttributes } from './spanTypes';
Expand All @@ -20,16 +15,12 @@ export function getRequestSpanData(span: Span | ReadableSpan): Partial<Sanitized
}

// eslint-disable-next-line typescript/no-deprecated
const maybeUrlAttribute = (span.attributes[ATTR_URL_FULL] || span.attributes[SEMATTRS_HTTP_URL]) as
| string
| undefined;
const maybeUrlAttribute = (span.attributes[URL_FULL] || span.attributes[HTTP_URL]) as string | undefined;

const data: Partial<SanitizedRequestData> = {
url: maybeUrlAttribute,
// eslint-disable-next-line typescript/no-deprecated
'http.method': (span.attributes[ATTR_HTTP_REQUEST_METHOD] || span.attributes[SEMATTRS_HTTP_METHOD]) as
| string
| undefined,
'http.method': (span.attributes[HTTP_REQUEST_METHOD] || span.attributes[HTTP_METHOD]) as string | undefined,
};

// Default to GET if URL is set but method is not
Expand Down
6 changes: 3 additions & 3 deletions packages/opentelemetry/src/utils/isSentryRequest.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ATTR_URL_FULL, SEMATTRS_HTTP_URL } from '@opentelemetry/semantic-conventions';
import { HTTP_URL, URL_FULL } from '@sentry/conventions/attributes';
import { getClient, isSentryRequestUrl } from '@sentry/core';
import type { AbstractSpan } from '../types';
import { spanHasAttributes } from './spanTypes';
Expand All @@ -15,9 +15,9 @@ export function isSentryRequestSpan(span: AbstractSpan): boolean {

const { attributes } = span;

// `ATTR_URL_FULL` is the new attribute, but we still support the old one, `ATTR_HTTP_URL`, for now.
// `URL_FULL` is the new attribute, but we still support the old one, `HTTP_URL`, for now.
// eslint-disable-next-line typescript/no-deprecated
const httpUrl = attributes[SEMATTRS_HTTP_URL] || attributes[ATTR_URL_FULL];
const httpUrl = attributes[HTTP_URL] || attributes[URL_FULL];

if (!httpUrl) {
return false;
Expand Down
10 changes: 3 additions & 7 deletions packages/opentelemetry/src/utils/mapStatus.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { SpanStatusCode } from '@opentelemetry/api';
import {
ATTR_HTTP_RESPONSE_STATUS_CODE,
SEMATTRS_HTTP_STATUS_CODE,
SEMATTRS_RPC_GRPC_STATUS_CODE,
} from '@opentelemetry/semantic-conventions';
import { HTTP_RESPONSE_STATUS_CODE, HTTP_STATUS_CODE, RPC_GRPC_STATUS_CODE } from '@sentry/conventions/attributes';
import type { SpanAttributes, SpanStatus } from '@sentry/core';
import { getSpanStatusFromHttpCode, SPAN_STATUS_ERROR, SPAN_STATUS_OK } from '@sentry/core';
import type { AbstractSpan } from '../types';
Expand Down Expand Up @@ -80,9 +76,9 @@ function inferStatusFromAttributes(attributes: SpanAttributes): SpanStatus | und
// If the span status is UNSET, we try to infer it from HTTP or GRPC status codes.

// eslint-disable-next-line typescript/no-deprecated
const httpCodeAttribute = attributes[ATTR_HTTP_RESPONSE_STATUS_CODE] || attributes[SEMATTRS_HTTP_STATUS_CODE];
const httpCodeAttribute = attributes[HTTP_RESPONSE_STATUS_CODE] || attributes[HTTP_STATUS_CODE];
// eslint-disable-next-line typescript/no-deprecated
const grpcCodeAttribute = attributes[SEMATTRS_RPC_GRPC_STATUS_CODE];
const grpcCodeAttribute = attributes[RPC_GRPC_STATUS_CODE];

const numberHttpCode =
typeof httpCodeAttribute === 'number'
Expand Down
44 changes: 22 additions & 22 deletions packages/opentelemetry/src/utils/parseSpanDescription.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import type { Attributes, AttributeValue } from '@opentelemetry/api';
import { SpanKind } from '@opentelemetry/api';
import {
ATTR_DB_SYSTEM_NAME,
ATTR_HTTP_REQUEST_METHOD,
ATTR_HTTP_ROUTE,
ATTR_URL_FULL,
SEMATTRS_DB_STATEMENT,
SEMATTRS_DB_SYSTEM,
SEMATTRS_FAAS_TRIGGER,
SEMATTRS_HTTP_METHOD,
SEMATTRS_HTTP_TARGET,
SEMATTRS_HTTP_URL,
SEMATTRS_MESSAGING_SYSTEM,
SEMATTRS_RPC_SERVICE,
} from '@opentelemetry/semantic-conventions';
DB_STATEMENT,
DB_SYSTEM,
DB_SYSTEM_NAME,
FAAS_TRIGGER,
HTTP_METHOD,
HTTP_REQUEST_METHOD,
HTTP_ROUTE,
HTTP_TARGET,
HTTP_URL,
MESSAGING_SYSTEM,
RPC_SERVICE,
URL_FULL,
} from '@sentry/conventions/attributes';
import type { SpanAttributes, TransactionSource } from '@sentry/core';
import {
getSanitizedUrlString,
Expand Down Expand Up @@ -42,13 +42,13 @@ interface SpanDescription {
export function inferSpanData(spanName: string, attributes: SpanAttributes, kind: SpanKind): SpanDescription {
// if http.method exists, this is an http request span
// eslint-disable-next-line typescript/no-deprecated
const httpMethod = attributes[ATTR_HTTP_REQUEST_METHOD] || attributes[SEMATTRS_HTTP_METHOD];
const httpMethod = attributes[HTTP_REQUEST_METHOD] || attributes[HTTP_METHOD];
if (httpMethod) {
return descriptionForHttpMethod({ attributes, name: spanName, kind }, httpMethod);
}

// eslint-disable-next-line typescript/no-deprecated
const dbSystem = attributes[ATTR_DB_SYSTEM_NAME] || attributes[SEMATTRS_DB_SYSTEM];
const dbSystem = attributes[DB_SYSTEM_NAME] || attributes[DB_SYSTEM];
const opIsCache =
typeof attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] === 'string' &&
attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP].startsWith('cache.');
Expand All @@ -63,7 +63,7 @@ export function inferSpanData(spanName: string, attributes: SpanAttributes, kind

// If rpc.service exists then this is a rpc call span.
// eslint-disable-next-line typescript/no-deprecated
const rpcService = attributes[SEMATTRS_RPC_SERVICE];
const rpcService = attributes[RPC_SERVICE];
if (rpcService) {
return {
...getUserUpdatedNameAndSource(spanName, attributes, 'route'),
Expand All @@ -73,7 +73,7 @@ export function inferSpanData(spanName: string, attributes: SpanAttributes, kind

// If messaging.system exists then this is a messaging system span.
// eslint-disable-next-line typescript/no-deprecated
const messagingSystem = attributes[SEMATTRS_MESSAGING_SYSTEM];
const messagingSystem = attributes[MESSAGING_SYSTEM];
if (messagingSystem) {
return {
...getUserUpdatedNameAndSource(spanName, attributes, customSourceOrRoute),
Expand All @@ -83,7 +83,7 @@ export function inferSpanData(spanName: string, attributes: SpanAttributes, kind

// If faas.trigger exists then this is a function as a service span.
// eslint-disable-next-line typescript/no-deprecated
const faasTrigger = attributes[SEMATTRS_FAAS_TRIGGER];
const faasTrigger = attributes[FAAS_TRIGGER];
if (faasTrigger) {
return {
...getUserUpdatedNameAndSource(spanName, attributes, customSourceOrRoute),
Expand Down Expand Up @@ -129,7 +129,7 @@ function descriptionForDbSystem({ attributes, name }: { attributes: Attributes;

// Use DB statement (Ex "SELECT * FROM table") if possible as description.
// eslint-disable-next-line typescript/no-deprecated
const statement = attributes[SEMATTRS_DB_STATEMENT];
const statement = attributes[DB_STATEMENT];

const description = statement ? statement.toString() : name;

Expand Down Expand Up @@ -248,12 +248,12 @@ export function getSanitizedUrl(
} {
// This is the relative path of the URL, e.g. /sub
// eslint-disable-next-line typescript/no-deprecated
const httpTarget = attributes[SEMATTRS_HTTP_TARGET];
const httpTarget = attributes[HTTP_TARGET];
// This is the full URL, including host & query params etc., e.g. https://example.com/sub?foo=bar
// eslint-disable-next-line typescript/no-deprecated
const httpUrl = attributes[SEMATTRS_HTTP_URL] || attributes[ATTR_URL_FULL];
const httpUrl = attributes[HTTP_URL] || attributes[URL_FULL];
// This is the normalized route name - may not always be available!
const httpRoute = attributes[ATTR_HTTP_ROUTE];
const httpRoute = attributes[HTTP_ROUTE];

const parsedUrl = typeof httpUrl === 'string' ? parseUrl(httpUrl) : undefined;
const url = parsedUrl ? getSanitizedUrlString(parsedUrl) : undefined;
Expand Down
Loading
Loading