Skip to content

Commit 8b6f838

Browse files
authored
feat(opentelemetry): Update OTEL packages & relax some version ranges (#11580)
This bumps all our OTEL dependencies to require the most up to date versions as of today for all the core packages. This allows us to use the new semantic attributes, which esp. also some instrumentation uses in newer versions. By requiring this as a minimum version, we can ensure that we can update all our instrumentation. This also relaxes all of the core packages to `^` range, so users can easier use `@sentry/node` together with their own otel instrumentation. The instrumentation we add remains hard-pinned. To avoid deprecation warnings I updated all the semantic attributes usage to the new syntax.
1 parent 919f60b commit 8b6f838

17 files changed

+201
-188
lines changed

packages/node/package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@
5353
"access": "public"
5454
},
5555
"dependencies": {
56-
"@opentelemetry/api": "1.7.0",
57-
"@opentelemetry/context-async-hooks": "1.21.0",
58-
"@opentelemetry/core": "1.21.0",
56+
"@opentelemetry/api": "^1.8.0",
57+
"@opentelemetry/context-async-hooks": "^1.23.0",
58+
"@opentelemetry/core": "^1.23.0",
5959
"@opentelemetry/instrumentation": "0.48.0",
6060
"@opentelemetry/instrumentation-express": "0.35.0",
6161
"@opentelemetry/instrumentation-fastify": "0.33.0",
@@ -69,9 +69,9 @@
6969
"@opentelemetry/instrumentation-mysql2": "0.35.0",
7070
"@opentelemetry/instrumentation-nestjs-core": "0.34.0",
7171
"@opentelemetry/instrumentation-pg": "0.38.0",
72-
"@opentelemetry/resources": "1.21.0",
73-
"@opentelemetry/sdk-trace-base": "1.21.0",
74-
"@opentelemetry/semantic-conventions": "1.21.0",
72+
"@opentelemetry/resources": "^1.23.0",
73+
"@opentelemetry/sdk-trace-base": "^1.23.0",
74+
"@opentelemetry/semantic-conventions": "^1.23.0",
7575
"@prisma/instrumentation": "5.9.0",
7676
"@sentry/core": "8.0.0-beta.1",
7777
"@sentry/opentelemetry": "8.0.0-beta.1",

packages/node/src/integrations/tracing/koa.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { registerInstrumentations } from '@opentelemetry/instrumentation';
22
import { KoaInstrumentation } from '@opentelemetry/instrumentation-koa';
3-
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
3+
import { SEMATTRS_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';
44
import {
55
captureException,
66
defineIntegration,
@@ -26,7 +26,7 @@ const _koaIntegration = (() => {
2626
return;
2727
}
2828
const attributes = spanToJSON(span).data;
29-
const route = attributes && attributes[SemanticAttributes.HTTP_ROUTE];
29+
const route = attributes && attributes[SEMATTRS_HTTP_ROUTE];
3030
const method = info.context.request.method.toUpperCase() || 'GET';
3131
if (route) {
3232
getIsolationScope().setTransactionName(`${method} ${route}`);

packages/node/src/sdk/initOtel.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { DiagLogLevel, diag } from '@opentelemetry/api';
22
import { Resource } from '@opentelemetry/resources';
33
import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';
4-
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
4+
import {
5+
SEMRESATTRS_SERVICE_NAME,
6+
SEMRESATTRS_SERVICE_NAMESPACE,
7+
SEMRESATTRS_SERVICE_VERSION,
8+
} from '@opentelemetry/semantic-conventions';
59
import { SDK_VERSION } from '@sentry/core';
610
import { SentryPropagator, SentrySampler, SentrySpanProcessor, setupEventContextTrace } from '@sentry/opentelemetry';
711
import { logger } from '@sentry/utils';
@@ -36,9 +40,9 @@ export function setupOtel(client: NodeClient): BasicTracerProvider {
3640
const provider = new BasicTracerProvider({
3741
sampler: new SentrySampler(client),
3842
resource: new Resource({
39-
[SemanticResourceAttributes.SERVICE_NAME]: 'node',
40-
[SemanticResourceAttributes.SERVICE_NAMESPACE]: 'sentry',
41-
[SemanticResourceAttributes.SERVICE_VERSION]: SDK_VERSION,
43+
[SEMRESATTRS_SERVICE_NAME]: 'node',
44+
[SEMRESATTRS_SERVICE_NAMESPACE]: 'sentry',
45+
[SEMRESATTRS_SERVICE_VERSION]: SDK_VERSION,
4246
}),
4347
forceFlushTimeoutMillis: 500,
4448
});

packages/opentelemetry/package.json

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,17 @@
4747
"@sentry/utils": "8.0.0-beta.1"
4848
},
4949
"peerDependencies": {
50-
"@opentelemetry/api": "^1.0.0",
51-
"@opentelemetry/core": "^1.0.0",
52-
"@opentelemetry/sdk-trace-base": "^1.0.0",
53-
"@opentelemetry/semantic-conventions": "^1.0.0"
50+
"@opentelemetry/api": "^1.8.0",
51+
"@opentelemetry/core": "^1.23.0",
52+
"@opentelemetry/sdk-trace-base": "^1.23.0",
53+
"@opentelemetry/semantic-conventions": "^1.23.0"
5454
},
5555
"devDependencies": {
56-
"@opentelemetry/api": "^1.6.0",
57-
"@opentelemetry/context-async-hooks": "^1.17.1",
58-
"@opentelemetry/core": "^1.17.1",
59-
"@opentelemetry/sdk-trace-base": "^1.17.1",
60-
"@opentelemetry/sdk-trace-node": "^1.17.1",
61-
"@opentelemetry/semantic-conventions": "^1.17.1"
56+
"@opentelemetry/api": "^1.8.0",
57+
"@opentelemetry/context-async-hooks": "^1.23.0",
58+
"@opentelemetry/core": "^1.23.0",
59+
"@opentelemetry/sdk-trace-base": "^1.23.0",
60+
"@opentelemetry/semantic-conventions": "^1.23.0"
6261
},
6362
"scripts": {
6463
"build": "run-p build:transpile build:types",

packages/opentelemetry/src/propagator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Baggage, Context, Span, SpanContext, TextMapGetter, TextMapSetter
22
import { context } from '@opentelemetry/api';
33
import { TraceFlags, propagation, trace } from '@opentelemetry/api';
44
import { TraceState, W3CBaggagePropagator, isTracingSuppressed } from '@opentelemetry/core';
5-
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
5+
import { SEMATTRS_HTTP_URL } from '@opentelemetry/semantic-conventions';
66
import type { continueTrace } from '@sentry/core';
77
import { hasTracingEnabled } from '@sentry/core';
88
import { getRootSpan } from '@sentry/core';
@@ -329,7 +329,7 @@ function getExistingBaggage(carrier: unknown): string | undefined {
329329
* 2. Else, if the active span has no URL attribute (e.g. it is unsampled), we check a special trace state (which we set in our sampler).
330330
*/
331331
function getCurrentURL(span: Span): string | undefined {
332-
const urlAttribute = spanToJSON(span).data?.[SemanticAttributes.HTTP_URL];
332+
const urlAttribute = spanToJSON(span).data?.[SEMATTRS_HTTP_URL];
333333
if (urlAttribute) {
334334
return urlAttribute;
335335
}

packages/opentelemetry/src/sampler.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type { Client, SpanAttributes } from '@sentry/types';
99
import { logger } from '@sentry/utils';
1010
import { SENTRY_TRACE_STATE_SAMPLED_NOT_RECORDING, SENTRY_TRACE_STATE_URL } from './constants';
1111

12-
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
12+
import { SEMATTRS_HTTP_METHOD, SEMATTRS_HTTP_URL } from '@opentelemetry/semantic-conventions';
1313
import { DEBUG_BUILD } from './debug-build';
1414
import { getPropagationContextFromSpan } from './propagator';
1515
import { getSamplingDecision } from './utils/getSamplingDecision';
@@ -43,7 +43,7 @@ export class SentrySampler implements Sampler {
4343
let traceState = parentContext?.traceState || new TraceState();
4444

4545
// We always keep the URL on the trace state, so we can access it in the propagator
46-
const url = spanAttributes[SemanticAttributes.HTTP_URL];
46+
const url = spanAttributes[SEMATTRS_HTTP_URL];
4747
if (url && typeof url === 'string') {
4848
traceState = traceState.set(SENTRY_TRACE_STATE_URL, url);
4949
}
@@ -56,7 +56,7 @@ export class SentrySampler implements Sampler {
5656
// but we want to leave downstream sampling decisions up to the server
5757
if (
5858
spanKind === SpanKind.CLIENT &&
59-
spanAttributes[SemanticAttributes.HTTP_METHOD] &&
59+
spanAttributes[SEMATTRS_HTTP_METHOD] &&
6060
(!parentSpan || parentContext?.isRemote)
6161
) {
6262
return { decision: SamplingDecision.NOT_RECORD, traceState };
@@ -86,7 +86,7 @@ export class SentrySampler implements Sampler {
8686
[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: sampleRate,
8787
};
8888

89-
const method = `${spanAttributes[SemanticAttributes.HTTP_METHOD]}`.toUpperCase();
89+
const method = `${spanAttributes[SEMATTRS_HTTP_METHOD]}`.toUpperCase();
9090
if (method === 'OPTIONS' || method === 'HEAD') {
9191
DEBUG_BUILD && logger.log(`[Tracing] Not sampling span because HTTP method is '${method}' for ${spanName}`);
9292
return {

packages/opentelemetry/src/spanExporter.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Span } from '@opentelemetry/api';
22
import { SpanKind } from '@opentelemetry/api';
33
import type { ReadableSpan } from '@opentelemetry/sdk-trace-base';
4-
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
4+
import { SEMATTRS_HTTP_STATUS_CODE } from '@opentelemetry/semantic-conventions';
55
import {
66
captureEvent,
77
getCapturedScopesOnSpan,
@@ -335,8 +335,8 @@ function getData(span: ReadableSpan): Record<string, unknown> {
335335
'otel.kind': SpanKind[span.kind],
336336
};
337337

338-
if (attributes[SemanticAttributes.HTTP_STATUS_CODE]) {
339-
const statusCode = attributes[SemanticAttributes.HTTP_STATUS_CODE] as string;
338+
if (attributes[SEMATTRS_HTTP_STATUS_CODE]) {
339+
const statusCode = attributes[SEMATTRS_HTTP_STATUS_CODE] as string;
340340
data['http.response.status_code'] = statusCode;
341341
}
342342

packages/opentelemetry/src/utils/getRequestSpanData.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Span } from '@opentelemetry/api';
22
import type { ReadableSpan } from '@opentelemetry/sdk-trace-base';
3-
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
3+
import { SEMATTRS_HTTP_METHOD, SEMATTRS_HTTP_URL } from '@opentelemetry/semantic-conventions';
44
import type { SanitizedRequestData } from '@sentry/types';
55
import { getSanitizedUrlString, parseUrl } from '@sentry/utils';
66

@@ -16,8 +16,8 @@ export function getRequestSpanData(span: Span | ReadableSpan): Partial<Sanitized
1616
}
1717

1818
const data: Partial<SanitizedRequestData> = {
19-
url: span.attributes[SemanticAttributes.HTTP_URL] as string | undefined,
20-
'http.method': span.attributes[SemanticAttributes.HTTP_METHOD] as string | undefined,
19+
url: span.attributes[SEMATTRS_HTTP_URL] as string | undefined,
20+
'http.method': span.attributes[SEMATTRS_HTTP_METHOD] as string | undefined,
2121
};
2222

2323
// Default to GET if URL is set but method is not
@@ -26,7 +26,7 @@ export function getRequestSpanData(span: Span | ReadableSpan): Partial<Sanitized
2626
}
2727

2828
try {
29-
const urlStr = span.attributes[SemanticAttributes.HTTP_URL];
29+
const urlStr = span.attributes[SEMATTRS_HTTP_URL];
3030
if (typeof urlStr === 'string') {
3131
const url = parseUrl(urlStr);
3232

packages/opentelemetry/src/utils/isSentryRequest.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
1+
import { SEMATTRS_HTTP_URL } from '@opentelemetry/semantic-conventions';
22
import { getClient, isSentryRequestUrl } from '@sentry/core';
33

44
import type { AbstractSpan } from '../types';
@@ -16,7 +16,7 @@ export function isSentryRequestSpan(span: AbstractSpan): boolean {
1616

1717
const { attributes } = span;
1818

19-
const httpUrl = attributes[SemanticAttributes.HTTP_URL];
19+
const httpUrl = attributes[SEMATTRS_HTTP_URL];
2020

2121
if (!httpUrl) {
2222
return false;

packages/opentelemetry/src/utils/mapStatus.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { SpanStatusCode } from '@opentelemetry/api';
2-
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
2+
import { SEMATTRS_HTTP_STATUS_CODE, SEMATTRS_RPC_GRPC_STATUS_CODE } from '@opentelemetry/semantic-conventions';
33
import { SPAN_STATUS_ERROR, SPAN_STATUS_OK, getSpanStatusFromHttpCode } from '@sentry/core';
44
import type { SpanStatus } from '@sentry/types';
55

@@ -53,8 +53,8 @@ export function mapStatus(span: AbstractSpan): SpanStatus {
5353

5454
// If the span status is UNSET, we try to infer it from HTTP or GRPC status codes.
5555

56-
const httpCodeAttribute = attributes[SemanticAttributes.HTTP_STATUS_CODE];
57-
const grpcCodeAttribute = attributes[SemanticAttributes.RPC_GRPC_STATUS_CODE];
56+
const httpCodeAttribute = attributes[SEMATTRS_HTTP_STATUS_CODE];
57+
const grpcCodeAttribute = attributes[SEMATTRS_RPC_GRPC_STATUS_CODE];
5858

5959
const numberHttpCode =
6060
typeof httpCodeAttribute === 'number'

packages/opentelemetry/src/utils/parseSpanDescription.ts

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
import type { AttributeValue, Attributes } from '@opentelemetry/api';
22
import { SpanKind } from '@opentelemetry/api';
3-
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
3+
import {
4+
SEMATTRS_DB_STATEMENT,
5+
SEMATTRS_DB_SYSTEM,
6+
SEMATTRS_FAAS_TRIGGER,
7+
SEMATTRS_HTTP_METHOD,
8+
SEMATTRS_HTTP_ROUTE,
9+
SEMATTRS_HTTP_TARGET,
10+
SEMATTRS_HTTP_URL,
11+
SEMATTRS_MESSAGING_SYSTEM,
12+
SEMATTRS_RPC_SERVICE,
13+
} from '@opentelemetry/semantic-conventions';
414
import type { TransactionSource } from '@sentry/types';
515
import { getSanitizedUrlString, parseUrl, stripUrlQueryAndFragment } from '@sentry/utils';
616

@@ -25,19 +35,19 @@ export function parseSpanDescription(span: AbstractSpan): SpanDescription {
2535
const name = spanHasName(span) ? span.name : '<unknown>';
2636

2737
// if http.method exists, this is an http request span
28-
const httpMethod = attributes[SemanticAttributes.HTTP_METHOD];
38+
const httpMethod = attributes[SEMATTRS_HTTP_METHOD];
2939
if (httpMethod) {
3040
return descriptionForHttpMethod({ attributes, name, kind: getSpanKind(span) }, httpMethod);
3141
}
3242

3343
// If db.type exists then this is a database call span.
34-
const dbSystem = attributes[SemanticAttributes.DB_SYSTEM];
44+
const dbSystem = attributes[SEMATTRS_DB_SYSTEM];
3545
if (dbSystem) {
3646
return descriptionForDbSystem({ attributes, name });
3747
}
3848

3949
// If rpc.service exists then this is a rpc call span.
40-
const rpcService = attributes[SemanticAttributes.RPC_SERVICE];
50+
const rpcService = attributes[SEMATTRS_RPC_SERVICE];
4151
if (rpcService) {
4252
return {
4353
op: 'rpc',
@@ -47,7 +57,7 @@ export function parseSpanDescription(span: AbstractSpan): SpanDescription {
4757
}
4858

4959
// If messaging.system exists then this is a messaging system span.
50-
const messagingSystem = attributes[SemanticAttributes.MESSAGING_SYSTEM];
60+
const messagingSystem = attributes[SEMATTRS_MESSAGING_SYSTEM];
5161
if (messagingSystem) {
5262
return {
5363
op: 'message',
@@ -57,7 +67,7 @@ export function parseSpanDescription(span: AbstractSpan): SpanDescription {
5767
}
5868

5969
// If faas.trigger exists then this is a function as a service span.
60-
const faasTrigger = attributes[SemanticAttributes.FAAS_TRIGGER];
70+
const faasTrigger = attributes[SEMATTRS_FAAS_TRIGGER];
6171
if (faasTrigger) {
6272
return { op: faasTrigger.toString(), description: name, source: 'route' };
6373
}
@@ -67,7 +77,7 @@ export function parseSpanDescription(span: AbstractSpan): SpanDescription {
6777

6878
function descriptionForDbSystem({ attributes, name }: { attributes: Attributes; name: string }): SpanDescription {
6979
// Use DB statement (Ex "SELECT * FROM table") if possible as description.
70-
const statement = attributes[SemanticAttributes.DB_STATEMENT];
80+
const statement = attributes[SEMATTRS_DB_STATEMENT];
7181

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

@@ -134,11 +144,11 @@ export function getSanitizedUrl(
134144
hasRoute: boolean;
135145
} {
136146
// This is the relative path of the URL, e.g. /sub
137-
const httpTarget = attributes[SemanticAttributes.HTTP_TARGET];
147+
const httpTarget = attributes[SEMATTRS_HTTP_TARGET];
138148
// This is the full URL, including host & query params etc., e.g. https://example.com/sub?foo=bar
139-
const httpUrl = attributes[SemanticAttributes.HTTP_URL];
149+
const httpUrl = attributes[SEMATTRS_HTTP_URL];
140150
// This is the normalized route name - may not always be available!
141-
const httpRoute = attributes[SemanticAttributes.HTTP_ROUTE];
151+
const httpRoute = attributes[SEMATTRS_HTTP_ROUTE];
142152

143153
const parsedUrl = typeof httpUrl === 'string' ? parseUrl(httpUrl) : undefined;
144154
const url = parsedUrl ? getSanitizedUrlString(parsedUrl) : undefined;

packages/opentelemetry/test/helpers/initOtel.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import { DiagLogLevel, diag } from '@opentelemetry/api';
22
import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks';
33
import { Resource } from '@opentelemetry/resources';
44
import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';
5-
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
5+
import {
6+
SEMRESATTRS_SERVICE_NAME,
7+
SEMRESATTRS_SERVICE_NAMESPACE,
8+
SEMRESATTRS_SERVICE_VERSION,
9+
} from '@opentelemetry/semantic-conventions';
610
import { SDK_VERSION, getClient } from '@sentry/core';
711
import { logger } from '@sentry/utils';
812

@@ -51,9 +55,9 @@ export function setupOtel(client: TestClientInterface): BasicTracerProvider {
5155
const provider = new BasicTracerProvider({
5256
sampler: new SentrySampler(client),
5357
resource: new Resource({
54-
[SemanticResourceAttributes.SERVICE_NAME]: 'opentelemetry-test',
55-
[SemanticResourceAttributes.SERVICE_NAMESPACE]: 'sentry',
56-
[SemanticResourceAttributes.SERVICE_VERSION]: SDK_VERSION,
58+
[SEMRESATTRS_SERVICE_NAME]: 'opentelemetry-test',
59+
[SEMRESATTRS_SERVICE_NAMESPACE]: 'sentry',
60+
[SEMRESATTRS_SERVICE_VERSION]: SDK_VERSION,
5761
}),
5862
forceFlushTimeoutMillis: 500,
5963
});

0 commit comments

Comments
 (0)