Skip to content
Draft
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
5 changes: 2 additions & 3 deletions packages/opentelemetry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,13 @@
"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"
"@sentry/conventions": "^0.11.0"
},
"scripts": {
"build": "run-p build:transpile build:types",
Expand Down
7 changes: 3 additions & 4 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,8 @@ 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.
// eslint-disable-next-line deprecation/deprecation
const urlAttribute = spanData[SEMATTRS_HTTP_URL] || spanData[ATTR_URL_FULL];
// `URL_FULL` is the new attribute, but we still support the old one, `HTTP_URL`, for now.
const urlAttribute = spanData[HTTP_URL] || spanData[URL_FULL];
if (typeof urlAttribute === 'string') {
return urlAttribute;
}
Expand Down
25 changes: 13 additions & 12 deletions packages/opentelemetry/src/resource.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
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 (yet) 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.
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 @@ -83,15 +85,14 @@ export function getSentryResource(serviceNameFallback: string): SentryResource {

return new SentryResource({
// Lowest priority: Sentry defaults
// eslint-disable-next-line deprecation/deprecation
[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
17 changes: 5 additions & 12 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,8 @@ 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.
// eslint-disable-next-line deprecation/deprecation
const maybeSpanHttpMethod = spanAttributes[SEMATTRS_HTTP_METHOD] || spanAttributes[ATTR_HTTP_REQUEST_METHOD];
// `HTTP_REQUEST_METHOD` is the new attribute, but we still support the old one, `HTTP_METHOD`, for now.
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 +325,8 @@ 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.
// eslint-disable-next-line deprecation/deprecation
const url = spanAttributes[SEMATTRS_HTTP_URL] || spanAttributes[ATTR_URL_FULL];
// `URL_FULL` is the new attribute, but we still support the old one, `HTTP_URL`, for now.
const url = spanAttributes[HTTP_URL] || spanAttributes[URL_FULL];
if (url && typeof url === 'string') {
traceState = traceState.set(SENTRY_TRACE_STATE_URL, url);
}
Expand Down
9 changes: 4 additions & 5 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 @@ -441,10 +441,9 @@ function getData(span: ReadableSpan): Record<string, unknown> {
data['otel.kind'] = SpanKind[span.kind];
}

// eslint-disable-next-line deprecation/deprecation
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
17 changes: 3 additions & 14 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 @@ -19,17 +14,11 @@ export function getRequestSpanData(span: Span | ReadableSpan): Partial<Sanitized
return {};
}

// eslint-disable-next-line deprecation/deprecation
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 deprecation/deprecation
'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
7 changes: 3 additions & 4 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,8 @@ 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.
// eslint-disable-next-line deprecation/deprecation
const httpUrl = attributes[SEMATTRS_HTTP_URL] || attributes[ATTR_URL_FULL];
// `URL_FULL` is the new attribute, but we still support the old one, `HTTP_URL`, for now.
const httpUrl = attributes[HTTP_URL] || attributes[URL_FULL];

if (!httpUrl) {
return false;
Expand Down
12 changes: 3 additions & 9 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 @@ -79,10 +75,8 @@ export function mapStatus(span: AbstractSpan): SpanStatus {
function inferStatusFromAttributes(attributes: SpanAttributes): SpanStatus | undefined {
// If the span status is UNSET, we try to infer it from HTTP or GRPC status codes.

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

const numberHttpCode =
typeof httpCodeAttribute === 'number'
Expand Down
52 changes: 22 additions & 30 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 @@ -41,14 +41,12 @@ 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 deprecation/deprecation
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 deprecation/deprecation
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 @@ -62,8 +60,7 @@ export function inferSpanData(spanName: string, attributes: SpanAttributes, kind
const customSourceOrRoute = attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] === 'custom' ? 'custom' : 'route';

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

// If messaging.system exists then this is a messaging system span.
// eslint-disable-next-line deprecation/deprecation
const messagingSystem = attributes[SEMATTRS_MESSAGING_SYSTEM];
const messagingSystem = attributes[MESSAGING_SYSTEM];
if (messagingSystem) {
return {
...getUserUpdatedNameAndSource(spanName, attributes, customSourceOrRoute),
Expand All @@ -82,8 +78,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 deprecation/deprecation
const faasTrigger = attributes[SEMATTRS_FAAS_TRIGGER];
const faasTrigger = attributes[FAAS_TRIGGER];
if (faasTrigger) {
return {
...getUserUpdatedNameAndSource(spanName, attributes, customSourceOrRoute),
Expand Down Expand Up @@ -128,8 +123,7 @@ function descriptionForDbSystem({ attributes, name }: { attributes: Attributes;
}

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

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

Expand Down Expand Up @@ -247,13 +241,11 @@ export function getSanitizedUrl(
hasRoute: boolean;
} {
// This is the relative path of the URL, e.g. /sub
// eslint-disable-next-line deprecation/deprecation
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 deprecation/deprecation
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