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.
- package/LICENSE +22 -0
- package/README.md +423 -0
- package/dist/core/EventLoopMonitor.d.ts +32 -0
- package/dist/core/EventLoopMonitor.d.ts.map +1 -0
- package/dist/core/EventLoopMonitor.js +131 -0
- package/dist/core/EventLoopMonitor.js.map +1 -0
- package/dist/core/GCMonitor.d.ts +32 -0
- package/dist/core/GCMonitor.d.ts.map +1 -0
- package/dist/core/GCMonitor.js +151 -0
- package/dist/core/GCMonitor.js.map +1 -0
- package/dist/core/Guardian.d.ts +76 -0
- package/dist/core/Guardian.d.ts.map +1 -0
- package/dist/core/Guardian.js +196 -0
- package/dist/core/Guardian.js.map +1 -0
- package/dist/core/HeuristicEngine.d.ts +27 -0
- package/dist/core/HeuristicEngine.d.ts.map +1 -0
- package/dist/core/HeuristicEngine.js +150 -0
- package/dist/core/HeuristicEngine.js.map +1 -0
- package/dist/core/MemoryMonitor.d.ts +33 -0
- package/dist/core/MemoryMonitor.d.ts.map +1 -0
- package/dist/core/MemoryMonitor.js +193 -0
- package/dist/core/MemoryMonitor.js.map +1 -0
- package/dist/core/ProtectionLayer.d.ts +42 -0
- package/dist/core/ProtectionLayer.d.ts.map +1 -0
- package/dist/core/ProtectionLayer.js +105 -0
- package/dist/core/ProtectionLayer.js.map +1 -0
- package/dist/core/ThreadPoolMonitor.d.ts +29 -0
- package/dist/core/ThreadPoolMonitor.d.ts.map +1 -0
- package/dist/core/ThreadPoolMonitor.js +144 -0
- package/dist/core/ThreadPoolMonitor.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/Plugin.d.ts +53 -0
- package/dist/plugins/Plugin.d.ts.map +1 -0
- package/dist/plugins/Plugin.js +74 -0
- package/dist/plugins/Plugin.js.map +1 -0
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +18 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/server/MetricsServer.d.ts +26 -0
- package/dist/server/MetricsServer.d.ts.map +1 -0
- package/dist/server/MetricsServer.js +86 -0
- package/dist/server/MetricsServer.js.map +1 -0
- package/dist/types/index.d.ts +104 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +19 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/metrics.d.ts +67 -0
- package/dist/types/metrics.d.ts.map +1 -0
- package/dist/types/metrics.js +3 -0
- package/dist/types/metrics.js.map +1 -0
- package/dist/worker/WorkerPool.d.ts +44 -0
- package/dist/worker/WorkerPool.d.ts.map +1 -0
- package/dist/worker/WorkerPool.js +214 -0
- package/dist/worker/WorkerPool.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { RuntimeMetrics } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Base interface for Guardian plugins
|
|
4
|
+
*/
|
|
5
|
+
export interface GuardianPlugin {
|
|
6
|
+
/**
|
|
7
|
+
* Called when metrics are updated
|
|
8
|
+
*/
|
|
9
|
+
onMetricUpdate(data: RuntimeMetrics): void;
|
|
10
|
+
/**
|
|
11
|
+
* Called when plugin is registered
|
|
12
|
+
*/
|
|
13
|
+
onRegister?(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Called when plugin is unregistered
|
|
16
|
+
*/
|
|
17
|
+
onUnregister?(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Plugin name
|
|
20
|
+
*/
|
|
21
|
+
name: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Plugin registry for managing plugins
|
|
25
|
+
*/
|
|
26
|
+
export declare class PluginRegistry {
|
|
27
|
+
private plugins;
|
|
28
|
+
/**
|
|
29
|
+
* Register a plugin
|
|
30
|
+
*/
|
|
31
|
+
register(plugin: GuardianPlugin): void;
|
|
32
|
+
/**
|
|
33
|
+
* Unregister a plugin
|
|
34
|
+
*/
|
|
35
|
+
unregister(name: string): void;
|
|
36
|
+
/**
|
|
37
|
+
* Get a plugin by name
|
|
38
|
+
*/
|
|
39
|
+
get(name: string): GuardianPlugin | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Get all registered plugins
|
|
42
|
+
*/
|
|
43
|
+
getAll(): GuardianPlugin[];
|
|
44
|
+
/**
|
|
45
|
+
* Notify all plugins of metric update
|
|
46
|
+
*/
|
|
47
|
+
notifyMetrics(data: RuntimeMetrics): void;
|
|
48
|
+
/**
|
|
49
|
+
* Clear all plugins
|
|
50
|
+
*/
|
|
51
|
+
clear(): void;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=Plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/Plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IAE3C;;OAEG;IACH,UAAU,CAAC,IAAI,IAAI,CAAC;IAEpB;;OAEG;IACH,YAAY,CAAC,IAAI,IAAI,CAAC;IAEtB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAA0C;IAEzD;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAatC;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAU9B;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI7C;;OAEG;IACH,MAAM,IAAI,cAAc,EAAE;IAI1B;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAWzC;;OAEG;IACH,KAAK,IAAI,IAAI;CAQd"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PluginRegistry = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Plugin registry for managing plugins
|
|
6
|
+
*/
|
|
7
|
+
class PluginRegistry {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.plugins = new Map();
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Register a plugin
|
|
13
|
+
*/
|
|
14
|
+
register(plugin) {
|
|
15
|
+
if (this.plugins.has(plugin.name)) {
|
|
16
|
+
throw new Error(`Plugin with name "${plugin.name}" is already registered`);
|
|
17
|
+
}
|
|
18
|
+
this.plugins.set(plugin.name, plugin);
|
|
19
|
+
if (plugin.onRegister) {
|
|
20
|
+
plugin.onRegister();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Unregister a plugin
|
|
25
|
+
*/
|
|
26
|
+
unregister(name) {
|
|
27
|
+
const plugin = this.plugins.get(name);
|
|
28
|
+
if (plugin) {
|
|
29
|
+
if (plugin.onUnregister) {
|
|
30
|
+
plugin.onUnregister();
|
|
31
|
+
}
|
|
32
|
+
this.plugins.delete(name);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get a plugin by name
|
|
37
|
+
*/
|
|
38
|
+
get(name) {
|
|
39
|
+
return this.plugins.get(name);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get all registered plugins
|
|
43
|
+
*/
|
|
44
|
+
getAll() {
|
|
45
|
+
return Array.from(this.plugins.values());
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Notify all plugins of metric update
|
|
49
|
+
*/
|
|
50
|
+
notifyMetrics(data) {
|
|
51
|
+
this.plugins.forEach((plugin) => {
|
|
52
|
+
try {
|
|
53
|
+
plugin.onMetricUpdate(data);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
// Silently handle plugin errors to prevent breaking the main flow
|
|
57
|
+
console.error(`Error in plugin ${plugin.name}:`, error);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Clear all plugins
|
|
63
|
+
*/
|
|
64
|
+
clear() {
|
|
65
|
+
this.plugins.forEach((plugin) => {
|
|
66
|
+
if (plugin.onUnregister) {
|
|
67
|
+
plugin.onUnregister();
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
this.plugins.clear();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.PluginRegistry = PluginRegistry;
|
|
74
|
+
//# sourceMappingURL=Plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Plugin.js","sourceRoot":"","sources":["../../src/plugins/Plugin.ts"],"names":[],"mappings":";;;AA2BA;;GAEG;AACH,MAAa,cAAc;IAA3B;QACU,YAAO,GAAgC,IAAI,GAAG,EAAE,CAAC;IAsE3D,CAAC;IApEC;;OAEG;IACH,QAAQ,CAAC,MAAsB;QAC7B,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CACb,qBAAqB,MAAM,CAAC,IAAI,yBAAyB,CAC1D,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACtC,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,IAAY;QACrB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;gBACxB,MAAM,CAAC,YAAY,EAAE,CAAC;YACxB,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,IAAoB;QAChC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YAC9B,IAAI,CAAC;gBACH,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,kEAAkE;gBAClE,OAAO,CAAC,KAAK,CAAC,mBAAmB,MAAM,CAAC,IAAI,GAAG,EAAE,KAAK,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YAC9B,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;gBACxB,MAAM,CAAC,YAAY,EAAE,CAAC;YACxB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CACF;AAvED,wCAuEC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./Plugin"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Guardian } from '../core/Guardian';
|
|
2
|
+
import { MetricsServerConfig } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* HTTP server for exposing metrics endpoint
|
|
5
|
+
*/
|
|
6
|
+
export declare class MetricsServer {
|
|
7
|
+
private server;
|
|
8
|
+
private guardian;
|
|
9
|
+
private config;
|
|
10
|
+
private isRunning;
|
|
11
|
+
constructor(guardian: Guardian, config?: MetricsServerConfig);
|
|
12
|
+
/**
|
|
13
|
+
* Start the metrics server
|
|
14
|
+
*/
|
|
15
|
+
start(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Stop the metrics server
|
|
18
|
+
*/
|
|
19
|
+
stop(): void;
|
|
20
|
+
/**
|
|
21
|
+
* Check if server is running
|
|
22
|
+
*/
|
|
23
|
+
getIsRunning(): boolean;
|
|
24
|
+
private handleRequest;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=MetricsServer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MetricsServer.d.ts","sourceRoot":"","sources":["../../src/server/MetricsServer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/C;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,SAAS,CAAS;gBAEd,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAE,mBAAwB;IAShE;;OAEG;IACH,KAAK,IAAI,IAAI;IAqBb;;OAEG;IACH,IAAI,IAAI,IAAI;IASZ;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB,OAAO,CAAC,aAAa;CAkCtB"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MetricsServer = void 0;
|
|
4
|
+
const http_1 = require("http");
|
|
5
|
+
/**
|
|
6
|
+
* HTTP server for exposing metrics endpoint
|
|
7
|
+
*/
|
|
8
|
+
class MetricsServer {
|
|
9
|
+
constructor(guardian, config = {}) {
|
|
10
|
+
this.server = null;
|
|
11
|
+
this.isRunning = false;
|
|
12
|
+
this.guardian = guardian;
|
|
13
|
+
this.config = {
|
|
14
|
+
enabled: config.enabled ?? true,
|
|
15
|
+
port: config.port ?? 9090,
|
|
16
|
+
path: config.path ?? '/guardian/metrics',
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Start the metrics server
|
|
21
|
+
*/
|
|
22
|
+
start() {
|
|
23
|
+
if (!this.config.enabled || this.isRunning) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
this.server = (0, http_1.createServer)((req, res) => {
|
|
27
|
+
this.handleRequest(req, res);
|
|
28
|
+
});
|
|
29
|
+
this.server.listen(this.config.port, () => {
|
|
30
|
+
this.isRunning = true;
|
|
31
|
+
console.log(`Guardian metrics server listening on port ${this.config.port}`);
|
|
32
|
+
});
|
|
33
|
+
this.server.on('error', (error) => {
|
|
34
|
+
console.error('Metrics server error:', error);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Stop the metrics server
|
|
39
|
+
*/
|
|
40
|
+
stop() {
|
|
41
|
+
if (this.server) {
|
|
42
|
+
this.server.close(() => {
|
|
43
|
+
this.isRunning = false;
|
|
44
|
+
});
|
|
45
|
+
this.server = null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Check if server is running
|
|
50
|
+
*/
|
|
51
|
+
getIsRunning() {
|
|
52
|
+
return this.isRunning;
|
|
53
|
+
}
|
|
54
|
+
handleRequest(req, res) {
|
|
55
|
+
// Only handle GET requests to the metrics path
|
|
56
|
+
if (req.method !== 'GET' || req.url !== this.config.path) {
|
|
57
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
58
|
+
res.end(JSON.stringify({ error: 'Not found' }));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const metrics = this.guardian.getMetrics();
|
|
63
|
+
const healthScore = this.guardian.getHealthScore();
|
|
64
|
+
const isProtectionActive = this.guardian.isProtectionActive();
|
|
65
|
+
const response = {
|
|
66
|
+
...metrics,
|
|
67
|
+
healthScore,
|
|
68
|
+
isProtectionActive,
|
|
69
|
+
};
|
|
70
|
+
res.writeHead(200, {
|
|
71
|
+
'Content-Type': 'application/json',
|
|
72
|
+
'Cache-Control': 'no-cache',
|
|
73
|
+
});
|
|
74
|
+
res.end(JSON.stringify(response, null, 2));
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
78
|
+
res.end(JSON.stringify({
|
|
79
|
+
error: 'Internal server error',
|
|
80
|
+
message: error instanceof Error ? error.message : String(error),
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.MetricsServer = MetricsServer;
|
|
86
|
+
//# sourceMappingURL=MetricsServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MetricsServer.js","sourceRoot":"","sources":["../../src/server/MetricsServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { RuntimeMetrics } from './metrics';
|
|
2
|
+
/**
|
|
3
|
+
* Guardian configuration
|
|
4
|
+
*/
|
|
5
|
+
export interface GuardianConfig {
|
|
6
|
+
eventLoop?: EventLoopConfig;
|
|
7
|
+
memory?: MemoryConfig;
|
|
8
|
+
gc?: GCConfig;
|
|
9
|
+
threadPool?: ThreadPoolConfig;
|
|
10
|
+
protection?: ProtectionConfig;
|
|
11
|
+
metricsServer?: MetricsServerConfig;
|
|
12
|
+
workerPool?: WorkerPoolConfig;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Event loop monitoring configuration
|
|
16
|
+
*/
|
|
17
|
+
export interface EventLoopConfig {
|
|
18
|
+
enabled?: boolean;
|
|
19
|
+
thresholdMs?: number;
|
|
20
|
+
intervalMs?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Memory monitoring configuration
|
|
24
|
+
*/
|
|
25
|
+
export interface MemoryConfig {
|
|
26
|
+
enabled?: boolean;
|
|
27
|
+
rssLimit?: number;
|
|
28
|
+
heapLimit?: number;
|
|
29
|
+
externalLimit?: number;
|
|
30
|
+
driftDetectionEnabled?: boolean;
|
|
31
|
+
driftThreshold?: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* GC monitoring configuration
|
|
35
|
+
*/
|
|
36
|
+
export interface GCConfig {
|
|
37
|
+
enabled?: boolean;
|
|
38
|
+
pressureThreshold?: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Thread pool monitoring configuration
|
|
42
|
+
*/
|
|
43
|
+
export interface ThreadPoolConfig {
|
|
44
|
+
enabled?: boolean;
|
|
45
|
+
saturationThreshold?: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Protection layer configuration
|
|
49
|
+
*/
|
|
50
|
+
export interface ProtectionConfig {
|
|
51
|
+
enabled?: boolean;
|
|
52
|
+
loadShedding?: LoadSheddingConfig;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Load shedding configuration
|
|
56
|
+
*/
|
|
57
|
+
export interface LoadSheddingConfig {
|
|
58
|
+
enabled?: boolean;
|
|
59
|
+
eventLoopThreshold?: number;
|
|
60
|
+
memoryThreshold?: number;
|
|
61
|
+
responseCode?: number;
|
|
62
|
+
responseMessage?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Metrics server configuration
|
|
66
|
+
*/
|
|
67
|
+
export interface MetricsServerConfig {
|
|
68
|
+
enabled?: boolean;
|
|
69
|
+
port?: number;
|
|
70
|
+
path?: string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Worker pool configuration
|
|
74
|
+
*/
|
|
75
|
+
export interface WorkerPoolConfig {
|
|
76
|
+
enabled?: boolean;
|
|
77
|
+
poolSize?: number;
|
|
78
|
+
maxQueueSize?: number;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Guardian events
|
|
82
|
+
*/
|
|
83
|
+
export type GuardianEvent = 'metric' | 'warning' | 'error' | 'eventLoopBlocked' | 'memoryDrift' | 'gcPressure' | 'threadPoolSaturated';
|
|
84
|
+
/**
|
|
85
|
+
* Event data for warnings
|
|
86
|
+
*/
|
|
87
|
+
export interface WarningEvent {
|
|
88
|
+
type: string;
|
|
89
|
+
message: string;
|
|
90
|
+
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
91
|
+
metrics: RuntimeMetrics;
|
|
92
|
+
timestamp: number;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Event data for errors
|
|
96
|
+
*/
|
|
97
|
+
export interface ErrorEvent {
|
|
98
|
+
type: string;
|
|
99
|
+
message: string;
|
|
100
|
+
error?: Error;
|
|
101
|
+
timestamp: number;
|
|
102
|
+
}
|
|
103
|
+
export * from './metrics';
|
|
104
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,EAAE,CAAC,EAAE,QAAQ,CAAC;IACd,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,QAAQ,GACR,SAAS,GACT,OAAO,GACP,kBAAkB,GAClB,aAAa,GACb,YAAY,GACZ,qBAAqB,CAAC;AAE1B;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IACjD,OAAO,EAAE,cAAc,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAGD,cAAc,WAAW,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
// Re-export metrics types
|
|
18
|
+
__exportStar(require("./metrics"), exports);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AA0HA,0BAA0B;AAC1B,4CAA0B"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime metrics collected by the Guardian
|
|
3
|
+
*/
|
|
4
|
+
export interface RuntimeMetrics {
|
|
5
|
+
eventLoopDelay: EventLoopMetrics;
|
|
6
|
+
memory: MemoryMetrics;
|
|
7
|
+
gc: GCMetrics;
|
|
8
|
+
threadPool: ThreadPoolMetrics;
|
|
9
|
+
cpu: CPUMetrics;
|
|
10
|
+
activeRequests: number;
|
|
11
|
+
timestamp: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Event loop delay metrics
|
|
15
|
+
*/
|
|
16
|
+
export interface EventLoopMetrics {
|
|
17
|
+
mean: number;
|
|
18
|
+
max: number;
|
|
19
|
+
min: number;
|
|
20
|
+
p50: number;
|
|
21
|
+
p95: number;
|
|
22
|
+
p99: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Memory metrics
|
|
26
|
+
*/
|
|
27
|
+
export interface MemoryMetrics {
|
|
28
|
+
heapUsed: number;
|
|
29
|
+
heapTotal: number;
|
|
30
|
+
rss: number;
|
|
31
|
+
external: number;
|
|
32
|
+
arrayBuffers: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* GC metrics
|
|
36
|
+
*/
|
|
37
|
+
export interface GCMetrics {
|
|
38
|
+
estimatedCycles: number;
|
|
39
|
+
minorGCCount: number;
|
|
40
|
+
majorGCCount: number;
|
|
41
|
+
gcPressure: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Thread pool metrics (inferred)
|
|
45
|
+
*/
|
|
46
|
+
export interface ThreadPoolMetrics {
|
|
47
|
+
saturationLevel: number;
|
|
48
|
+
estimatedQueueSize: number;
|
|
49
|
+
avgLatency: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* CPU usage metrics
|
|
53
|
+
*/
|
|
54
|
+
export interface CPUMetrics {
|
|
55
|
+
user: number;
|
|
56
|
+
system: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Memory drift pattern
|
|
60
|
+
*/
|
|
61
|
+
export interface MemoryDrift {
|
|
62
|
+
rssGrowthRate: number;
|
|
63
|
+
heapGrowthRate: number;
|
|
64
|
+
externalGrowthRate: number;
|
|
65
|
+
isLeakSuspected: boolean;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/types/metrics.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,gBAAgB,CAAC;IACjC,MAAM,EAAE,aAAa,CAAC;IACtB,EAAE,EAAE,SAAS,CAAC;IACd,UAAU,EAAE,iBAAiB,CAAC;IAC9B,GAAG,EAAE,UAAU,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,OAAO,CAAC;CAC1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/types/metrics.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { WorkerPoolConfig } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Managed worker thread pool with queue management
|
|
4
|
+
*/
|
|
5
|
+
export declare class WorkerPool {
|
|
6
|
+
private workers;
|
|
7
|
+
private queue;
|
|
8
|
+
private activeTasks;
|
|
9
|
+
private workerTaskMap;
|
|
10
|
+
private config;
|
|
11
|
+
private workerScript;
|
|
12
|
+
private isShuttingDown;
|
|
13
|
+
constructor(workerScript: string, config?: WorkerPoolConfig);
|
|
14
|
+
/**
|
|
15
|
+
* Run a task in the worker pool
|
|
16
|
+
*/
|
|
17
|
+
run<TResult>(data: unknown): Promise<TResult>;
|
|
18
|
+
/**
|
|
19
|
+
* Get current queue size
|
|
20
|
+
*/
|
|
21
|
+
getQueueSize(): number;
|
|
22
|
+
/**
|
|
23
|
+
* Get number of active tasks
|
|
24
|
+
*/
|
|
25
|
+
getActiveTasks(): number;
|
|
26
|
+
/**
|
|
27
|
+
* Get pool statistics
|
|
28
|
+
*/
|
|
29
|
+
getStats(): {
|
|
30
|
+
poolSize: number;
|
|
31
|
+
activeTasks: number;
|
|
32
|
+
queueSize: number;
|
|
33
|
+
availableWorkers: number;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Shutdown the worker pool
|
|
37
|
+
*/
|
|
38
|
+
shutdown(): Promise<void>;
|
|
39
|
+
private initializeWorkers;
|
|
40
|
+
private createWorker;
|
|
41
|
+
private processQueue;
|
|
42
|
+
private isWorkerBusy;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=WorkerPool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkerPool.d.ts","sourceRoot":"","sources":["../../src/worker/WorkerPool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAS5C;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,WAAW,CAAkD;IACrE,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,cAAc,CAAS;gBAEnB,YAAY,EAAE,MAAM,EAAE,MAAM,GAAE,gBAAqB;IAa/D;;OAEG;IACG,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IA6BnD;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,QAAQ;;;;;;IAUR;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAuE/B,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,YAAY;IAoDpB,OAAO,CAAC,YAAY;IA+BpB,OAAO,CAAC,YAAY;CAIrB"}
|