@senzops/apm-node 1.1.12 → 1.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.global.js +1 -1
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/core/client.ts +133 -2
- package/src/instrumentation/bullmq.ts +175 -50
- package/src/instrumentation/cron.ts +190 -27
- package/src/instrumentation/hook.ts +240 -17
- package/src/utils/sdkMeta.ts +6 -0
- package/tsconfig.json +1 -0
|
@@ -1,24 +1,247 @@
|
|
|
1
1
|
import Module from 'module';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
const SENZOR_PATCHED =
|
|
4
|
+
Symbol.for('senzor.require.patched');
|
|
5
|
+
|
|
6
|
+
const SENZOR_HOOKS =
|
|
7
|
+
Symbol.for('senzor.require.hooks');
|
|
8
|
+
|
|
9
|
+
type HookFn =
|
|
10
|
+
(exports: unknown) => void;
|
|
11
|
+
|
|
12
|
+
type HookMap =
|
|
13
|
+
Map<string, HookFn[]>;
|
|
14
|
+
|
|
15
|
+
function getHookRegistry(): HookMap {
|
|
16
|
+
|
|
17
|
+
const mod =
|
|
18
|
+
Module as unknown as Record<
|
|
19
|
+
symbol,
|
|
20
|
+
HookMap
|
|
21
|
+
>;
|
|
22
|
+
|
|
23
|
+
if (!mod[SENZOR_HOOKS]) {
|
|
24
|
+
|
|
25
|
+
Object.defineProperty(
|
|
26
|
+
mod,
|
|
27
|
+
SENZOR_HOOKS,
|
|
28
|
+
{
|
|
29
|
+
value: new Map(),
|
|
30
|
+
enumerable: false
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return mod[SENZOR_HOOKS];
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function runHooks(
|
|
41
|
+
moduleName: string,
|
|
42
|
+
exports: unknown
|
|
43
|
+
) {
|
|
44
|
+
|
|
45
|
+
const registry =
|
|
46
|
+
(Module as unknown as Record<
|
|
47
|
+
symbol,
|
|
48
|
+
HookMap
|
|
49
|
+
>)[SENZOR_HOOKS];
|
|
50
|
+
|
|
51
|
+
if (!registry) return;
|
|
52
|
+
|
|
53
|
+
const hooks =
|
|
54
|
+
registry.get(moduleName);
|
|
55
|
+
|
|
56
|
+
if (!hooks?.length) return;
|
|
57
|
+
|
|
58
|
+
for (const hook of hooks) {
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
hook(exports);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
|
|
65
|
+
console.error(
|
|
66
|
+
`[Senzor] instrumentation failed for ${moduleName}`,
|
|
67
|
+
err
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function patchLoaderOnce() {
|
|
77
|
+
|
|
78
|
+
const mod =
|
|
79
|
+
Module as unknown as any;
|
|
80
|
+
|
|
81
|
+
if (mod[SENZOR_PATCHED]) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const previousLoad =
|
|
86
|
+
mod._load;
|
|
87
|
+
|
|
88
|
+
mod._load =
|
|
89
|
+
function patchedLoad(
|
|
90
|
+
request: string,
|
|
91
|
+
parent: unknown,
|
|
92
|
+
isMain: boolean
|
|
93
|
+
) {
|
|
94
|
+
|
|
95
|
+
const exports =
|
|
96
|
+
previousLoad.apply(
|
|
97
|
+
this,
|
|
98
|
+
arguments
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
runHooks(
|
|
102
|
+
request,
|
|
103
|
+
exports
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
return exports;
|
|
107
|
+
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
Object.defineProperty(
|
|
111
|
+
mod,
|
|
112
|
+
SENZOR_PATCHED,
|
|
113
|
+
{
|
|
114
|
+
value: true,
|
|
115
|
+
enumerable: false
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function patchCached(
|
|
122
|
+
moduleName: string,
|
|
123
|
+
hook: HookFn
|
|
124
|
+
) {
|
|
125
|
+
|
|
5
126
|
try {
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
127
|
+
|
|
128
|
+
const resolved =
|
|
129
|
+
require.resolve(
|
|
130
|
+
moduleName
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
const cached =
|
|
134
|
+
require.cache?.[
|
|
135
|
+
resolved
|
|
136
|
+
];
|
|
137
|
+
|
|
138
|
+
if (cached?.exports) {
|
|
139
|
+
|
|
140
|
+
hook(
|
|
141
|
+
cached.exports
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
}
|
|
147
|
+
catch { }
|
|
148
|
+
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function tryRequire(
|
|
152
|
+
moduleName: string,
|
|
153
|
+
hook: HookFn
|
|
154
|
+
) {
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
|
|
158
|
+
const mod =
|
|
159
|
+
require(moduleName);
|
|
160
|
+
|
|
161
|
+
if (mod) {
|
|
162
|
+
hook(mod);
|
|
10
163
|
}
|
|
11
|
-
|
|
12
|
-
// Silently ignore if module is not installed
|
|
164
|
+
|
|
13
165
|
}
|
|
166
|
+
catch { }
|
|
167
|
+
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function retryPatch(
|
|
171
|
+
moduleName: string,
|
|
172
|
+
hook: HookFn
|
|
173
|
+
) {
|
|
174
|
+
|
|
175
|
+
let attempts = 0;
|
|
176
|
+
|
|
177
|
+
const max = 5;
|
|
178
|
+
|
|
179
|
+
const timer =
|
|
180
|
+
setInterval(() => {
|
|
181
|
+
|
|
182
|
+
attempts++;
|
|
183
|
+
|
|
184
|
+
try {
|
|
185
|
+
|
|
186
|
+
const mod =
|
|
187
|
+
require(moduleName);
|
|
188
|
+
|
|
189
|
+
if (mod) {
|
|
190
|
+
|
|
191
|
+
hook(mod);
|
|
192
|
+
|
|
193
|
+
clearInterval(timer);
|
|
194
|
+
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
}
|
|
198
|
+
catch { }
|
|
199
|
+
|
|
200
|
+
if (attempts >= max) {
|
|
201
|
+
clearInterval(timer);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
}, 200);
|
|
205
|
+
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export const hookRequire =
|
|
209
|
+
(
|
|
210
|
+
moduleName: string,
|
|
211
|
+
onRequire: HookFn
|
|
212
|
+
) => {
|
|
213
|
+
|
|
214
|
+
const registry =
|
|
215
|
+
getHookRegistry();
|
|
216
|
+
|
|
217
|
+
if (!registry.has(moduleName)) {
|
|
218
|
+
|
|
219
|
+
registry.set(
|
|
220
|
+
moduleName,
|
|
221
|
+
[]
|
|
222
|
+
);
|
|
14
223
|
|
|
15
|
-
// 2. Intercept future requires
|
|
16
|
-
const originalLoad = (Module as any)._load;
|
|
17
|
-
(Module as any)._load = function (request: string, parent: any, isMain: boolean) {
|
|
18
|
-
const exports = originalLoad.apply(this, arguments);
|
|
19
|
-
if (request === moduleName && exports) {
|
|
20
|
-
onRequire(exports);
|
|
21
224
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
225
|
+
|
|
226
|
+
registry
|
|
227
|
+
.get(moduleName)!
|
|
228
|
+
.push(onRequire);
|
|
229
|
+
|
|
230
|
+
patchLoaderOnce();
|
|
231
|
+
|
|
232
|
+
patchCached(
|
|
233
|
+
moduleName,
|
|
234
|
+
onRequire
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
tryRequire(
|
|
238
|
+
moduleName,
|
|
239
|
+
onRequire
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
retryPatch(
|
|
243
|
+
moduleName,
|
|
244
|
+
onRequire
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
};
|