node-runtime-guardian 0.1.0

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 (59) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +423 -0
  3. package/dist/core/EventLoopMonitor.d.ts +32 -0
  4. package/dist/core/EventLoopMonitor.d.ts.map +1 -0
  5. package/dist/core/EventLoopMonitor.js +131 -0
  6. package/dist/core/EventLoopMonitor.js.map +1 -0
  7. package/dist/core/GCMonitor.d.ts +32 -0
  8. package/dist/core/GCMonitor.d.ts.map +1 -0
  9. package/dist/core/GCMonitor.js +151 -0
  10. package/dist/core/GCMonitor.js.map +1 -0
  11. package/dist/core/Guardian.d.ts +76 -0
  12. package/dist/core/Guardian.d.ts.map +1 -0
  13. package/dist/core/Guardian.js +196 -0
  14. package/dist/core/Guardian.js.map +1 -0
  15. package/dist/core/HeuristicEngine.d.ts +27 -0
  16. package/dist/core/HeuristicEngine.d.ts.map +1 -0
  17. package/dist/core/HeuristicEngine.js +150 -0
  18. package/dist/core/HeuristicEngine.js.map +1 -0
  19. package/dist/core/MemoryMonitor.d.ts +33 -0
  20. package/dist/core/MemoryMonitor.d.ts.map +1 -0
  21. package/dist/core/MemoryMonitor.js +193 -0
  22. package/dist/core/MemoryMonitor.js.map +1 -0
  23. package/dist/core/ProtectionLayer.d.ts +42 -0
  24. package/dist/core/ProtectionLayer.d.ts.map +1 -0
  25. package/dist/core/ProtectionLayer.js +105 -0
  26. package/dist/core/ProtectionLayer.js.map +1 -0
  27. package/dist/core/ThreadPoolMonitor.d.ts +29 -0
  28. package/dist/core/ThreadPoolMonitor.d.ts.map +1 -0
  29. package/dist/core/ThreadPoolMonitor.js +144 -0
  30. package/dist/core/ThreadPoolMonitor.js.map +1 -0
  31. package/dist/index.d.ts +18 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +53 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/plugins/Plugin.d.ts +53 -0
  36. package/dist/plugins/Plugin.d.ts.map +1 -0
  37. package/dist/plugins/Plugin.js +74 -0
  38. package/dist/plugins/Plugin.js.map +1 -0
  39. package/dist/plugins/index.d.ts +2 -0
  40. package/dist/plugins/index.d.ts.map +1 -0
  41. package/dist/plugins/index.js +18 -0
  42. package/dist/plugins/index.js.map +1 -0
  43. package/dist/server/MetricsServer.d.ts +26 -0
  44. package/dist/server/MetricsServer.d.ts.map +1 -0
  45. package/dist/server/MetricsServer.js +86 -0
  46. package/dist/server/MetricsServer.js.map +1 -0
  47. package/dist/types/index.d.ts +104 -0
  48. package/dist/types/index.d.ts.map +1 -0
  49. package/dist/types/index.js +19 -0
  50. package/dist/types/index.js.map +1 -0
  51. package/dist/types/metrics.d.ts +67 -0
  52. package/dist/types/metrics.d.ts.map +1 -0
  53. package/dist/types/metrics.js +3 -0
  54. package/dist/types/metrics.js.map +1 -0
  55. package/dist/worker/WorkerPool.d.ts +44 -0
  56. package/dist/worker/WorkerPool.d.ts.map +1 -0
  57. package/dist/worker/WorkerPool.js +214 -0
  58. package/dist/worker/WorkerPool.js.map +1 -0
  59. package/package.json +63 -0
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Node Runtime Guardian Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md ADDED
@@ -0,0 +1,423 @@
1
+ <div align="center">
2
+ <h1>Node Runtime Guardian</h1>
3
+ <img src="assets/node-runtime-guardian.gif" alt="Node Runtime Guardian Logo" width="600">
4
+ <p><strong>Runtime visibility and self-protection for Node.js applications</strong></p>
5
+ </div>
6
+
7
+ ---
8
+
9
+ Node Runtime Guardian is a lightweight, dependency-free runtime diagnostics and protection layer for Node.js. It runs inside your process to observe event loop health, memory behavior, garbage collection pressure, and thread pool saturation — and can optionally shed load when your application is under stress.
10
+
11
+ This project is intentionally calm, explicit, and production-focused. It is built for backend developers who want to understand how the Node.js runtime behaves under real load, not just what dashboards report after the fact.
12
+
13
+ ## Table of Contents
14
+
15
+ - [Why This Exists](#why-this-exists)
16
+ - [When Should You Use This?](#when-should-you-use-this)
17
+ - [Features](#features)
18
+ - [Installation](#installation)
19
+ - [Quick Start](#quick-start)
20
+ - [Documentation](#documentation)
21
+ - [API Reference](#api-documentation)
22
+ - [Usage Examples](#usage-examples)
23
+ - [Metrics](#metrics)
24
+ - [Development](#development)
25
+ - [Contributing](#contributing)
26
+ - [License](#license)
27
+
28
+ ## Why This Exists
29
+
30
+ Most Node.js production issues don't show up as errors.
31
+
32
+ They show up as:
33
+
34
+ - **Latency spikes** with no obvious cause
35
+ - **Memory usage** slowly creeping upward
36
+ - **GC pauses** causing jittery response times
37
+ - **Pods restarting** due to OOM without clear signals
38
+ - **Services degrading** under burst traffic
39
+
40
+ By the time traditional monitoring alerts fire, the system is often already unhealthy.
41
+
42
+ Node Runtime Guardian was built to observe these problems from inside the Node.js runtime itself — where the event loop, garbage collector, and thread pool actually live.
43
+
44
+ ## When Should You Use This?
45
+
46
+ Node Runtime Guardian is useful if:
47
+
48
+ - You suspect event loop blocking or synchronous CPU work
49
+ - Your service slows down under load without throwing errors
50
+ - Memory usage grows steadily and heap snapshots aren't obvious
51
+ - You want runtime insight without a full APM stack
52
+ - You want a last-line defense against cascading failures
53
+
54
+ It is especially well-suited for:
55
+
56
+ - High-traffic API servers
57
+ - Background workers and job processors
58
+ - Memory-constrained containers
59
+ - High-throughput Node.js services
60
+
61
+ ## Features
62
+
63
+ - **Event Loop Monitoring**: Track event loop delay using `perf_hooks`
64
+ - **Memory Monitoring**: Detect memory leaks and drift patterns
65
+ - **GC Pressure Estimation**: Monitor garbage collection behavior
66
+ - **Thread Pool Saturation Detection**: Infer thread pool queue buildup
67
+ - **Load Shedding**: Automatic request rejection when thresholds are exceeded
68
+ - **Metrics Endpoint**: HTTP endpoint for runtime metrics
69
+ - **Plugin System**: Extensible architecture for custom integrations
70
+ - **Worker Thread Pool**: Managed worker pool utility
71
+ - **Zero Dependencies**: Uses only Node.js built-in modules
72
+
73
+ ## Installation
74
+
75
+ ```bash
76
+ npm install node-runtime-guardian
77
+ ```
78
+
79
+ ## Quick Start
80
+
81
+ ```typescript
82
+ import { Guardian } from 'node-runtime-guardian';
83
+
84
+ // Initialize Guardian
85
+ const guardian = new Guardian({
86
+ eventLoop: {
87
+ thresholdMs: 100,
88
+ },
89
+ memory: {
90
+ rssLimit: 512 * 1024 * 1024, // 512MB
91
+ driftDetectionEnabled: true,
92
+ },
93
+ protection: {
94
+ enabled: true,
95
+ loadShedding: {
96
+ enabled: true,
97
+ eventLoopThreshold: 200,
98
+ },
99
+ },
100
+ metricsServer: {
101
+ enabled: true,
102
+ port: 9090,
103
+ },
104
+ });
105
+
106
+ // Start monitoring
107
+ guardian.start();
108
+
109
+ // Listen for warnings
110
+ guardian.on('warning', (warning) => {
111
+ console.warn('Guardian warning:', warning);
112
+ });
113
+
114
+ // Get current metrics
115
+ const metrics = guardian.getMetrics();
116
+ console.log('Health score:', guardian.getHealthScore());
117
+ ```
118
+
119
+ > 💡 **Tip**: For more detailed examples and configuration options, see the [Usage Documentation](docs/USAGE.md).
120
+
121
+ ## Documentation
122
+
123
+ 📖 **For comprehensive usage guides, configuration options, integration patterns, and best practices, see the [Usage Documentation](docs/USAGE.md).**
124
+
125
+ The [Usage Documentation](docs/USAGE.md) provides detailed information on:
126
+
127
+ - **Configuration Examples**: Development, production, memory-sensitive, and CPU-intensive setups
128
+ - **Integration Patterns**: Express.js, Fastify, Koa.js middleware integration
129
+ - **Usage Patterns**: Background job monitoring, microservices health reporting
130
+ - **Best Practices**: Configuration tuning, event handling, request tracking
131
+ - **Troubleshooting**: Common issues and solutions
132
+ - **Advanced Topics**: Custom health scoring, APM integration, metrics export
133
+
134
+ ## API Documentation
135
+
136
+ ### Guardian Class
137
+
138
+ Main class that orchestrates all monitoring and protection.
139
+
140
+ #### Constructor
141
+
142
+ ```typescript
143
+ new Guardian(config?: GuardianConfig)
144
+ ```
145
+
146
+ #### Methods
147
+
148
+ - `init(config?: GuardianConfig): void` - Initialize and start monitoring
149
+ - `start(): void` - Start all monitors
150
+ - `stop(): void` - Stop all monitors
151
+ - `getMetrics(): RuntimeMetrics` - Get current aggregated metrics
152
+ - `getHealthScore(): number` - Get health score (0-1, where 1 is healthy)
153
+ - `isProtectionActive(): boolean` - Check if protection is active
154
+ - `shouldRejectRequest(): boolean` - Check if a request should be rejected
155
+ - `getRejectionResponse(): { statusCode: number; message: string }` - Get rejection response
156
+ - `trackRequest(): void` - Track incoming request
157
+ - `trackRequestComplete(): void` - Track completed request
158
+
159
+ #### Events
160
+
161
+ - `metric` - Emitted when metrics are collected
162
+ - `warning` - Emitted when thresholds are exceeded
163
+ - `eventLoopBlocked` - Emitted when event loop delay exceeds threshold
164
+ - `memoryDrift` - Emitted when memory drift is detected
165
+ - `gcPressure` - Emitted when GC pressure is high
166
+ - `threadPoolSaturated` - Emitted when thread pool is saturated
167
+ - `protectionActivated` - Emitted when protection is activated
168
+ - `protectionDeactivated` - Emitted when protection is deactivated
169
+
170
+ ### Configuration
171
+
172
+ ```typescript
173
+ interface GuardianConfig {
174
+ eventLoop?: {
175
+ enabled?: boolean;
176
+ thresholdMs?: number; // Default: 100
177
+ intervalMs?: number; // Default: 1000
178
+ };
179
+ memory?: {
180
+ enabled?: boolean;
181
+ rssLimit?: number;
182
+ heapLimit?: number;
183
+ externalLimit?: number;
184
+ driftDetectionEnabled?: boolean; // Default: true
185
+ driftThreshold?: number; // Default: 0.1
186
+ };
187
+ gc?: {
188
+ enabled?: boolean;
189
+ pressureThreshold?: number; // Default: 0.7
190
+ };
191
+ threadPool?: {
192
+ enabled?: boolean;
193
+ saturationThreshold?: number; // Default: 0.8
194
+ };
195
+ protection?: {
196
+ enabled?: boolean;
197
+ loadShedding?: {
198
+ enabled?: boolean;
199
+ eventLoopThreshold?: number; // Default: 200
200
+ memoryThreshold?: number; // Default: 0.9
201
+ responseCode?: number; // Default: 503
202
+ responseMessage?: string;
203
+ };
204
+ };
205
+ metricsServer?: {
206
+ enabled?: boolean;
207
+ port?: number; // Default: 9090
208
+ path?: string; // Default: '/guardian/metrics'
209
+ };
210
+ workerPool?: {
211
+ enabled?: boolean;
212
+ poolSize?: number; // Default: 4
213
+ maxQueueSize?: number; // Default: 100
214
+ };
215
+ }
216
+ ```
217
+
218
+ ## Usage Examples
219
+
220
+ > 📚 **See [Usage Documentation](docs/USAGE.md) for more comprehensive examples including Express, Fastify, Koa.js integrations, and advanced patterns.**
221
+
222
+ ### Basic Monitoring
223
+
224
+ ```typescript
225
+ import { Guardian } from 'node-runtime-guardian';
226
+
227
+ const guardian = new Guardian({
228
+ eventLoop: { thresholdMs: 100 },
229
+ memory: { driftDetectionEnabled: true },
230
+ });
231
+
232
+ guardian.start();
233
+
234
+ guardian.on('warning', (warning) => {
235
+ console.error('Warning:', warning.message);
236
+ });
237
+ ```
238
+
239
+ ### Load Shedding Integration
240
+
241
+ ```typescript
242
+ import express from 'express';
243
+ import { Guardian } from 'node-runtime-guardian';
244
+
245
+ const app = express();
246
+ const guardian = new Guardian({
247
+ protection: {
248
+ enabled: true,
249
+ loadShedding: {
250
+ enabled: true,
251
+ eventLoopThreshold: 200,
252
+ },
253
+ },
254
+ });
255
+
256
+ guardian.start();
257
+
258
+ // Middleware to check protection
259
+ app.use((req, res, next) => {
260
+ guardian.trackRequest();
261
+
262
+ if (guardian.shouldRejectRequest()) {
263
+ const response = guardian.getRejectionResponse();
264
+ guardian.trackRequestComplete();
265
+ return res.status(response.statusCode).json({ error: response.message });
266
+ }
267
+
268
+ res.on('finish', () => {
269
+ guardian.trackRequestComplete();
270
+ });
271
+
272
+ next();
273
+ });
274
+
275
+ app.get('/api/data', (req, res) => {
276
+ res.json({ data: 'Hello World' });
277
+ });
278
+ ```
279
+
280
+ ### Metrics Endpoint
281
+
282
+ ```typescript
283
+ import { Guardian, MetricsServer } from 'node-runtime-guardian';
284
+
285
+ const guardian = new Guardian();
286
+ guardian.start();
287
+
288
+ const metricsServer = new MetricsServer(guardian, {
289
+ port: 9090,
290
+ path: '/guardian/metrics',
291
+ });
292
+
293
+ metricsServer.start();
294
+
295
+ // Access metrics at http://localhost:9090/guardian/metrics
296
+ ```
297
+
298
+ ### Plugin System
299
+
300
+ ```typescript
301
+ import {
302
+ Guardian,
303
+ GuardianPlugin,
304
+ RuntimeMetrics,
305
+ } from 'node-runtime-guardian';
306
+
307
+ class CustomLoggerPlugin implements GuardianPlugin {
308
+ name = 'custom-logger';
309
+
310
+ onMetricUpdate(data: RuntimeMetrics): void {
311
+ console.log('Metrics:', {
312
+ eventLoopDelay: data.eventLoopDelay.mean,
313
+ memory: data.memory.heapUsed,
314
+ health: data.healthScore,
315
+ });
316
+ }
317
+ }
318
+
319
+ const guardian = new Guardian();
320
+ guardian.start();
321
+
322
+ // Register plugin (would need plugin registry integration)
323
+ // This is a conceptual example
324
+ ```
325
+
326
+ ### Worker Pool
327
+
328
+ ```typescript
329
+ import { WorkerPool } from 'node-runtime-guardian';
330
+
331
+ const pool = new WorkerPool('./worker.js', {
332
+ poolSize: 4,
333
+ maxQueueSize: 100,
334
+ });
335
+
336
+ // Run a task
337
+ const result = await pool.run({ task: 'process-data' });
338
+
339
+ // Get pool statistics
340
+ const stats = pool.getStats();
341
+ console.log('Active tasks:', stats.activeTasks);
342
+ console.log('Queue size:', stats.queueSize);
343
+ ```
344
+
345
+ ## Metrics
346
+
347
+ The metrics endpoint returns the following data:
348
+
349
+ ```json
350
+ {
351
+ "eventLoopDelay": {
352
+ "mean": 2.5,
353
+ "max": 10.2,
354
+ "min": 0.1,
355
+ "p50": 2.0,
356
+ "p95": 8.5,
357
+ "p99": 9.8
358
+ },
359
+ "memory": {
360
+ "heapUsed": 52428800,
361
+ "heapTotal": 67108864,
362
+ "rss": 134217728,
363
+ "external": 1024000,
364
+ "arrayBuffers": 512000
365
+ },
366
+ "gc": {
367
+ "estimatedCycles": 15,
368
+ "minorGCCount": 12,
369
+ "majorGCCount": 3,
370
+ "gcPressure": 0.45
371
+ },
372
+ "threadPool": {
373
+ "saturationLevel": 0.2,
374
+ "estimatedQueueSize": 0.8,
375
+ "avgLatency": 0.5
376
+ },
377
+ "cpu": {
378
+ "user": 125.5,
379
+ "system": 45.2
380
+ },
381
+ "activeRequests": 5,
382
+ "healthScore": 0.85,
383
+ "isProtectionActive": false,
384
+ "timestamp": 1704067200000
385
+ }
386
+ ```
387
+
388
+ ## Development
389
+
390
+ ```bash
391
+ # Install dependencies
392
+ npm install
393
+
394
+ # Build
395
+ npm run build
396
+
397
+ # Run tests
398
+ npm test
399
+
400
+ # Lint
401
+ npm run lint
402
+
403
+ # Format code
404
+ npm run format
405
+ ```
406
+
407
+ ## Contributing
408
+
409
+ Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
410
+
411
+ ## License
412
+
413
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
414
+
415
+ ## Acknowledgments
416
+
417
+ - Built with TypeScript
418
+ - Uses Node.js built-in modules only
419
+ - Inspired by production monitoring needs
420
+
421
+ ---
422
+
423
+ **If this project helped you or sparked an idea, consider dropping a star or a kind word. It quietly keeps me motivated.**
@@ -0,0 +1,32 @@
1
+ /// <reference types="node" />
2
+ import { EventEmitter } from 'events';
3
+ import { EventLoopConfig, EventLoopMetrics } from '../types';
4
+ /**
5
+ * Monitors event loop delay using perf_hooks
6
+ */
7
+ export declare class EventLoopMonitor extends EventEmitter {
8
+ private monitor;
9
+ private interval;
10
+ private config;
11
+ private isRunning;
12
+ constructor(config?: EventLoopConfig);
13
+ /**
14
+ * Start monitoring event loop delay
15
+ */
16
+ start(): void;
17
+ /**
18
+ * Stop monitoring
19
+ */
20
+ stop(): void;
21
+ /**
22
+ * Collect current metrics
23
+ */
24
+ getMetrics(): EventLoopMetrics;
25
+ /**
26
+ * Reset monitor statistics
27
+ */
28
+ reset(): void;
29
+ private collectMetrics;
30
+ private getEmptyMetrics;
31
+ }
32
+ //# sourceMappingURL=EventLoopMonitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventLoopMonitor.d.ts","sourceRoot":"","sources":["../../src/core/EventLoopMonitor.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EACL,eAAe,EACf,gBAAgB,EAMjB,MAAM,UAAU,CAAC;AAElB;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,OAAO,CAAyD;IACxE,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,SAAS,CAAS;gBAEd,MAAM,GAAE,eAAoB;IASxC;;OAEG;IACH,KAAK,IAAI,IAAI;IAeb;;OAEG;IACH,IAAI,IAAI,IAAI;IAcZ;;OAEG;IACH,UAAU,IAAI,gBAAgB;IAgB9B;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb,OAAO,CAAC,cAAc;IAsDtB,OAAO,CAAC,eAAe;CAUxB"}
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventLoopMonitor = void 0;
4
+ const perf_hooks_1 = require("perf_hooks");
5
+ const events_1 = require("events");
6
+ /**
7
+ * Monitors event loop delay using perf_hooks
8
+ */
9
+ class EventLoopMonitor extends events_1.EventEmitter {
10
+ constructor(config = {}) {
11
+ super();
12
+ this.monitor = null;
13
+ this.interval = null;
14
+ this.isRunning = false;
15
+ this.config = {
16
+ enabled: config.enabled ?? true,
17
+ thresholdMs: config.thresholdMs ?? 100,
18
+ intervalMs: config.intervalMs ?? 1000,
19
+ };
20
+ }
21
+ /**
22
+ * Start monitoring event loop delay
23
+ */
24
+ start() {
25
+ if (!this.config.enabled || this.isRunning) {
26
+ return;
27
+ }
28
+ this.monitor = (0, perf_hooks_1.monitorEventLoopDelay)({ resolution: 10 });
29
+ this.monitor.enable();
30
+ this.interval = setInterval(() => {
31
+ this.collectMetrics();
32
+ }, this.config.intervalMs);
33
+ this.isRunning = true;
34
+ }
35
+ /**
36
+ * Stop monitoring
37
+ */
38
+ stop() {
39
+ if (this.interval) {
40
+ clearInterval(this.interval);
41
+ this.interval = null;
42
+ }
43
+ if (this.monitor) {
44
+ this.monitor.disable();
45
+ this.monitor = null;
46
+ }
47
+ this.isRunning = false;
48
+ }
49
+ /**
50
+ * Collect current metrics
51
+ */
52
+ getMetrics() {
53
+ if (!this.monitor) {
54
+ return this.getEmptyMetrics();
55
+ }
56
+ const stats = this.monitor;
57
+ return {
58
+ mean: stats.mean / 1e6, // Convert nanoseconds to milliseconds
59
+ max: stats.max / 1e6,
60
+ min: stats.min / 1e6,
61
+ p50: stats.percentile(50) / 1e6,
62
+ p95: stats.percentile(95) / 1e6,
63
+ p99: stats.percentile(99) / 1e6,
64
+ };
65
+ }
66
+ /**
67
+ * Reset monitor statistics
68
+ */
69
+ reset() {
70
+ if (this.monitor) {
71
+ this.monitor.reset();
72
+ }
73
+ }
74
+ collectMetrics() {
75
+ const metrics = this.getMetrics();
76
+ if (metrics.mean > this.config.thresholdMs) {
77
+ const emptyMemory = {
78
+ heapUsed: 0,
79
+ heapTotal: 0,
80
+ rss: 0,
81
+ external: 0,
82
+ arrayBuffers: 0,
83
+ };
84
+ const emptyGC = {
85
+ estimatedCycles: 0,
86
+ minorGCCount: 0,
87
+ majorGCCount: 0,
88
+ gcPressure: 0,
89
+ };
90
+ const emptyThreadPool = {
91
+ saturationLevel: 0,
92
+ estimatedQueueSize: 0,
93
+ avgLatency: 0,
94
+ };
95
+ const emptyCPU = {
96
+ user: 0,
97
+ system: 0,
98
+ };
99
+ const warning = {
100
+ type: 'eventLoopBlocked',
101
+ message: `Event loop delay exceeded threshold: ${metrics.mean.toFixed(2)}ms > ${this.config.thresholdMs}ms`,
102
+ severity: metrics.mean > this.config.thresholdMs * 2 ? 'high' : 'medium',
103
+ metrics: {
104
+ eventLoopDelay: metrics,
105
+ memory: emptyMemory,
106
+ gc: emptyGC,
107
+ threadPool: emptyThreadPool,
108
+ cpu: emptyCPU,
109
+ activeRequests: 0,
110
+ timestamp: Date.now(),
111
+ },
112
+ timestamp: Date.now(),
113
+ };
114
+ this.emit('warning', warning);
115
+ this.emit('eventLoopBlocked', metrics);
116
+ }
117
+ this.emit('metric', metrics);
118
+ }
119
+ getEmptyMetrics() {
120
+ return {
121
+ mean: 0,
122
+ max: 0,
123
+ min: 0,
124
+ p50: 0,
125
+ p95: 0,
126
+ p99: 0,
127
+ };
128
+ }
129
+ }
130
+ exports.EventLoopMonitor = EventLoopMonitor;
131
+ //# sourceMappingURL=EventLoopMonitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventLoopMonitor.js","sourceRoot":"","sources":["../../src/core/EventLoopMonitor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /// <reference types="node" />
2
+ import { EventEmitter } from 'events';
3
+ import { GCConfig, GCMetrics } from '../types';
4
+ /**
5
+ * Monitors GC pressure by observing heap drop patterns
6
+ */
7
+ export declare class GCMonitor extends EventEmitter {
8
+ private interval;
9
+ private config;
10
+ private isRunning;
11
+ private heapHistory;
12
+ private readonly maxHistorySize;
13
+ private minorGCCount;
14
+ private majorGCCount;
15
+ private lastHeapSize;
16
+ constructor(config?: GCConfig);
17
+ /**
18
+ * Start monitoring GC
19
+ */
20
+ start(): void;
21
+ /**
22
+ * Stop monitoring
23
+ */
24
+ stop(): void;
25
+ /**
26
+ * Get current GC metrics
27
+ */
28
+ getMetrics(): GCMetrics;
29
+ private collectMetrics;
30
+ private calculatePressure;
31
+ }
32
+ //# sourceMappingURL=GCMonitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GCMonitor.d.ts","sourceRoot":"","sources":["../../src/core/GCMonitor.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EACL,QAAQ,EACR,SAAS,EAMV,MAAM,UAAU,CAAC;AAElB;;GAEG;AACH,qBAAa,SAAU,SAAQ,YAAY;IACzC,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAO;IACtC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,YAAY,CAAK;gBAEb,MAAM,GAAE,QAAa;IAQjC;;OAEG;IACH,KAAK,IAAI,IAAI;IAcb;;OAEG;IACH,IAAI,IAAI,IAAI;IAYZ;;OAEG;IACH,UAAU,IAAI,SAAS;IAiBvB,OAAO,CAAC,cAAc;IA+EtB,OAAO,CAAC,iBAAiB;CAuB1B"}