Skip to content

Commit 9666506

Browse files
authored
ref(node-otel): Avoid exporting internals & refactor attribute adding (#8920)
I noticed that we kind of extended the public API by exporting some things from opentelemetry-node that we need in node-experimental. I am deprecating these internals as I'm refactoring some things to be a bit cleaner IMHO. The one export we actually need outside I am exporting as `_INTERNAL_getSentrySpan` to make it clear this is not meant to be used otherwise. The main reason I am not just exporting this is that this _may_ have to change if we change how we internally store/handle spans - e.g. if we move away from the map this is just not possible to have anymore, and I do not want to lock us into having to support this in the future.
1 parent 91c48c9 commit 9666506

File tree

12 files changed

+133
-106
lines changed

12 files changed

+133
-106
lines changed

packages/node-experimental/src/integrations/express.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import type { Instrumentation } from '@opentelemetry/instrumentation';
22
import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express';
3-
import { addOtelSpanData } from '@sentry/opentelemetry-node';
43
import type { Integration } from '@sentry/types';
54

5+
import { addOriginToOtelSpan } from '../utils/addOriginToSpan';
66
import { NodePerformanceIntegration } from './NodePerformanceIntegration';
77

88
/**
@@ -31,9 +31,7 @@ export class Express extends NodePerformanceIntegration<void> implements Integra
3131
return [
3232
new ExpressInstrumentation({
3333
requestHook(span) {
34-
addOtelSpanData(span.spanContext().spanId, {
35-
origin: 'auto.http.otel.express',
36-
});
34+
addOriginToOtelSpan(span, 'auto.http.otel.express');
3735
},
3836
}),
3937
];

packages/node-experimental/src/integrations/fastify.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import type { Instrumentation } from '@opentelemetry/instrumentation';
22
import { FastifyInstrumentation } from '@opentelemetry/instrumentation-fastify';
3-
import { addOtelSpanData } from '@sentry/opentelemetry-node';
43
import type { Integration } from '@sentry/types';
54

5+
import { addOriginToOtelSpan } from '../utils/addOriginToSpan';
66
import { NodePerformanceIntegration } from './NodePerformanceIntegration';
77

88
/**
@@ -31,9 +31,7 @@ export class Fastify extends NodePerformanceIntegration<void> implements Integra
3131
return [
3232
new FastifyInstrumentation({
3333
requestHook(span) {
34-
addOtelSpanData(span.spanContext().spanId, {
35-
origin: 'auto.http.otel.fastify',
36-
});
34+
addOriginToOtelSpan(span, 'auto.http.otel.fastify');
3735
},
3836
}),
3937
];

packages/node-experimental/src/integrations/graphql.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import type { Instrumentation } from '@opentelemetry/instrumentation';
22
import { GraphQLInstrumentation } from '@opentelemetry/instrumentation-graphql';
3-
import { addOtelSpanData } from '@sentry/opentelemetry-node';
43
import type { Integration } from '@sentry/types';
54

5+
import { addOriginToOtelSpan } from '../utils/addOriginToSpan';
66
import { NodePerformanceIntegration } from './NodePerformanceIntegration';
77

88
/**
@@ -32,9 +32,7 @@ export class GraphQL extends NodePerformanceIntegration<void> implements Integra
3232
new GraphQLInstrumentation({
3333
ignoreTrivialResolveSpans: true,
3434
responseHook(span) {
35-
addOtelSpanData(span.spanContext().spanId, {
36-
origin: 'auto.graphql.otel-graphql',
37-
});
35+
addOriginToOtelSpan(span, 'auto.graphql.otel.graphql');
3836
},
3937
}),
4038
];

packages/node-experimental/src/integrations/http.ts

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ import { registerInstrumentations } from '@opentelemetry/instrumentation';
44
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
55
import type { Span as OtelSpan } from '@opentelemetry/sdk-trace-node';
66
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
7-
import { hasTracingEnabled } from '@sentry/core';
7+
import { hasTracingEnabled, Transaction } from '@sentry/core';
88
import { getCurrentHub } from '@sentry/node';
9-
import type { AdditionalOtelSpanData } from '@sentry/opentelemetry-node';
10-
import { addOtelSpanData } from '@sentry/opentelemetry-node';
9+
import { _INTERNAL_getSentrySpan } from '@sentry/opentelemetry-node';
1110
import type { EventProcessor, Hub, Integration } from '@sentry/types';
1211
import type { ClientRequest, IncomingMessage, ServerResponse } from 'http';
1312

@@ -146,34 +145,37 @@ export class Http implements Integration {
146145
const data = getRequestSpanData(span, request, response);
147146
const { attributes } = span;
148147

149-
const additionalData: AdditionalOtelSpanData = {
150-
tags: {},
151-
data: {
148+
const sentrySpan = _INTERNAL_getSentrySpan(span.spanContext().spanId);
149+
if (sentrySpan) {
150+
sentrySpan.origin = 'auto.http.otel.http';
151+
152+
const additionalData: Record<string, unknown> = {
152153
url: data.url,
153-
},
154-
contexts: {},
155-
metadata: {},
156-
origin: 'auto.http.otel.http',
157-
};
158-
159-
if (span.kind === SpanKind.SERVER) {
160-
additionalData.metadata = { request };
161-
}
154+
};
162155

163-
if (attributes[SemanticAttributes.HTTP_STATUS_CODE]) {
164-
const statusCode = attributes[SemanticAttributes.HTTP_STATUS_CODE] as string;
165-
additionalData.tags['http.status_code'] = statusCode;
166-
additionalData.data['http.response.status_code'] = statusCode;
167-
}
156+
if (sentrySpan instanceof Transaction && span.kind === SpanKind.SERVER) {
157+
sentrySpan.setMetadata({ request });
158+
}
168159

169-
if (data['http.query']) {
170-
additionalData.data['http.query'] = data['http.query'].slice(1);
171-
}
172-
if (data['http.fragment']) {
173-
additionalData.data['http.fragment'] = data['http.fragment'].slice(1);
174-
}
160+
if (attributes[SemanticAttributes.HTTP_STATUS_CODE]) {
161+
const statusCode = attributes[SemanticAttributes.HTTP_STATUS_CODE] as string;
162+
additionalData['http.response.status_code'] = statusCode;
175163

176-
addOtelSpanData(span.spanContext().spanId, additionalData);
164+
sentrySpan.setTag('http.status_code', statusCode);
165+
}
166+
167+
if (data['http.query']) {
168+
additionalData['http.query'] = data['http.query'].slice(1);
169+
}
170+
if (data['http.fragment']) {
171+
additionalData['http.fragment'] = data['http.fragment'].slice(1);
172+
}
173+
174+
Object.keys(additionalData).forEach(prop => {
175+
const value = additionalData[prop];
176+
sentrySpan.setData(prop, value);
177+
});
178+
}
177179

178180
if (this._breadcrumbs) {
179181
getCurrentHub().addBreadcrumb(

packages/node-experimental/src/integrations/mongo.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import type { Instrumentation } from '@opentelemetry/instrumentation';
22
import { MongoDBInstrumentation } from '@opentelemetry/instrumentation-mongodb';
3-
import { addOtelSpanData } from '@sentry/opentelemetry-node';
43
import type { Integration } from '@sentry/types';
54

5+
import { addOriginToOtelSpan } from '../utils/addOriginToSpan';
66
import { NodePerformanceIntegration } from './NodePerformanceIntegration';
77

88
/**
@@ -31,9 +31,7 @@ export class Mongo extends NodePerformanceIntegration<void> implements Integrati
3131
return [
3232
new MongoDBInstrumentation({
3333
responseHook(span) {
34-
addOtelSpanData(span.spanContext().spanId, {
35-
origin: 'auto.db.otel-mongo',
36-
});
34+
addOriginToOtelSpan(span, 'auto.db.otel.mongo');
3735
},
3836
}),
3937
];

packages/node-experimental/src/integrations/mongoose.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import type { Instrumentation } from '@opentelemetry/instrumentation';
22
import { MongooseInstrumentation } from '@opentelemetry/instrumentation-mongoose';
3-
import { addOtelSpanData } from '@sentry/opentelemetry-node';
43
import type { Integration } from '@sentry/types';
54

5+
import { addOriginToOtelSpan } from '../utils/addOriginToSpan';
66
import { NodePerformanceIntegration } from './NodePerformanceIntegration';
77

88
/**
@@ -31,9 +31,7 @@ export class Mongoose extends NodePerformanceIntegration<void> implements Integr
3131
return [
3232
new MongooseInstrumentation({
3333
responseHook(span) {
34-
addOtelSpanData(span.spanContext().spanId, {
35-
origin: 'auto.db.otel-mongoose',
36-
});
34+
addOriginToOtelSpan(span, 'auto.db.otel.mongoose');
3735
},
3836
}),
3937
];

packages/node-experimental/src/integrations/mysql2.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import type { Instrumentation } from '@opentelemetry/instrumentation';
22
import { MySQL2Instrumentation } from '@opentelemetry/instrumentation-mysql2';
3-
import { addOtelSpanData } from '@sentry/opentelemetry-node';
43
import type { Integration } from '@sentry/types';
54

5+
import { addOriginToOtelSpan } from '../utils/addOriginToSpan';
66
import { NodePerformanceIntegration } from './NodePerformanceIntegration';
77

88
/**
@@ -31,9 +31,7 @@ export class Mysql2 extends NodePerformanceIntegration<void> implements Integrat
3131
return [
3232
new MySQL2Instrumentation({
3333
responseHook(span) {
34-
addOtelSpanData(span.spanContext().spanId, {
35-
origin: 'auto.db.otel-mysql2',
36-
});
34+
addOriginToOtelSpan(span, 'auto.db.otel.mysql2');
3735
},
3836
}),
3937
];

packages/node-experimental/src/integrations/postgres.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import type { Instrumentation } from '@opentelemetry/instrumentation';
22
import { PgInstrumentation } from '@opentelemetry/instrumentation-pg';
3-
import { addOtelSpanData } from '@sentry/opentelemetry-node';
43
import type { Integration } from '@sentry/types';
54

5+
import { addOriginToOtelSpan } from '../utils/addOriginToSpan';
66
import { NodePerformanceIntegration } from './NodePerformanceIntegration';
77

88
/**
@@ -31,9 +31,7 @@ export class Postgres extends NodePerformanceIntegration<void> implements Integr
3131
return [
3232
new PgInstrumentation({
3333
requestHook(span) {
34-
addOtelSpanData(span.spanContext().spanId, {
35-
origin: 'auto.db.otel-postgres',
36-
});
34+
addOriginToOtelSpan(span, 'auto.db.otel.postgres');
3735
},
3836
}),
3937
];
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import type { Span as OtelSpan } from '@opentelemetry/api';
2+
import { _INTERNAL_getSentrySpan } from '@sentry/opentelemetry-node';
3+
import type { SpanOrigin } from '@sentry/types';
4+
5+
/** Adds an origin to an OTEL Span. */
6+
export function addOriginToOtelSpan(otelSpan: OtelSpan, origin: SpanOrigin): void {
7+
const sentrySpan = _INTERNAL_getSentrySpan(otelSpan.spanContext().spanId);
8+
if (!sentrySpan) {
9+
return;
10+
}
11+
12+
sentrySpan.origin = origin;
13+
}
Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
import { getSentrySpan } from './spanprocessor';
2+
13
export { SentrySpanProcessor } from './spanprocessor';
24
export { SentryPropagator } from './propagator';
3-
export * from './utils/spanData';
5+
6+
/* eslint-disable deprecation/deprecation */
7+
export { addOtelSpanData, getOtelSpanData, clearOtelSpanData } from './utils/spanData';
8+
export type { AdditionalOtelSpanData } from './utils/spanData';
9+
/* eslint-enable deprecation/deprecation */
10+
11+
/**
12+
* This is only exported for internal use.
13+
* Semver etc. does not apply here, this is subject to change at any time!
14+
* This is explicitly _NOT_ public because we may have to change the underlying way we store/handle spans,
15+
* which may make this API unusable without further notice.
16+
*
17+
* @private
18+
*/
19+
export { getSentrySpan as _INTERNAL_getSentrySpan };

packages/opentelemetry-node/src/spanprocessor.ts

Lines changed: 8 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ import { SENTRY_DYNAMIC_SAMPLING_CONTEXT_KEY, SENTRY_TRACE_PARENT_CONTEXT_KEY }
1010
import { isSentryRequestSpan } from './utils/isSentryRequest';
1111
import { mapOtelStatus } from './utils/mapOtelStatus';
1212
import { parseSpanDescription } from './utils/parseOtelSpanDescription';
13-
import { clearOtelSpanData, getOtelSpanData } from './utils/spanData';
1413

15-
export const SENTRY_SPAN_PROCESSOR_MAP: Map<SentrySpan['spanId'], SentrySpan> = new Map<
16-
SentrySpan['spanId'],
17-
SentrySpan
18-
>();
14+
export const SENTRY_SPAN_PROCESSOR_MAP: Map<string, SentrySpan> = new Map<string, SentrySpan>();
1915

2016
// make sure to remove references in maps, to ensure this can be GCed
2117
function clearSpan(otelSpanId: string): void {
22-
clearOtelSpanData(otelSpanId);
2318
SENTRY_SPAN_PROCESSOR_MAP.delete(otelSpanId);
2419
}
2520

21+
/** Get a Sentry span for an otel span ID. */
22+
export function getSentrySpan(otelSpanId: string): SentrySpan | undefined {
23+
return SENTRY_SPAN_PROCESSOR_MAP.get(otelSpanId);
24+
}
25+
2626
/**
2727
* Converts OpenTelemetry Spans to Sentry Spans and sends them to Sentry via
2828
* the Sentry SDK.
@@ -225,18 +225,10 @@ function updateSpanWithOtelData(sentrySpan: SentrySpan, otelSpan: OtelSpan): voi
225225

226226
const { op, description, data } = parseSpanDescription(otelSpan);
227227

228-
const { data: additionalData, tags, origin } = getOtelSpanData(otelSpan.spanContext().spanId);
229-
230228
sentrySpan.setStatus(mapOtelStatus(otelSpan));
231229
sentrySpan.setData('otel.kind', SpanKind[kind]);
232230

233-
if (tags) {
234-
Object.keys(tags).forEach(prop => {
235-
sentrySpan.setTag(prop, tags[prop]);
236-
});
237-
}
238-
239-
const allData = { ...attributes, ...data, ...additionalData };
231+
const allData = { ...attributes, ...data };
240232

241233
Object.keys(allData).forEach(prop => {
242234
const value = allData[prop];
@@ -245,52 +237,27 @@ function updateSpanWithOtelData(sentrySpan: SentrySpan, otelSpan: OtelSpan): voi
245237

246238
sentrySpan.op = op;
247239
sentrySpan.description = description;
248-
249-
if (origin) {
250-
sentrySpan.origin = origin;
251-
}
252240
}
253241

254242
function updateTransactionWithOtelData(transaction: Transaction, otelSpan: OtelSpan): void {
255243
const { op, description, source, data } = parseSpanDescription(otelSpan);
256-
const { data: additionalData, tags, contexts, metadata, origin } = getOtelSpanData(otelSpan.spanContext().spanId);
257244

258245
transaction.setContext('otel', {
259246
attributes: otelSpan.attributes,
260247
resource: otelSpan.resource.attributes,
261248
});
262249

263-
if (tags) {
264-
Object.keys(tags).forEach(prop => {
265-
transaction.setTag(prop, tags[prop]);
266-
});
267-
}
268-
269-
if (metadata) {
270-
transaction.setMetadata(metadata);
271-
}
272-
273-
const allData = { ...data, ...additionalData };
250+
const allData = data || {};
274251

275252
Object.keys(allData).forEach(prop => {
276253
const value = allData[prop];
277254
transaction.setData(prop, value);
278255
});
279256

280-
if (contexts) {
281-
Object.keys(contexts).forEach(prop => {
282-
transaction.setContext(prop, contexts[prop]);
283-
});
284-
}
285-
286257
transaction.setStatus(mapOtelStatus(otelSpan));
287258

288259
transaction.op = op;
289260
transaction.setName(description, source);
290-
291-
if (origin) {
292-
transaction.origin = origin;
293-
}
294261
}
295262

296263
function convertOtelTimeToSeconds([seconds, nano]: [number, number]): number {

0 commit comments

Comments
 (0)