Skip to content

Commit 545ea04

Browse files
committed
First non-working implementation of injectable patch
1 parent b2dded8 commit 545ea04

File tree

1 file changed

+96
-1
lines changed
  • packages/node/src/integrations/tracing

1 file changed

+96
-1
lines changed

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

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ import {
1212
import type { IntegrationFn, Span } from '@sentry/types';
1313
import { logger } from '@sentry/utils';
1414
import { generateInstrumentOnce } from '../../otel/instrument';
15+
import type { InstrumentationConfig } from '@opentelemetry/instrumentation';
16+
import {
17+
InstrumentationBase,
18+
InstrumentationNodeModuleDefinition, InstrumentationNodeModuleFile
19+
} from '@opentelemetry/instrumentation';
20+
import { isWrapped } from '@opentelemetry/core';
1521

1622
interface MinimalNestJsExecutionContext {
1723
getType: () => string;
@@ -44,7 +50,96 @@ interface MinimalNestJsApp {
4450

4551
const INTEGRATION_NAME = 'Nest';
4652

47-
export const instrumentNest = generateInstrumentOnce(INTEGRATION_NAME, () => new NestInstrumentation());
53+
const supportedVersions = ['>=8.0.0 <11'];
54+
55+
/**
56+
*
57+
*/
58+
export class SentryNestInstrumentation extends InstrumentationBase {
59+
public static readonly COMPONENT = '@nestjs/common';
60+
public static readonly COMMON_ATTRIBUTES = {
61+
component: SentryNestInstrumentation.COMPONENT,
62+
};
63+
64+
public constructor(config: InstrumentationConfig = {}) {
65+
super('sentry-nestjs', '1.0.0', config);
66+
}
67+
68+
/**
69+
*
70+
*/
71+
public init(): void {
72+
logger.log('init!');
73+
const module = new InstrumentationNodeModuleDefinition(
74+
SentryNestInstrumentation.COMPONENT,
75+
supportedVersions
76+
)
77+
78+
module.files.push(
79+
this._getInjectableFileInstrumentation(supportedVersions)
80+
)
81+
}
82+
83+
/**
84+
*
85+
*/
86+
private _getInjectableFileInstrumentation(versions: string[]): InstrumentationNodeModuleFile {
87+
logger.log('create instrumentation node module file');
88+
return new InstrumentationNodeModuleFile(
89+
'@nestjs/common/decorators/core/injectable.decorator.js',
90+
versions,
91+
(moduleExports: any) => {
92+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
93+
if (isWrapped(moduleExports.Injectable)) {
94+
this._unwrap(moduleExports, 'Injectable');
95+
}
96+
this._wrap(moduleExports, 'Injectable', this._createWrapInjectable());
97+
return moduleExports;
98+
},
99+
(moduleExports: any) => {
100+
this._unwrap(moduleExports, 'Injectable');
101+
}
102+
)
103+
}
104+
105+
/**
106+
*
107+
*/
108+
private _createWrapInjectable() {
109+
return function wrapInjectable(original: any) {
110+
return function wrappedInjectable(options?: any) {
111+
return function (target: any) {
112+
logger.log('Injectable target:', target);
113+
114+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
115+
if (typeof target.prototype.use === 'function') {
116+
logger.log('middleware!');
117+
}
118+
119+
return original(options)(target);
120+
};
121+
};
122+
};
123+
}
124+
}
125+
126+
const instrumentNestCore = generateInstrumentOnce('Nest-Core', () => {
127+
logger.log('init nest core instrumentation');
128+
return new NestInstrumentation();
129+
});
130+
131+
const instrumentMiddleware = generateInstrumentOnce('Nest-Middleware', () => {
132+
logger.log('init nest middleware instrumentation');
133+
return new SentryNestInstrumentation();
134+
});
135+
136+
export const instrumentNest = Object.assign(
137+
(): void => {
138+
instrumentNestCore();
139+
instrumentMiddleware();
140+
},
141+
{ id: INTEGRATION_NAME },
142+
);
48143

49144
const _nestIntegration = (() => {
50145
return {

0 commit comments

Comments
 (0)