@senzops/apm-node 1.2.1 → 1.2.2

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.
Files changed (54) hide show
  1. package/.claude/worktrees/infallible-chatelet-f3fb36/.claude/settings.local.json +9 -0
  2. package/.claude/worktrees/infallible-chatelet-f3fb36/CHANGELOG.md +49 -0
  3. package/.claude/worktrees/infallible-chatelet-f3fb36/README.md +398 -0
  4. package/.claude/worktrees/infallible-chatelet-f3fb36/package-lock.json +1494 -0
  5. package/.claude/worktrees/infallible-chatelet-f3fb36/package.json +42 -0
  6. package/.claude/worktrees/infallible-chatelet-f3fb36/src/core/client.ts +451 -0
  7. package/.claude/worktrees/infallible-chatelet-f3fb36/src/core/context.ts +48 -0
  8. package/.claude/worktrees/infallible-chatelet-f3fb36/src/core/normalizer.ts +44 -0
  9. package/.claude/worktrees/infallible-chatelet-f3fb36/src/core/sanitizer.ts +203 -0
  10. package/.claude/worktrees/infallible-chatelet-f3fb36/src/core/transport.ts +273 -0
  11. package/.claude/worktrees/infallible-chatelet-f3fb36/src/core/types.ts +106 -0
  12. package/.claude/worktrees/infallible-chatelet-f3fb36/src/index.ts +36 -0
  13. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/bullmq.ts +195 -0
  14. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/cron.ts +204 -0
  15. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/express.ts +338 -0
  16. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/fastify.ts +296 -0
  17. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/framework.ts +301 -0
  18. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/hook.ts +134 -0
  19. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/http.ts +530 -0
  20. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/koa.ts +173 -0
  21. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/mongo.ts +202 -0
  22. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/mongoose.ts +156 -0
  23. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/mysql.ts +169 -0
  24. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/patch.ts +56 -0
  25. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/pg.ts +131 -0
  26. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/redis.ts +109 -0
  27. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/span.ts +73 -0
  28. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/undici.ts +189 -0
  29. package/.claude/worktrees/infallible-chatelet-f3fb36/src/middleware/express.ts +48 -0
  30. package/.claude/worktrees/infallible-chatelet-f3fb36/src/register.ts +58 -0
  31. package/.claude/worktrees/infallible-chatelet-f3fb36/src/utils/getClientIp.ts +175 -0
  32. package/.claude/worktrees/infallible-chatelet-f3fb36/src/utils/ids.ts +7 -0
  33. package/.claude/worktrees/infallible-chatelet-f3fb36/src/utils/internal.ts +1 -0
  34. package/.claude/worktrees/infallible-chatelet-f3fb36/src/utils/sdkMeta.ts +6 -0
  35. package/.claude/worktrees/infallible-chatelet-f3fb36/src/utils/traceContext.ts +44 -0
  36. package/.claude/worktrees/infallible-chatelet-f3fb36/src/wrappers/fastify.ts +35 -0
  37. package/.claude/worktrees/infallible-chatelet-f3fb36/src/wrappers/h3.ts +59 -0
  38. package/.claude/worktrees/infallible-chatelet-f3fb36/src/wrappers/next.ts +131 -0
  39. package/.claude/worktrees/infallible-chatelet-f3fb36/tsconfig.json +15 -0
  40. package/.claude/worktrees/infallible-chatelet-f3fb36/tsup.config.ts +21 -0
  41. package/.claude/worktrees/infallible-chatelet-f3fb36/wiki.md +852 -0
  42. package/CHANGELOG.md +4 -0
  43. package/dist/index.global.js +1 -1
  44. package/dist/index.global.js.map +1 -1
  45. package/dist/index.js +1 -1
  46. package/dist/index.js.map +1 -1
  47. package/dist/index.mjs +1 -1
  48. package/dist/index.mjs.map +1 -1
  49. package/dist/register.js +1 -1
  50. package/dist/register.js.map +1 -1
  51. package/dist/register.mjs +1 -1
  52. package/dist/register.mjs.map +1 -1
  53. package/package.json +1 -1
  54. package/src/instrumentation/hook.ts +85 -216
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@senzops/apm-node",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "Universal APM SDK for Senzor",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,265 +1,134 @@
1
1
  import Module from 'module';
2
2
 
