Skip to content

Commit

Permalink
feat(otel): Upgrade @opentelemetry/semantic-conventions to 1.26.0 (#1…
Browse files Browse the repository at this point in the history
…3631)

resolves #13627

In 1.26.0 otel-js has updated the deprecations for the attributes based
on the new changes to semantic conventions.

They also changed the name of some exports, for example:
`SEMATTRS_HTTP_ROUTE` -> `ATTR_HTTP_ROUTE`. Some exports names were not
able to be changed because they are imported from a subpath export
@opentelemetry/semantic-conventions/incubating. This subpath breaks some
bundling setups, so we are unable to use it.
  • Loading branch information
AbhiPrasad authored Sep 10, 2024
1 parent 017e8f9 commit cef6986
Show file tree
Hide file tree
Showing 19 changed files with 133 additions and 66 deletions.
2 changes: 1 addition & 1 deletion packages/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
},
"dependencies": {
"@opentelemetry/instrumentation-http": "0.53.0",
"@opentelemetry/semantic-conventions": "^1.25.1",
"@opentelemetry/semantic-conventions": "^1.27.0",
"@rollup/plugin-commonjs": "26.0.1",
"@sentry/core": "8.29.0",
"@sentry/node": "8.29.0",
Expand Down
18 changes: 15 additions & 3 deletions packages/nextjs/src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ import { getDefaultIntegrations, init as nodeInit } from '@sentry/node';
import type { NodeClient, NodeOptions } from '@sentry/node';
import { GLOBAL_OBJ, logger } from '@sentry/utils';

import { SEMATTRS_HTTP_METHOD, SEMATTRS_HTTP_ROUTE, SEMATTRS_HTTP_TARGET } from '@opentelemetry/semantic-conventions';
import {
ATTR_HTTP_REQUEST_METHOD,
ATTR_HTTP_ROUTE,
SEMATTRS_HTTP_METHOD,
SEMATTRS_HTTP_TARGET,
} from '@opentelemetry/semantic-conventions';
import type { EventProcessor } from '@sentry/types';
import { DEBUG_BUILD } from '../common/debug-build';
import { devErrorSymbolicationEventProcessor } from '../common/devErrorSymbolicationEventProcessor';
Expand Down Expand Up @@ -150,8 +155,11 @@ export function init(options: NodeOptions): NodeClient | undefined {
// because we didn't get the chance to do `suppressTracing`, since this happens outside of userland.
// We need to drop these spans.
if (
// eslint-disable-next-line deprecation/deprecation
typeof spanAttributes[SEMATTRS_HTTP_TARGET] === 'string' &&
// eslint-disable-next-line deprecation/deprecation
spanAttributes[SEMATTRS_HTTP_TARGET].includes('sentry_key') &&
// eslint-disable-next-line deprecation/deprecation
spanAttributes[SEMATTRS_HTTP_TARGET].includes('sentry_client')
) {
samplingDecision.decision = false;
Expand All @@ -168,8 +176,12 @@ export function init(options: NodeOptions): NodeClient | undefined {
const rootSpanAttributes = spanToJSON(rootSpan).data;

// Only hoist the http.route attribute if the transaction doesn't already have it
if (rootSpanAttributes?.[SEMATTRS_HTTP_METHOD] && !rootSpanAttributes?.[SEMATTRS_HTTP_ROUTE]) {
rootSpan.setAttribute(SEMATTRS_HTTP_ROUTE, spanAttributes['next.route']);
if (
// eslint-disable-next-line deprecation/deprecation
(rootSpanAttributes?.[ATTR_HTTP_REQUEST_METHOD] || rootSpanAttributes?.[SEMATTRS_HTTP_METHOD]) &&
!rootSpanAttributes?.[ATTR_HTTP_ROUTE]
) {
rootSpan.setAttribute(ATTR_HTTP_ROUTE, spanAttributes['next.route']);
}
}

Expand Down
6 changes: 3 additions & 3 deletions packages/node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@
"@opentelemetry/instrumentation-pg": "0.44.0",
"@opentelemetry/instrumentation-redis-4": "0.42.0",
"@opentelemetry/instrumentation-undici": "0.6.0",
"@opentelemetry/resources": "^1.25.1",
"@opentelemetry/sdk-trace-base": "^1.25.1",
"@opentelemetry/semantic-conventions": "^1.25.1",
"@opentelemetry/resources": "^1.26.0",
"@opentelemetry/sdk-trace-base": "^1.26.0",
"@opentelemetry/semantic-conventions": "^1.27.0",
"@prisma/instrumentation": "5.19.1",
"@sentry/core": "8.29.0",
"@sentry/opentelemetry": "8.29.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/node/src/integrations/tracing/koa.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { KoaInstrumentation } from '@opentelemetry/instrumentation-koa';
import { SEMATTRS_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';
import { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';
import {
SEMANTIC_ATTRIBUTE_SENTRY_OP,
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
Expand Down Expand Up @@ -29,7 +29,7 @@ export const instrumentKoa = generateInstrumentOnce(
return;
}
const attributes = spanToJSON(span).data;
const route = attributes && attributes[SEMATTRS_HTTP_ROUTE];
const route = attributes && attributes[ATTR_HTTP_ROUTE];
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
const method: string = info?.context?.request?.method?.toUpperCase() || 'GET';
if (route) {
Expand Down
9 changes: 5 additions & 4 deletions packages/node/src/sdk/initOtel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { DiagLogLevel, diag } from '@opentelemetry/api';
import { Resource } from '@opentelemetry/resources';
import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';
import {
SEMRESATTRS_SERVICE_NAME,
ATTR_SERVICE_NAME,
ATTR_SERVICE_VERSION,
SEMRESATTRS_SERVICE_NAMESPACE,
SEMRESATTRS_SERVICE_VERSION,
} from '@opentelemetry/semantic-conventions';
import { SDK_VERSION } from '@sentry/core';
import { SentryPropagator, SentrySampler, SentrySpanProcessor } from '@sentry/opentelemetry';
Expand Down Expand Up @@ -130,9 +130,10 @@ export function setupOtel(client: NodeClient): BasicTracerProvider {
const provider = new BasicTracerProvider({
sampler: new SentrySampler(client),
resource: new Resource({
[SEMRESATTRS_SERVICE_NAME]: 'node',
[ATTR_SERVICE_NAME]: 'node',
// eslint-disable-next-line deprecation/deprecation
[SEMRESATTRS_SERVICE_NAMESPACE]: 'sentry',
[SEMRESATTRS_SERVICE_VERSION]: SDK_VERSION,
[ATTR_SERVICE_VERSION]: SDK_VERSION,
}),
forceFlushTimeoutMillis: 500,
});
Expand Down
8 changes: 4 additions & 4 deletions packages/opentelemetry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/core": "^1.25.1",
"@opentelemetry/instrumentation": "^0.53.0",
"@opentelemetry/sdk-trace-base": "^1.25.1",
"@opentelemetry/semantic-conventions": "^1.25.1"
"@opentelemetry/sdk-trace-base": "^1.26.0",
"@opentelemetry/semantic-conventions": "^1.27.0"
},
"devDependencies": {
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/context-async-hooks": "^1.25.1",
"@opentelemetry/core": "^1.25.1",
"@opentelemetry/sdk-trace-base": "^1.25.1",
"@opentelemetry/semantic-conventions": "^1.25.1"
"@opentelemetry/sdk-trace-base": "^1.26.0",
"@opentelemetry/semantic-conventions": "^1.27.0"
},
"scripts": {
"build": "run-p build:transpile build:types",
Expand Down
7 changes: 4 additions & 3 deletions packages/opentelemetry/src/propagator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ import { INVALID_TRACEID } from '@opentelemetry/api';
import { context } from '@opentelemetry/api';
import { propagation, trace } from '@opentelemetry/api';
import { W3CBaggagePropagator, isTracingSuppressed } from '@opentelemetry/core';
import { SEMATTRS_HTTP_URL } from '@opentelemetry/semantic-conventions';
import { ATTR_URL_FULL, SEMATTRS_HTTP_URL } from '@opentelemetry/semantic-conventions';
import type { continueTrace } from '@sentry/core';
import { SEMANTIC_ATTRIBUTE_URL_FULL } from '@sentry/core';
import { hasTracingEnabled } from '@sentry/core';
import { getRootSpan } from '@sentry/core';
import { spanToJSON } from '@sentry/core';
Expand Down Expand Up @@ -294,7 +293,9 @@ function getExistingBaggage(carrier: unknown): string | undefined {
*/
function getCurrentURL(span: Span): string | undefined {
const spanData = spanToJSON(span).data;
const urlAttribute = spanData?.[SEMATTRS_HTTP_URL] || spanData?.[SEMANTIC_ATTRIBUTE_URL_FULL];
// `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];
if (urlAttribute) {
return urlAttribute;
}
Expand Down
25 changes: 15 additions & 10 deletions packages/opentelemetry/src/sampler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@ import { TraceState } from '@opentelemetry/core';
import type { Sampler, SamplingResult } from '@opentelemetry/sdk-trace-base';
import { SamplingDecision } from '@opentelemetry/sdk-trace-base';
import {
SEMANTIC_ATTRIBUTE_HTTP_REQUEST_METHOD,
SEMANTIC_ATTRIBUTE_SENTRY_OP,
SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE,
SEMANTIC_ATTRIBUTE_URL_FULL,
hasTracingEnabled,
sampleSpan,
} from '@sentry/core';
import type { Client, SpanAttributes } from '@sentry/types';
import { logger } from '@sentry/utils';
import { SENTRY_TRACE_STATE_SAMPLED_NOT_RECORDING, SENTRY_TRACE_STATE_URL } from './constants';

import { SEMATTRS_HTTP_METHOD, SEMATTRS_HTTP_URL } from '@opentelemetry/semantic-conventions';
import {
ATTR_HTTP_REQUEST_METHOD,
ATTR_URL_FULL,
SEMATTRS_HTTP_METHOD,
SEMATTRS_HTTP_URL,
} from '@opentelemetry/semantic-conventions';
import { DEBUG_BUILD } from './debug-build';
import { getPropagationContextFromSpan } from './propagator';
import { getSamplingDecision } from './utils/getSamplingDecision';
Expand Down Expand Up @@ -52,13 +55,13 @@ 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];

// 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
if (
spanKind === SpanKind.CLIENT &&
(spanAttributes[SEMATTRS_HTTP_METHOD] || spanAttributes[SEMANTIC_ATTRIBUTE_HTTP_REQUEST_METHOD]) &&
(!parentSpan || parentContext?.isRemote)
) {
if (spanKind === SpanKind.CLIENT && maybeSpanHttpMethod && (!parentSpan || parentContext?.isRemote)) {
return wrapSamplingDecision({ decision: undefined, context, spanAttributes });
}

Expand Down Expand Up @@ -109,7 +112,7 @@ export class SentrySampler implements Sampler {
[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: sampleRate,
};

const method = `${spanAttributes[SEMATTRS_HTTP_METHOD]}`.toUpperCase();
const method = `${maybeSpanHttpMethod}`.toUpperCase();
if (method === 'OPTIONS' || method === 'HEAD') {
DEBUG_BUILD && logger.log(`[Tracing] Not sampling span because HTTP method is '${method}' for ${spanName}`);

Expand Down Expand Up @@ -198,7 +201,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
const url = spanAttributes[SEMATTRS_HTTP_URL] || spanAttributes[SEMANTIC_ATTRIBUTE_URL_FULL];
// `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];
if (url && typeof url === 'string') {
traceState = traceState.set(SENTRY_TRACE_STATE_URL, url);
}
Expand Down
9 changes: 5 additions & 4 deletions packages/opentelemetry/src/spanExporter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Span } from '@opentelemetry/api';
import { SpanKind } from '@opentelemetry/api';
import type { ReadableSpan } from '@opentelemetry/sdk-trace-base';
import { SEMATTRS_HTTP_STATUS_CODE } from '@opentelemetry/semantic-conventions';
import { ATTR_HTTP_RESPONSE_STATUS_CODE, SEMATTRS_HTTP_STATUS_CODE } from '@opentelemetry/semantic-conventions';
import {
captureEvent,
getCapturedScopesOnSpan,
Expand Down Expand Up @@ -358,9 +358,10 @@ function getData(span: ReadableSpan): Record<string, unknown> {
data['otel.kind'] = SpanKind[span.kind];
}

if (attributes[SEMATTRS_HTTP_STATUS_CODE]) {
const statusCode = attributes[SEMATTRS_HTTP_STATUS_CODE] as string;
data['http.response.status_code'] = statusCode;
// eslint-disable-next-line deprecation/deprecation
const maybeHttpStatusCodeAttribute = attributes[SEMATTRS_HTTP_STATUS_CODE];
if (maybeHttpStatusCodeAttribute) {
data[ATTR_HTTP_RESPONSE_STATUS_CODE] = maybeHttpStatusCodeAttribute as string;
}

const requestData = getRequestSpanData(span);
Expand Down
24 changes: 18 additions & 6 deletions packages/opentelemetry/src/utils/getRequestSpanData.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import type { Span } from '@opentelemetry/api';
import type { ReadableSpan } from '@opentelemetry/sdk-trace-base';
import { SEMATTRS_HTTP_METHOD, SEMATTRS_HTTP_URL } from '@opentelemetry/semantic-conventions';
import {
ATTR_HTTP_REQUEST_METHOD,
ATTR_URL_FULL,
SEMATTRS_HTTP_METHOD,
SEMATTRS_HTTP_URL,
} from '@opentelemetry/semantic-conventions';
import type { SanitizedRequestData } from '@sentry/types';
import { getSanitizedUrlString, parseUrl } from '@sentry/utils';

Expand All @@ -15,9 +20,17 @@ 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 data: Partial<SanitizedRequestData> = {
url: span.attributes[SEMATTRS_HTTP_URL] as string | undefined,
'http.method': span.attributes[SEMATTRS_HTTP_METHOD] as string | undefined,
url: maybeUrlAttribute,
// eslint-disable-next-line deprecation/deprecation
'http.method': (span.attributes[ATTR_HTTP_REQUEST_METHOD] || span.attributes[SEMATTRS_HTTP_METHOD]) as
| string
| undefined,
};

// Default to GET if URL is set but method is not
Expand All @@ -26,9 +39,8 @@ export function getRequestSpanData(span: Span | ReadableSpan): Partial<Sanitized
}

try {
const urlStr = span.attributes[SEMATTRS_HTTP_URL];
if (typeof urlStr === 'string') {
const url = parseUrl(urlStr);
if (typeof maybeUrlAttribute === 'string') {
const url = parseUrl(maybeUrlAttribute);

data.url = getSanitizedUrlString(url);

Expand Down
8 changes: 5 additions & 3 deletions packages/opentelemetry/src/utils/isSentryRequest.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SEMATTRS_HTTP_URL } from '@opentelemetry/semantic-conventions';
import { SEMANTIC_ATTRIBUTE_URL_FULL, getClient, isSentryRequestUrl } from '@sentry/core';
import { ATTR_URL_FULL, SEMATTRS_HTTP_URL } from '@opentelemetry/semantic-conventions';
import { getClient, isSentryRequestUrl } from '@sentry/core';

import type { AbstractSpan } from '../types';
import { spanHasAttributes } from './spanTypes';
Expand All @@ -16,7 +16,9 @@ export function isSentryRequestSpan(span: AbstractSpan): boolean {

const { attributes } = span;

const httpUrl = attributes[SEMATTRS_HTTP_URL] || attributes[SEMANTIC_ATTRIBUTE_URL_FULL];
// `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];

if (!httpUrl) {
return false;
Expand Down
10 changes: 8 additions & 2 deletions packages/opentelemetry/src/utils/mapStatus.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { SpanStatusCode } from '@opentelemetry/api';
import { SEMATTRS_HTTP_STATUS_CODE, SEMATTRS_RPC_GRPC_STATUS_CODE } from '@opentelemetry/semantic-conventions';
import {
ATTR_HTTP_RESPONSE_STATUS_CODE,
SEMATTRS_HTTP_STATUS_CODE,
SEMATTRS_RPC_GRPC_STATUS_CODE,
} from '@opentelemetry/semantic-conventions';
import { SPAN_STATUS_ERROR, SPAN_STATUS_OK, getSpanStatusFromHttpCode } from '@sentry/core';
import type { SpanAttributes, SpanStatus } from '@sentry/types';

Expand Down Expand Up @@ -76,7 +80,9 @@ 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.

const httpCodeAttribute = attributes[SEMATTRS_HTTP_STATUS_CODE];
// 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 numberHttpCode =
Expand Down
Loading

0 comments on commit cef6986

Please sign in to comment.