Skip to content

Commit c0bcd8e

Browse files
mydeaonurtemizkan
authored andcommitted
feat(node-experimental): Update tracing integrations to functional style (#10443)
This refactors the node-experimental performance integrations to functional style. Importantly, it also slightly updates the options for httpIntegration & nativeNodeFetchIntegration, with what they can/should be in v8: * There is no way to disable span creation for them (this is pretty hacky to do, and prob. not needed - not allowing this simplifies this a lot) * You can define filters for incoming/outgoing requests to filter them fully - that will filter them both for breadcrumbs and spans. * spans are not created anyhow when tracing is disabled.
1 parent 6170a76 commit c0bcd8e

File tree

20 files changed

+531
-141
lines changed

20 files changed

+531
-141
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ jobs:
126126
node:
127127
- *shared
128128
- 'packages/node/**'
129+
- 'packages/node-experimental/**'
129130
- 'dev-packages/node-integration-tests/**'
130131
deno:
131132
- *shared

packages/node-experimental/src/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,20 @@
11
import { Integrations as CoreIntegrations } from '@sentry/core';
22

33
import * as NodeExperimentalIntegrations from './integrations';
4+
export { expressIntegration } from './integrations/express';
5+
export { fastifyIntegration } from './integrations/fastify';
6+
export { graphqlIntegration } from './integrations/graphql';
7+
export { httpIntegration } from './integrations/http';
8+
export { mongoIntegration } from './integrations/mongo';
9+
export { mongooseIntegration } from './integrations/mongoose';
10+
export { mysqlIntegration } from './integrations/mysql';
11+
export { mysql2Integration } from './integrations/mysql2';
12+
export { nestIntegration } from './integrations/nest';
13+
export { nativeNodeFetchIntegration } from './integrations/node-fetch';
14+
export { postgresIntegration } from './integrations/postgres';
15+
export { prismaIntegration } from './integrations/prisma';
416

17+
/** @deprecated Import the integration function directly, e.g. `inboundFiltersIntegration()` instead of `new Integrations.InboundFilter(). */
518
export const Integrations = {
619
// eslint-disable-next-line deprecation/deprecation
720
...CoreIntegrations,

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

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,36 @@
11
import type { Instrumentation } from '@opentelemetry/instrumentation';
2+
import { registerInstrumentations } from '@opentelemetry/instrumentation';
23
import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express';
3-
import type { Integration } from '@sentry/types';
4+
import { defineIntegration } from '@sentry/core';
5+
import type { Integration, IntegrationFn } from '@sentry/types';
46

57
import { addOriginToSpan } from '../utils/addOriginToSpan';
68
import { NodePerformanceIntegration } from './NodePerformanceIntegration';
79

10+
const _expressIntegration = (() => {
11+
return {
12+
name: 'Express',
13+
setupOnce() {
14+
registerInstrumentations({
15+
instrumentations: [
16+
new ExpressInstrumentation({
17+
requestHook(span) {
18+
addOriginToSpan(span, 'auto.http.otel.express');
19+
},
20+
}),
21+
],
22+
});
23+
},
24+
};
25+
}) satisfies IntegrationFn;
26+
27+
export const expressIntegration = defineIntegration(_expressIntegration);
28+
829
/**
930
* Express integration
1031
*
1132
* Capture tracing data for express.
33+
* @deprecated Use `expressIntegration()` instead.
1234
*/
1335
export class Express extends NodePerformanceIntegration<void> implements Integration {
1436
/**
@@ -23,6 +45,7 @@ export class Express extends NodePerformanceIntegration<void> implements Integra
2345

2446
public constructor() {
2547
super();
48+
// eslint-disable-next-line deprecation/deprecation
2649
this.name = Express.id;
2750
}
2851

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,37 @@
11
import type { Instrumentation } from '@opentelemetry/instrumentation';
2+
import { registerInstrumentations } from '@opentelemetry/instrumentation';
23
import { FastifyInstrumentation } from '@opentelemetry/instrumentation-fastify';
3-
import type { Integration } from '@sentry/types';
4+
import { defineIntegration } from '@sentry/core';
5+
import type { Integration, IntegrationFn } from '@sentry/types';
46

57
import { addOriginToSpan } from '../utils/addOriginToSpan';
68
import { NodePerformanceIntegration } from './NodePerformanceIntegration';
79

10+
const _fastifyIntegration = (() => {
11+
return {
12+
name: 'Fastify',
13+
setupOnce() {
14+
registerInstrumentations({
15+
instrumentations: [
16+
new FastifyInstrumentation({
17+
requestHook(span) {
18+
addOriginToSpan(span, 'auto.http.otel.fastify');
19+
},
20+
}),
21+
],
22+
});
23+
},
24+
};
25+
}) satisfies IntegrationFn;
26+
27+
export const fastifyIntegration = defineIntegration(_fastifyIntegration);
28+
829
/**
930
* Express integration
1031
*
1132
* Capture tracing data for fastify.
33+
*
34+
* @deprecated Use `fastifyIntegration()` instead.
1235
*/
1336
export class Fastify extends NodePerformanceIntegration<void> implements Integration {
1437
/**
@@ -23,6 +46,7 @@ export class Fastify extends NodePerformanceIntegration<void> implements Integra
2346

2447
public constructor() {
2548
super();
49+
// eslint-disable-next-line deprecation/deprecation
2650
this.name = Fastify.id;
2751
}
2852

Lines changed: 25 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,32 @@
11
import type { Integration } from '@sentry/types';
22

3-
import type { NodePerformanceIntegration } from './NodePerformanceIntegration';
4-
import { Express } from './express';
5-
import { Fastify } from './fastify';
6-
import { GraphQL } from './graphql';
7-
import { Hapi } from './hapi';
8-
import { Mongo } from './mongo';
9-
import { Mongoose } from './mongoose';
10-
import { Mysql } from './mysql';
11-
import { Mysql2 } from './mysql2';
12-
import { Nest } from './nest';
13-
import { Postgres } from './postgres';
14-
import { Prisma } from './prisma';
15-
16-
const INTEGRATIONS: (() => NodePerformanceIntegration<unknown>)[] = [
17-
() => {
18-
return new Express();
19-
},
20-
() => {
21-
return new Fastify();
22-
},
23-
() => {
24-
return new GraphQL();
25-
},
26-
() => {
27-
return new Mongo();
28-
},
29-
() => {
30-
return new Mongoose();
31-
},
32-
() => {
33-
return new Mysql();
34-
},
35-
() => {
36-
return new Mysql2();
37-
},
38-
() => {
39-
return new Postgres();
40-
},
41-
() => {
42-
return new Prisma();
43-
},
44-
() => {
45-
return new Nest();
46-
},
47-
() => {
48-
return new Hapi();
49-
},
50-
];
3+
import { expressIntegration } from './express';
4+
import { fastifyIntegration } from './fastify';
5+
import { graphqlIntegration } from './graphql';
6+
import { hapiIntegration } from './hapi';
7+
import { mongoIntegration } from './mongo';
8+
import { mongooseIntegration } from './mongoose';
9+
import { mysqlIntegration } from './mysql';
10+
import { mysql2Integration } from './mysql2';
11+
import { nestIntegration } from './nest';
12+
import { postgresIntegration } from './postgres';
13+
import { prismaIntegration } from './prisma';
5114

5215
/**
53-
* Get auto-dsicovered performance integrations.
54-
* Note that due to the way OpenTelemetry instrumentation works, this will generally still return Integrations
55-
* for stuff that may not be installed. This is because Otel only instruments when the module is imported/required,
56-
* so if the package is not required at all it will not be patched, and thus not instrumented.
57-
* But the _Sentry_ Integration will still be added.
58-
* This _may_ be a bit confusing because it shows all integrations as being installed in the debug logs, but this is
59-
* technically not wrong because we install it (it just doesn't do anything).
16+
* With OTEL, all performance integrations will be added, as OTEL only initializes them when the patched package is actually required.
6017
*/
6118
export function getAutoPerformanceIntegrations(): Integration[] {
62-
const loadedIntegrations = INTEGRATIONS.map(tryLoad => {
63-
try {
64-
const integration = tryLoad();
65-
const isLoaded = integration.loadInstrumentations();
66-
return isLoaded ? integration : false;
67-
} catch (_) {
68-
return false;
69-
}
70-
}).filter(integration => !!integration) as Integration[];
71-
72-
return loadedIntegrations;
19+
return [
20+
expressIntegration(),
21+
fastifyIntegration(),
22+
graphqlIntegration(),
23+
mongoIntegration(),
24+
mongooseIntegration(),
25+
mysqlIntegration(),
26+
mysql2Integration(),
27+
postgresIntegration(),
28+
prismaIntegration(),
29+
nestIntegration(),
30+
hapiIntegration(),
31+
];
7332
}

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

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,38 @@
11
import type { Instrumentation } from '@opentelemetry/instrumentation';
2+
import { registerInstrumentations } from '@opentelemetry/instrumentation';
23
import { GraphQLInstrumentation } from '@opentelemetry/instrumentation-graphql';
3-
import type { Integration } from '@sentry/types';
4+
import { defineIntegration } from '@sentry/core';
5+
import type { Integration, IntegrationFn } from '@sentry/types';
46

57
import { addOriginToSpan } from '../utils/addOriginToSpan';
68
import { NodePerformanceIntegration } from './NodePerformanceIntegration';
79

10+
const _graphqlIntegration = (() => {
11+
return {
12+
name: 'Graphql',
13+
setupOnce() {
14+
registerInstrumentations({
15+
instrumentations: [
16+
new GraphQLInstrumentation({
17+
ignoreTrivialResolveSpans: true,
18+
responseHook(span) {
19+
addOriginToSpan(span, 'auto.graphql.otel.graphql');
20+
},
21+
}),
22+
],
23+
});
24+
},
25+
};
26+
}) satisfies IntegrationFn;
27+
28+
export const graphqlIntegration = defineIntegration(_graphqlIntegration);
29+
830
/**
931
* GraphQL integration
1032
*
1133
* Capture tracing data for GraphQL.
34+
*
35+
* @deprecated Use `graphqlIntegration()` instead.
1236
*/
1337
export class GraphQL extends NodePerformanceIntegration<void> implements Integration {
1438
/**
@@ -23,6 +47,7 @@ export class GraphQL extends NodePerformanceIntegration<void> implements Integra
2347

2448
public constructor() {
2549
super();
50+
// eslint-disable-next-line deprecation/deprecation
2651
this.name = GraphQL.id;
2752
}
2853

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,30 @@
11
import type { Instrumentation } from '@opentelemetry/instrumentation';
2+
import { registerInstrumentations } from '@opentelemetry/instrumentation';
23
import { HapiInstrumentation } from '@opentelemetry/instrumentation-hapi';
3-
import type { Integration } from '@sentry/types';
4+
import { defineIntegration } from '@sentry/core';
5+
import type { Integration, IntegrationFn } from '@sentry/types';
46

57
import { NodePerformanceIntegration } from './NodePerformanceIntegration';
68

9+
const _hapiIntegration = (() => {
10+
return {
11+
name: 'Hapi',
12+
setupOnce() {
13+
registerInstrumentations({
14+
instrumentations: [new HapiInstrumentation()],
15+
});
16+
},
17+
};
18+
}) satisfies IntegrationFn;
19+
20+
export const hapiIntegration = defineIntegration(_hapiIntegration);
21+
722
/**
823
* Hapi integration
924
*
1025
* Capture tracing data for Hapi.
26+
*
27+
* @deprecated Use `hapiIntegration()` instead.
1128
*/
1229
export class Hapi extends NodePerformanceIntegration<void> implements Integration {
1330
/**
@@ -22,6 +39,7 @@ export class Hapi extends NodePerformanceIntegration<void> implements Integratio
2239

2340
public constructor() {
2441
super();
42+
// eslint-disable-next-line deprecation/deprecation
2543
this.name = Hapi.id;
2644
}
2745

0 commit comments

Comments
 (0)