3
- const SENZOR_PATCHED =
4
- Symbol.for('senzor.require.patched');
3
+ const SENZOR_PATCHED = Symbol.for('senzor.require.patched');
4
+ const SENZOR_HOOKS = Symbol.for('senzor.require.hooks');
5
5
 
6
- const SENZOR_HOOKS =
7
- Symbol.for('senzor.require.hooks');
6
+ type HookFn = (exports: unknown) => unknown | void;
7
+ type HookMap = Map<string, HookFn[]>;
8
8
 
9
- type HookFn =
10
- (exports: unknown) => unknown | void;
11
-
12
- type HookMap =
13
- Map<string, HookFn[]>;
9
+ // Module.createRequire works in both CJS and ESM contexts,
10
+ // unlike bare `require` which is unavailable in ESM builds.
11
+ const safeRequire: NodeRequire = Module.createRequire(
12
+ typeof __filename !== 'undefined'
13
+ ? __filename
14
+ : process.cwd() + '/'
15
+ );
14
16
 
15
17
  function getHookRegistry(): HookMap {
16
-
17
- const mod =
18
- Module as unknown as Record<
19
- symbol,
20
- HookMap
21
- >;
18
+ const mod = Module as unknown as Record<symbol, HookMap>;
22
19
 
23
20
  if (!mod[SENZOR_HOOKS]) {
24
-
25
- Object.defineProperty(
26
- mod,
27
- SENZOR_HOOKS,
28
- {
29
- value: new Map(),
30
- enumerable: false
31
- }
32
- );
33
-
21
+ Object.defineProperty(mod, SENZOR_HOOKS, {
22
+ value: new Map(),
23
+ enumerable: false
24
+ });
34
25
  }
35
26
 
36
27
  return mod[SENZOR_HOOKS];
37
-
38
28
  }
