Skip to content

Commit ee30339

Browse files
committed
ref add stuff
1 parent 3431a27 commit ee30339

File tree

8 files changed

+347
-208
lines changed

8 files changed

+347
-208
lines changed

Diff for: packages/node/src/integrations/tracing/dataloader.ts

+8-10
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ import {
33
SEMANTIC_ATTRIBUTE_SENTRY_OP,
44
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
55
defineIntegration,
6-
getClient,
76
spanToJSON,
87
} from '@sentry/core';
98
import type { IntegrationFn } from '@sentry/core';
10-
import { callWhenWrapped, generateInstrumentOnce } from '../../otel/instrument';
9+
import { instrumentWhenWrapped, generateInstrumentOnce } from '../../otel/instrument';
1110

1211
const INTEGRATION_NAME = 'Dataloader';
1312

@@ -20,20 +19,19 @@ export const instrumentDataloader = generateInstrumentOnce(
2019
);
2120

2221
const _dataloaderIntegration = (() => {
23-
let hookCallback: undefined | (() => void);
22+
let instrumentationWrappedCallback: undefined | ((callback: () => void) => void);
2423

2524
return {
2625
name: INTEGRATION_NAME,
2726
setupOnce() {
2827
const instrumentation = instrumentDataloader();
28+
instrumentationWrappedCallback = instrumentWhenWrapped(instrumentation);
29+
},
2930

30-
callWhenWrapped(instrumentation, () => {
31-
const client = getClient();
32-
if (hookCallback || !client) {
33-
return;
34-
}
35-
36-
hookCallback = client.on('spanStart', span => {
31+
setup(client) {
32+
// This is called either immediately or when the instrumentation is wrapped
33+
instrumentationWrappedCallback?.(() => {
34+
client.on('spanStart', span => {
3735
const spanJSON = spanToJSON(span);
3836
if (spanJSON.description?.startsWith('dataloader')) {
3937
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.dataloader');

Diff for: packages/node/src/integrations/tracing/genericPool.ts

+17-12
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,38 @@
11
import { GenericPoolInstrumentation } from '@opentelemetry/instrumentation-generic-pool';
22
import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration, spanToJSON } from '@sentry/core';
33
import type { IntegrationFn } from '@sentry/core';
4-
import { generateInstrumentOnce } from '../../otel/instrument';
4+
import { generateInstrumentOnce, instrumentWhenWrapped } from '../../otel/instrument';
55

66
const INTEGRATION_NAME = 'GenericPool';
77

88
export const instrumentGenericPool = generateInstrumentOnce(INTEGRATION_NAME, () => new GenericPoolInstrumentation({}));
99

1010
const _genericPoolIntegration = (() => {
11+
let instrumentationWrappedCallback: undefined | ((callback: () => void) => void);
12+
1113
return {
1214
name: INTEGRATION_NAME,
1315
setupOnce() {
14-
instrumentGenericPool();
16+
const instrumentation = instrumentGenericPool();
17+
instrumentationWrappedCallback = instrumentWhenWrapped(instrumentation);
1518
},
1619

1720
setup(client) {
18-
client.on('spanStart', span => {
19-
const spanJSON = spanToJSON(span);
21+
instrumentationWrappedCallback?.(() =>
22+
client.on('spanStart', span => {
23+
const spanJSON = spanToJSON(span);
2024

21-
const spanDescription = spanJSON.description;
25+
const spanDescription = spanJSON.description;
2226

23-
// typo in emitted span for version <= 0.38.0 of @opentelemetry/instrumentation-generic-pool
24-
const isGenericPoolSpan =
25-
spanDescription === 'generic-pool.aquire' || spanDescription === 'generic-pool.acquire';
27+
// typo in emitted span for version <= 0.38.0 of @opentelemetry/instrumentation-generic-pool
28+
const isGenericPoolSpan =
29+
spanDescription === 'generic-pool.aquire' || spanDescription === 'generic-pool.acquire';
2630

27-
if (isGenericPoolSpan) {
28-
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.generic_pool');
29-
}
30-
});
31+
if (isGenericPoolSpan) {
32+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.generic_pool');
33+
}
34+
}),
35+
);
3136
},
3237
};
3338
}) satisfies IntegrationFn;

Diff for: packages/node/src/integrations/tracing/knex.ts

+15-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { KnexInstrumentation } from '@opentelemetry/instrumentation-knex';
22
import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration, spanToJSON } from '@sentry/core';
33
import type { IntegrationFn } from '@sentry/core';
4-
import { generateInstrumentOnce } from '../../otel/instrument';
4+
import { generateInstrumentOnce, instrumentWhenWrapped } from '../../otel/instrument';
55

66
const INTEGRATION_NAME = 'Knex';
77

@@ -11,21 +11,26 @@ export const instrumentKnex = generateInstrumentOnce(
1111
);
1212

1313
const _knexIntegration = (() => {
14+
let instrumentationWrappedCallback: undefined | ((callback: () => void) => void);
15+
1416
return {
1517
name: INTEGRATION_NAME,
1618
setupOnce() {
17-
instrumentKnex();
19+
const instrumentation = instrumentKnex();
20+
instrumentationWrappedCallback = instrumentWhenWrapped(instrumentation);
1821
},
1922

2023
setup(client) {
21-
client.on('spanStart', span => {
22-
const { data } = spanToJSON(span);
23-
// knex.version is always set in the span data
24-
// https://github.com./open-telemetry/opentelemetry-js-contrib/blob/0309caeafc44ac9cb13a3345b790b01b76d0497d/plugins/node/opentelemetry-instrumentation-knex/src/instrumentation.ts#L138
25-
if ('knex.version' in data) {
26-
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.knex');
27-
}
28-
});
24+
instrumentationWrappedCallback?.(() =>
25+
client.on('spanStart', span => {
26+
const { data } = spanToJSON(span);
27+
// knex.version is always set in the span data
28+
// https://github.com./open-telemetry/opentelemetry-js-contrib/blob/0309caeafc44ac9cb13a3345b790b01b76d0497d/plugins/node/opentelemetry-instrumentation-knex/src/instrumentation.ts#L138
29+
if ('knex.version' in data) {
30+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.knex');
31+
}
32+
}),
33+
);
2934
},
3035
};
3136
}) satisfies IntegrationFn;

Diff for: packages/node/src/integrations/tracing/prisma.ts

+22-17
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Instrumentation } from '@opentelemetry/instrumentation';
22
// When importing CJS modules into an ESM module, we cannot import the named exports directly.
33
import * as prismaInstrumentation from '@prisma/instrumentation';
44
import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, consoleSandbox, defineIntegration, spanToJSON } from '@sentry/core';
5-
import { generateInstrumentOnce } from '../../otel/instrument';
5+
import { generateInstrumentOnce, instrumentWhenWrapped } from '../../otel/instrument';
66
import type { PrismaV5TracingHelper } from './prisma/vendor/v5-tracing-helper';
77
import type { PrismaV6TracingHelper } from './prisma/vendor/v6-tracing-helper';
88

@@ -113,29 +113,34 @@ export const prismaIntegration = defineIntegration(
113113
*/
114114
prismaInstrumentation?: Instrumentation;
115115
} = {}) => {
116+
let instrumentationWrappedCallback: undefined | ((callback: () => void) => void);
117+
116118
return {
117119
name: INTEGRATION_NAME,
118120
setupOnce() {
119-
instrumentPrisma({ prismaInstrumentation });
121+
const instrumentation = instrumentPrisma({ prismaInstrumentation });
122+
instrumentationWrappedCallback = instrumentWhenWrapped(instrumentation);
120123
},
121124
setup(client) {
122-
client.on('spanStart', span => {
123-
const spanJSON = spanToJSON(span);
124-
if (spanJSON.description?.startsWith('prisma:')) {
125-
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.prisma');
126-
}
125+
instrumentationWrappedCallback?.(() =>
126+
client.on('spanStart', span => {
127+
const spanJSON = spanToJSON(span);
128+
if (spanJSON.description?.startsWith('prisma:')) {
129+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.prisma');
130+
}
127131

128-
// Make sure we use the query text as the span name, for ex. SELECT * FROM "User" WHERE "id" = $1
129-
if (spanJSON.description === 'prisma:engine:db_query' && spanJSON.data['db.query.text']) {
130-
span.updateName(spanJSON.data['db.query.text'] as string);
131-
}
132+
// Make sure we use the query text as the span name, for ex. SELECT * FROM "User" WHERE "id" = $1
133+
if (spanJSON.description === 'prisma:engine:db_query' && spanJSON.data['db.query.text']) {
134+
span.updateName(spanJSON.data['db.query.text'] as string);
135+
}
132136

133-
// In Prisma v5.22+, the `db.system` attribute is automatically set
134-
// On older versions, this is missing, so we add it here
135-
if (spanJSON.description === 'prisma:engine:db_query' && !spanJSON.data['db.system']) {
136-
span.setAttribute('db.system', 'prisma');
137-
}
138-
});
137+
// In Prisma v5.22+, the `db.system` attribute is automatically set
138+
// On older versions, this is missing, so we add it here
139+
if (spanJSON.description === 'prisma:engine:db_query' && !spanJSON.data['db.system']) {
140+
span.setAttribute('db.system', 'prisma');
141+
}
142+
}),
143+
);
139144
},
140145
};
141146
},

Diff for: packages/node/src/integrations/tracing/tedious.ts

+19-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { TediousInstrumentation } from '@opentelemetry/instrumentation-tedious';
22
import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration, spanToJSON } from '@sentry/core';
33
import type { IntegrationFn } from '@sentry/core';
4-
import { generateInstrumentOnce } from '../../otel/instrument';
4+
import { generateInstrumentOnce, instrumentWhenWrapped } from '../../otel/instrument';
55

66
const TEDIUS_INSTRUMENTED_METHODS = new Set([
77
'callProcedure',
@@ -17,25 +17,30 @@ const INTEGRATION_NAME = 'Tedious';
1717
export const instrumentTedious = generateInstrumentOnce(INTEGRATION_NAME, () => new TediousInstrumentation({}));
1818

1919
const _tediousIntegration = (() => {
20+
let instrumentationWrappedCallback: undefined | ((callback: () => void) => void);
21+
2022
return {
2123
name: INTEGRATION_NAME,
2224
setupOnce() {
23-
instrumentTedious();
25+
const instrumentation = instrumentTedious();
26+
instrumentationWrappedCallback = instrumentWhenWrapped(instrumentation);
2427
},
2528

2629
setup(client) {
27-
client.on('spanStart', span => {
28-
const { description, data } = spanToJSON(span);
29-
// Tedius integration always set a span name and `db.system` attribute to `mssql`.
30-
if (!description || data['db.system'] !== 'mssql') {
31-
return;
32-
}
33-
34-
const operation = description.split(' ')[0] || '';
35-
if (TEDIUS_INSTRUMENTED_METHODS.has(operation)) {
36-
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.tedious');
37-
}
38-
});
30+
instrumentationWrappedCallback?.(() =>
31+
client.on('spanStart', span => {
32+
const { description, data } = spanToJSON(span);
33+
// Tedius integration always set a span name and `db.system` attribute to `mssql`.
34+
if (!description || data['db.system'] !== 'mssql') {
35+
return;
36+
}
37+
38+
const operation = description.split(' ')[0] || '';
39+
if (TEDIUS_INSTRUMENTED_METHODS.has(operation)) {
40+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.tedious');
41+
}
42+
}),
43+
);
3944
},
4045
};
4146
}) satisfies IntegrationFn;

0 commit comments

Comments
 (0)