39
29
 
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];
30
+ function runHooks(moduleName: string, exports: unknown) {
31
+ const registry = (Module as unknown as Record<symbol, HookMap>)[SENZOR_HOOKS];
32
+ if (!registry) return exports;
50
33
 
51
- if (!registry) return exports;
34
+ const hooks = registry.get(moduleName);
35
+ if (!hooks?.length) return exports;
52
36
 
53
- const hooks =
54
- registry.get(moduleName);
55
-
56
- if (!hooks?.length) return exports;
57
-
58
- let currentExports =
59
- exports;
60
-
61
- for (const hook of hooks) {
62
-
63
- try {
64
- const nextExports =
65
- hook(currentExports);
66
-
67
- if (nextExports !== undefined) {
68
- currentExports =
69
- nextExports;
70
- }
71
- }
72
- catch (err) {
73
-
74
- console.error(
75
- `[Senzor] instrumentation failed for ${moduleName}`,
76
- err
77
- );
37
+ let currentExports = exports;
78
38
 
39
+ for (const hook of hooks) {
40
+ try {
41
+ const nextExports = hook(currentExports);
42
+ if (nextExports !== undefined) {
43
+ currentExports = nextExports;
44
+ }
45
+ } catch (err) {
46
+ console.error(`[Senzor] instrumentation failed for ${moduleName}`, err);
79
47
  }
80
-
81
- }
82
-
83
- return currentExports;
84
-
85
- }
86
-
87
- function patchLoaderOnce() {
88
-
89
- const mod =
90
- Module as unknown as any;
91
-
92
- if (mod[SENZOR_PATCHED]) {
93
- return;
94
48
  }
95
49
 
96
- const previousLoad =
97
- mod._load;
50
+ return currentExports;
51
+ }
98
52
 
99
- mod._load =
100
- function patchedLoad(
101
- request: string,
102
- parent: unknown,
103
- isMain: boolean
104
- ) {
53
+ function patchLoaderOnce() {
54
+ const mod = Module as unknown as any;
105
55
 
106
- const exports =
107
- previousLoad.apply(
108
- this,
109
- arguments
110
- );
56
+ if (mod[SENZOR_PATCHED]) return;
111
57
 
112
- const patchedExports =
113
- runHooks(
114
- request,
115
- exports
116
- );
117
-
118
- return patchedExports;
58
+ const previousLoad = mod._load;
119
59
 
120
- };
121
-
122
- Object.defineProperty(
123
- mod,
124
- SENZOR_PATCHED,
125
- {
126
- value: true,
127
- enumerable: false
128
- }
129
- );
60
+ mod._load = function patchedLoad(
61
+ request: string,
62
+ parent: unknown,
63
+ isMain: boolean
64
+ ) {
65
+ const exports = previousLoad.apply(this, arguments);
66
+ return runHooks(request, exports);
67
+ };
130
68
 
69
+ Object.defineProperty(mod, SENZOR_PATCHED, {
70
+ value: true,
71
+ enumerable: false
72
+ });
131
73
  }
132
74
 
133
- function patchCached(
134
- moduleName: string,
135
- hook: HookFn
136
- ) {
137
-
75
+ function patchCached(moduleName: string, hook: HookFn) {
138
76
  try {
139
-
140
- const resolved =
141
- require.resolve(
142
- moduleName
143
- );
144
-
145
- const cached =
146
- require.cache?.[
147
- resolved
148
- ];
77
+ const resolved = safeRequire.resolve(moduleName);
78
+ const cached = safeRequire.cache?.[resolved];
149
79
 
150
80
  if (cached?.exports) {
151
-
152
- const replacement =
153
- hook(
154
- cached.exports
155
- );
156
-
157
- if (replacement !== undefined) {
158
- cached.exports =
159
- replacement;
160
- }
161
-
162
- }
163
-
164
- }
165
- catch { }
166
-
81
+ const replacement = hook(cached.exports);
82
+ if (replacement !== undefined) {
83
+ cached.exports = replacement;
84
+ }
85
+ }
86
+ } catch { }
167
87
  }
168
88
 
169
- function tryRequire(
170
- moduleName: string,
171
- hook: HookFn
172
- ) {
173
-
89
+ function tryRequire(moduleName: string, hook: HookFn) {
174
90
  try {
175
-
176
- const mod =
177
- require(moduleName);
178
-
91
+ const mod = safeRequire(moduleName);
179
92
  if (mod) {
180
- hook(mod);
93
+ hook(mod);
181
94
  }
182
-
183
- }
184
- catch { }
185
-
95
+ } catch { }
186
96
  }
187
97
 
188
- function retryPatch(
189
- moduleName: string,
190
- hook: HookFn
191
- ) {
192
-
98
+ function retryPatch(moduleName: string, hook: HookFn) {
193
99
  let attempts = 0;
194
-
195
100
  const max = 5;
196
101
 
197
- const timer =
198
- setInterval(() => {
199
-
200
- attempts++;
201
-
202
- try {
203
-
204
- const mod =
205
- require(moduleName);
206
-
207
- if (mod) {
208
-
209
- hook(mod);
102
+ const timer = setInterval(() => {
103
+ attempts++;
210
104
 
211
- clearInterval(timer);
212
-
213
- }
214
-
215
- }
216
- catch { }
217
-
218
- if (attempts >= max) {
105
+ try {
106
+ const mod = safeRequire(moduleName);
107
+ if (mod) {
108
+ hook(mod);
219
109
  clearInterval(timer);
220
110
  }
111
+ } catch { }
221
112
 
222
- }, 200);
223
-
224
- }
225
-
226
- export const hookRequire =
227
- (
228
- moduleName: string,
229
- onRequire: HookFn
230
- ) => {
231
-
232
- const registry =
233
- getHookRegistry();
234
-
235
- if (!registry.has(moduleName)) {
236
-
237
- registry.set(
238
- moduleName,
239
- []
240
- );
241
-
113
+ if (attempts >= max) {
114
+ clearInterval(timer);
242
115
  }
116
+ }, 200);
243
117
 
244
- registry
245
- .get(moduleName)!
246
- .push(onRequire);
247
-
248
- patchLoaderOnce();
118
+ if (typeof timer.unref === 'function') timer.unref();
119
+ }
249
120
 
250
- patchCached(
251
- moduleName,
252
- onRequire
253
- );
121
+ export const hookRequire = (moduleName: string, onRequire: HookFn) => {
122
+ const registry = getHookRegistry();
254
123
 
255
- tryRequire(
256
- moduleName,
257
- onRequire
258
- );
124
+ if (!registry.has(moduleName)) {
125
+ registry.set(moduleName, []);
126
+ }
259
127
 
260
- retryPatch(
261
- moduleName,
262
- onRequire
263
- );
128
+ registry.get(moduleName)!.push(onRequire);
264
129
 
265
- };
130
+ patchLoaderOnce();
131
+ patchCached(moduleName, onRequire);
132
+ tryRequire(moduleName, onRequire);
133
+ retryPatch(moduleName, onRequire);
134
+ };