apm-optima 0.0.1

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 (131) hide show
  1. package/dist/adapters/http.adapter.d.ts +12 -0
  2. package/dist/adapters/http.adapter.js +2 -0
  3. package/dist/adapters/websocket.adapter.d.ts +5 -0
  4. package/dist/adapters/websocket.adapter.js +2 -0
  5. package/dist/config/config.manager.d.ts +12 -0
  6. package/dist/config/config.manager.js +111 -0
  7. package/dist/config/config.types.d.ts +19 -0
  8. package/dist/config/config.types.js +2 -0
  9. package/dist/config/index.d.ts +2 -0
  10. package/dist/config/index.js +18 -0
  11. package/dist/core/delivery/index.d.ts +2 -0
  12. package/dist/core/delivery/index.js +18 -0
  13. package/dist/core/delivery/metrics.publisher.d.ts +18 -0
  14. package/dist/core/delivery/metrics.publisher.js +36 -0
  15. package/dist/core/delivery/websocket.events.d.ts +12 -0
  16. package/dist/core/delivery/websocket.events.js +16 -0
  17. package/dist/core/domain/common.types.d.ts +44 -0
  18. package/dist/core/domain/common.types.js +20 -0
  19. package/dist/core/domain/dashboard.types.d.ts +108 -0
  20. package/dist/core/domain/dashboard.types.js +2 -0
  21. package/dist/core/domain/endpoints.types.d.ts +43 -0
  22. package/dist/core/domain/endpoints.types.js +2 -0
  23. package/dist/core/domain/index.d.ts +6 -0
  24. package/dist/core/domain/index.js +22 -0
  25. package/dist/core/domain/metrics.types.d.ts +119 -0
  26. package/dist/core/domain/metrics.types.js +2 -0
  27. package/dist/core/domain/system.types.d.ts +51 -0
  28. package/dist/core/domain/system.types.js +2 -0
  29. package/dist/core/domain/telemetry.types.d.ts +8 -0
  30. package/dist/core/domain/telemetry.types.js +2 -0
  31. package/dist/core/storage/index.d.ts +3 -0
  32. package/dist/core/storage/index.js +19 -0
  33. package/dist/core/storage/local.repository.d.ts +17 -0
  34. package/dist/core/storage/local.repository.js +52 -0
  35. package/dist/core/storage/stores/alert.store.d.ts +13 -0
  36. package/dist/core/storage/stores/alert.store.js +71 -0
  37. package/dist/core/storage/stores/analytics.store.d.ts +15 -0
  38. package/dist/core/storage/stores/analytics.store.js +59 -0
  39. package/dist/core/storage/stores/bucket.store.d.ts +40 -0
  40. package/dist/core/storage/stores/bucket.store.js +75 -0
  41. package/dist/core/storage/stores/dashboard.store.d.ts +15 -0
  42. package/dist/core/storage/stores/dashboard.store.js +78 -0
  43. package/dist/core/storage/stores/endpoint.store.d.ts +16 -0
  44. package/dist/core/storage/stores/endpoint.store.js +62 -0
  45. package/dist/core/storage/stores/health.store.d.ts +20 -0
  46. package/dist/core/storage/stores/health.store.js +133 -0
  47. package/dist/core/storage/stores/index.d.ts +8 -0
  48. package/dist/core/storage/stores/index.js +24 -0
  49. package/dist/core/storage/stores/metrics.store.d.ts +23 -0
  50. package/dist/core/storage/stores/metrics.store.js +49 -0
  51. package/dist/core/storage/stores/system.store.d.ts +8 -0
  52. package/dist/core/storage/stores/system.store.js +19 -0
  53. package/dist/core/storage/utility/histogram.d.ts +37 -0
  54. package/dist/core/storage/utility/histogram.js +91 -0
  55. package/dist/core/storage/utility/index.d.ts +2 -0
  56. package/dist/core/storage/utility/index.js +18 -0
  57. package/dist/core/storage/utility/ring-buffer.d.ts +12 -0
  58. package/dist/core/storage/utility/ring-buffer.js +47 -0
  59. package/dist/core/telemetry/collector.service.d.ts +18 -0
  60. package/dist/core/telemetry/collector.service.js +92 -0
  61. package/dist/core/telemetry/collectors/cpu.collector.d.ts +22 -0
  62. package/dist/core/telemetry/collectors/cpu.collector.js +39 -0
  63. package/dist/core/telemetry/collectors/event-loop.collector.d.ts +22 -0
  64. package/dist/core/telemetry/collectors/event-loop.collector.js +27 -0
  65. package/dist/core/telemetry/collectors/gc.collector.d.ts +61 -0
  66. package/dist/core/telemetry/collectors/gc.collector.js +86 -0
  67. package/dist/core/telemetry/collectors/handles.collector.d.ts +20 -0
  68. package/dist/core/telemetry/collectors/handles.collector.js +26 -0
  69. package/dist/core/telemetry/collectors/index.d.ts +6 -0
  70. package/dist/core/telemetry/collectors/index.js +22 -0
  71. package/dist/core/telemetry/collectors/interface.d.ts +3 -0
  72. package/dist/core/telemetry/collectors/interface.js +2 -0
  73. package/dist/core/telemetry/collectors/memory.collector.d.ts +18 -0
  74. package/dist/core/telemetry/collectors/memory.collector.js +24 -0
  75. package/dist/core/telemetry/collectors/runtime.collector.d.ts +32 -0
  76. package/dist/core/telemetry/collectors/runtime.collector.js +29 -0
  77. package/dist/core/telemetry/correlation.service.d.ts +9 -0
  78. package/dist/core/telemetry/correlation.service.js +72 -0
  79. package/dist/core/telemetry/logger.d.ts +11 -0
  80. package/dist/core/telemetry/logger.js +63 -0
  81. package/dist/core/telemetry/telemetry.service.d.ts +10 -0
  82. package/dist/core/telemetry/telemetry.service.js +36 -0
  83. package/dist/core/utility/base-math.d.ts +15 -0
  84. package/dist/core/utility/base-math.js +26 -0
  85. package/dist/core/utility/conversion.d.ts +31 -0
  86. package/dist/core/utility/conversion.js +74 -0
  87. package/dist/core/utility/index.d.ts +4 -0
  88. package/dist/core/utility/index.js +20 -0
  89. package/dist/core/utility/mocking.d.ts +21 -0
  90. package/dist/core/utility/mocking.js +40 -0
  91. package/dist/core/utility/pagination.d.ts +9 -0
  92. package/dist/core/utility/pagination.js +23 -0
  93. package/dist/core/utility/statistics.d.ts +140 -0
  94. package/dist/core/utility/statistics.js +349 -0
  95. package/dist/express/index.d.ts +6 -0
  96. package/dist/express/index.js +22 -0
  97. package/dist/express/metrics-websocket.adapter.d.ts +14 -0
  98. package/dist/express/metrics-websocket.adapter.js +70 -0
  99. package/dist/express/metrics.adapter.d.ts +12 -0
  100. package/dist/express/metrics.adapter.js +31 -0
  101. package/dist/express/metrics.bootstrap.d.ts +2 -0
  102. package/dist/express/metrics.bootstrap.js +35 -0
  103. package/dist/express/metrics.dashboard.d.ts +2 -0
  104. package/dist/express/metrics.dashboard.js +15 -0
  105. package/dist/express/metrics.middleware.d.ts +2 -0
  106. package/dist/express/metrics.middleware.js +29 -0
  107. package/dist/index.d.ts +3 -0
  108. package/dist/index.js +6 -0
  109. package/dist/nest/index.d.ts +4 -0
  110. package/dist/nest/index.js +11 -0
  111. package/dist/nest/metrics-websocket.adapter.d.ts +15 -0
  112. package/dist/nest/metrics-websocket.adapter.js +88 -0
  113. package/dist/nest/metrics.adapter.d.ts +12 -0
  114. package/dist/nest/metrics.adapter.js +33 -0
  115. package/dist/nest/metrics.bootstrap.service.d.ts +13 -0
  116. package/dist/nest/metrics.bootstrap.service.js +66 -0
  117. package/dist/nest/metrics.interceptor.d.ts +11 -0
  118. package/dist/nest/metrics.interceptor.js +57 -0
  119. package/dist/nest/metrics.module.d.ts +6 -0
  120. package/dist/nest/metrics.module.js +74 -0
  121. package/dist/simulation/config.d.ts +20 -0
  122. package/dist/simulation/config.js +54 -0
  123. package/dist/simulation/journey.d.ts +7 -0
  124. package/dist/simulation/journey.js +49 -0
  125. package/dist/simulation/scenarios.d.ts +17 -0
  126. package/dist/simulation/scenarios.js +96 -0
  127. package/dist/simulation/simulation.d.ts +24 -0
  128. package/dist/simulation/simulation.js +154 -0
  129. package/dist/simulation/utility.d.ts +23 -0
  130. package/dist/simulation/utility.js +50 -0
  131. package/package.json +71 -0
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.collectorService = void 0;
4
+ const storage_1 = require("../storage");
5
+ const collectors_1 = require("./collectors");
6
+ const config_1 = require("../../config");
7
+ class CollectorService {
8
+ cpuCollector;
9
+ memoryCollector;
10
+ eventLoopCollector;
11
+ gcCollector;
12
+ handlesCollector;
13
+ runtimeCollector;
14
+ constructor(cpuCollector, memoryCollector, eventLoopCollector, gcCollector, handlesCollector, runtimeCollector) {
15
+ this.cpuCollector = cpuCollector;
16
+ this.memoryCollector = memoryCollector;
17
+ this.eventLoopCollector = eventLoopCollector;
18
+ this.gcCollector = gcCollector;
19
+ this.handlesCollector = handlesCollector;
20
+ this.runtimeCollector = runtimeCollector;
21
+ }
22
+ getSystemStaticInfo() {
23
+ return storage_1.storage.system.get();
24
+ }
25
+ getDashboardData() {
26
+ return storage_1.storage.dashboard.get();
27
+ }
28
+ getAnalyticsData() {
29
+ return storage_1.storage.analytics.get();
30
+ }
31
+ getHealthData() {
32
+ return storage_1.storage.health.get();
33
+ }
34
+ tick() {
35
+ const cpuData = this.cpuCollector.collect();
36
+ storage_1.storage.health.updateCPU({
37
+ usageRate: cpuData.totalPercent,
38
+ numberOfCores: cpuData.numberOfCores,
39
+ perCoreUsage: cpuData.perCoreUsage,
40
+ userUsage: cpuData.userPercent,
41
+ systemUsage: cpuData.systemPercent,
42
+ idleUsage: cpuData.idlePercent
43
+ });
44
+ const memoryData = this.memoryCollector.collect();
45
+ storage_1.storage.health.updateMemory({
46
+ heapUsage: memoryData.heapUsage,
47
+ heapSize: memoryData.heapSize,
48
+ rssMemory: memoryData.rssMemory,
49
+ rssMemoryTotal: memoryData.rssMemoryTotal,
50
+ externalMemory: memoryData.externalMemory,
51
+ });
52
+ const eventLoopData = this.eventLoopCollector.collect();
53
+ storage_1.storage.health.updateEventLoop({
54
+ lag: eventLoopData.meanMs,
55
+ threshold: this.eventLoopCollector.thresholdMs,
56
+ });
57
+ const handlesData = this.handlesCollector.collect();
58
+ storage_1.storage.health.updateHandles({
59
+ activeHandles: handlesData.activeHandles,
60
+ activeHandlesTimers: handlesData.activeHandlesTimers,
61
+ activeHandlesSockets: handlesData.activeHandlesSockets,
62
+ activeLibuvHandles: handlesData.activeLibuvHandles,
63
+ timers: handlesData.timers,
64
+ fileDescriptors: handlesData.fileDescriptors
65
+ });
66
+ const gcData = this.gcCollector.collect();
67
+ storage_1.storage.health.updateGC({
68
+ gcCount: gcData.gcCount,
69
+ gcTime: gcData.gcTime,
70
+ gcPauseAverage: gcData.gcPauseAverage,
71
+ minorGC: gcData.minorGC,
72
+ majorGC: gcData.majorGC,
73
+ incrementalGC: gcData.incrementalGC,
74
+ heapSpaces: gcData.heapSpaces,
75
+ gcTotals: gcData.gcTotals
76
+ });
77
+ const runtimeData = this.runtimeCollector.collect();
78
+ storage_1.storage.health.updateRuntime({
79
+ pid: runtimeData.pid,
80
+ platform: runtimeData.platform,
81
+ nodeVersion: runtimeData.nodeVersion,
82
+ v8Version: runtimeData.v8Version,
83
+ libuvVersion: runtimeData.libuvVersion,
84
+ openSSLVersion: runtimeData.openSSLVersion,
85
+ threadPoolSize: runtimeData.threadPoolSize,
86
+ activeThreads: runtimeData.activeThreads,
87
+ startup: runtimeData.startup
88
+ });
89
+ storage_1.storage.tick();
90
+ }
91
+ }
92
+ exports.collectorService = new CollectorService(new collectors_1.CPUCollector(), new collectors_1.MemoryCollector(), new collectors_1.EventLoopCollector((0, config_1.getConfig)().publisher.eventLoopResolutionMs, (0, config_1.getConfig)().publisher.eventLoopLagThresholdMs), new collectors_1.GCCollector(), new collectors_1.HandlesCollector(), new collectors_1.RuntimeCollector());
@@ -0,0 +1,22 @@
1
+ import { ICollector } from './interface';
2
+ type CPUUsageResult = {
3
+ numberOfCores: number;
4
+ userPercent: number;
5
+ systemPercent: number;
6
+ totalPercent: number;
7
+ idlePercent: number;
8
+ perCoreUsage: number[];
9
+ };
10
+ declare class CPUCollector implements ICollector<CPUUsageResult> {
11
+ private lastCpuSample;
12
+ private lastTimeSample;
13
+ collect(): {
14
+ numberOfCores: number;
15
+ userPercent: number;
16
+ systemPercent: number;
17
+ totalPercent: number;
18
+ idlePercent: number;
19
+ perCoreUsage: number[];
20
+ };
21
+ }
22
+ export { CPUCollector, CPUUsageResult };
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CPUCollector = void 0;
7
+ const node_os_1 = __importDefault(require("node:os"));
8
+ const node_process_1 = __importDefault(require("node:process"));
9
+ const utility_1 = require("../../utility");
10
+ class CPUCollector {
11
+ lastCpuSample = node_process_1.default.cpuUsage();
12
+ lastTimeSample = node_process_1.default.hrtime.bigint();
13
+ collect() {
14
+ const currentCpuUsage = node_process_1.default.cpuUsage(this.lastCpuSample);
15
+ const currentSampleTime = node_process_1.default.hrtime.bigint();
16
+ const elapsedTimeInNs = currentSampleTime - this.lastTimeSample;
17
+ const elapsedTimeInMicros = Number(elapsedTimeInNs) / 1000;
18
+ this.lastCpuSample = node_process_1.default.cpuUsage();
19
+ this.lastTimeSample = currentSampleTime;
20
+ const userPercent = (0, utility_1.toPercentage)(currentCpuUsage.user, elapsedTimeInMicros);
21
+ const systemPercent = (0, utility_1.toPercentage)(currentCpuUsage.system, elapsedTimeInMicros);
22
+ const idlePercent = Math.max(0, 100 - (userPercent + systemPercent));
23
+ const cpus = node_os_1.default.cpus();
24
+ const perCoreUsage = cpus.map((core, index) => {
25
+ const coreTotalTime = Object.values(core.times).reduce((a, b) => a + b, 0);
26
+ return coreTotalTime > 0 ? (0, utility_1.toPercentage)((coreTotalTime - core.times.idle), coreTotalTime) : 0;
27
+ });
28
+ return {
29
+ numberOfCores: cpus.length,
30
+ userPercent: userPercent,
31
+ systemPercent: systemPercent,
32
+ totalPercent: (0, utility_1.clamp)(userPercent + systemPercent, 0, 100),
33
+ idlePercent: idlePercent,
34
+ perCoreUsage: perCoreUsage,
35
+ };
36
+ }
37
+ ;
38
+ }
39
+ exports.CPUCollector = CPUCollector;
@@ -0,0 +1,22 @@
1
+ import { ICollector } from './interface';
2
+ type EventLoopUsageResult = {
3
+ minMs: number;
4
+ maxMs: number;
5
+ meanMs: number;
6
+ p50Ms: number;
7
+ p99Ms: number;
8
+ };
9
+ declare class EventLoopCollector implements ICollector<EventLoopUsageResult> {
10
+ readonly resolutionMs: number;
11
+ readonly thresholdMs: number;
12
+ private histogram;
13
+ constructor(resolutionMs?: number, thresholdMs?: number);
14
+ collect(): {
15
+ minMs: number;
16
+ maxMs: number;
17
+ meanMs: number;
18
+ p50Ms: number;
19
+ p99Ms: number;
20
+ };
21
+ }
22
+ export { EventLoopCollector, EventLoopUsageResult };
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventLoopCollector = void 0;
4
+ const perf_hooks_1 = require("perf_hooks");
5
+ const utility_1 = require("../../utility");
6
+ class EventLoopCollector {
7
+ resolutionMs;
8
+ thresholdMs;
9
+ histogram;
10
+ constructor(resolutionMs = 20, thresholdMs = 100) {
11
+ this.resolutionMs = resolutionMs;
12
+ this.thresholdMs = thresholdMs;
13
+ this.histogram = (0, perf_hooks_1.monitorEventLoopDelay)({ resolution: this.resolutionMs });
14
+ this.histogram.enable();
15
+ }
16
+ collect() {
17
+ const toMs = (ns) => (0, utility_1.convertNanoseconds)(ns, 'ms');
18
+ return {
19
+ minMs: toMs(this.histogram.min),
20
+ maxMs: toMs(this.histogram.max),
21
+ meanMs: toMs(this.histogram.mean),
22
+ p50Ms: toMs(this.histogram.percentile(50)),
23
+ p99Ms: toMs(this.histogram.percentile(99))
24
+ };
25
+ }
26
+ }
27
+ exports.EventLoopCollector = EventLoopCollector;
@@ -0,0 +1,61 @@
1
+ import { ICollector } from './interface';
2
+ type GCUsageResult = {
3
+ gcCount: number;
4
+ gcTime: number;
5
+ gcPauseAverage: number;
6
+ minorGC: {
7
+ runCount: number;
8
+ averageTime: number;
9
+ };
10
+ majorGC: {
11
+ runCount: number;
12
+ averageTime: number;
13
+ };
14
+ incrementalGC: {
15
+ runCount: number;
16
+ averageTime: number;
17
+ };
18
+ heapSpaces: {
19
+ label: string;
20
+ used: number;
21
+ }[];
22
+ gcTotals: {
23
+ totalPauseTime: number;
24
+ freedMemory: number;
25
+ promotions: number;
26
+ tenuredSize: number;
27
+ };
28
+ };
29
+ declare class GCCollector implements ICollector<GCUsageResult> {
30
+ private gcStats;
31
+ private gcObserver;
32
+ constructor();
33
+ collect(): {
34
+ gcCount: number;
35
+ gcTime: number;
36
+ gcPauseAverage: number;
37
+ minorGC: {
38
+ runCount: number;
39
+ averageTime: number;
40
+ };
41
+ majorGC: {
42
+ runCount: number;
43
+ averageTime: number;
44
+ };
45
+ incrementalGC: {
46
+ runCount: number;
47
+ averageTime: number;
48
+ };
49
+ heapSpaces: {
50
+ label: string;
51
+ used: number;
52
+ }[];
53
+ gcTotals: {
54
+ totalPauseTime: number;
55
+ freedMemory: number;
56
+ promotions: number;
57
+ tenuredSize: number;
58
+ };
59
+ };
60
+ }
61
+ export { GCCollector, GCUsageResult };
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.GCCollector = void 0;
7
+ const node_v8_1 = __importDefault(require("node:v8"));
8
+ const node_perf_hooks_1 = require("node:perf_hooks");
9
+ const utility_1 = require("../../utility");
10
+ class GCCollector {
11
+ gcStats;
12
+ gcObserver = new node_perf_hooks_1.PerformanceObserver((list) => {
13
+ const entries = list.getEntries();
14
+ for (const entry of entries) {
15
+ const duration = entry.duration;
16
+ this.gcStats.gcCount++;
17
+ this.gcStats.gcTime += duration;
18
+ const detail = entry.detail;
19
+ const kind = detail ? detail.kind : 0;
20
+ if (kind === 1) { // Minor GC
21
+ this.gcStats.minorGC.runCount++;
22
+ this.gcStats.minorGC.totalTime += duration;
23
+ }
24
+ else if (kind === 2) { // Major GC
25
+ this.gcStats.majorGC.runCount++;
26
+ this.gcStats.majorGC.totalTime += duration;
27
+ }
28
+ else { // Incremental GC
29
+ this.gcStats.incrementalGC.runCount++;
30
+ this.gcStats.incrementalGC.totalTime += duration;
31
+ }
32
+ if (detail) {
33
+ if (detail.freedMemory)
34
+ this.gcStats.freedMemory += detail.freedMemory;
35
+ }
36
+ }
37
+ });
38
+ constructor() {
39
+ this.gcStats = {
40
+ gcCount: 0,
41
+ gcTime: 0,
42
+ gcPauseAverage: 0,
43
+ minorGC: { runCount: 0, totalTime: 0 },
44
+ majorGC: { runCount: 0, totalTime: 0 },
45
+ incrementalGC: { runCount: 0, totalTime: 0 },
46
+ freedMemory: 0
47
+ };
48
+ this.gcObserver.observe({ entryTypes: ['gc'], buffered: true });
49
+ }
50
+ collect() {
51
+ const spaceStats = node_v8_1.default.getHeapSpaceStatistics();
52
+ const heapSpaces = spaceStats.map(space => ({
53
+ label: space.space_name,
54
+ used: space.space_used_size / 1024 / 1024
55
+ }));
56
+ const tenuredSpace = spaceStats.find(s => s.space_name === 'old_space');
57
+ const parseFloatFixed = (value) => parseFloat(value.toFixed(2));
58
+ const parseFloatSafe = (value, condition) => condition ? parseFloatFixed(value) : 0;
59
+ return {
60
+ gcCount: this.gcStats.gcCount,
61
+ gcTime: parseFloatFixed(this.gcStats.gcTime),
62
+ gcPauseAverage: parseFloatSafe(this.gcStats.gcTime / this.gcStats.gcCount, this.gcStats.gcCount > 0),
63
+ minorGC: {
64
+ runCount: this.gcStats.minorGC.runCount,
65
+ averageTime: parseFloatSafe(this.gcStats.minorGC.totalTime / this.gcStats.minorGC.runCount, this.gcStats.minorGC.runCount > 0)
66
+ },
67
+ majorGC: {
68
+ runCount: this.gcStats.majorGC.runCount,
69
+ averageTime: parseFloatSafe(this.gcStats.majorGC.totalTime / this.gcStats.majorGC.runCount, this.gcStats.majorGC.runCount > 0)
70
+ },
71
+ incrementalGC: {
72
+ runCount: this.gcStats.incrementalGC.runCount,
73
+ averageTime: parseFloatSafe(this.gcStats.incrementalGC.totalTime / this.gcStats.incrementalGC.runCount, this.gcStats.incrementalGC.runCount > 0)
74
+ },
75
+ heapSpaces,
76
+ gcTotals: {
77
+ totalPauseTime: parseFloatFixed(this.gcStats.gcTime),
78
+ freedMemory: (0, utility_1.convertBytes)(this.gcStats.freedMemory, 'MB'),
79
+ promotions: this.gcStats.majorGC.runCount,
80
+ tenuredSize: tenuredSpace ? tenuredSpace.space_used_size / 1024 / 1024 : 0
81
+ }
82
+ };
83
+ }
84
+ }
85
+ exports.GCCollector = GCCollector;
86
+ ;
@@ -0,0 +1,20 @@
1
+ import { ICollector } from './interface';
2
+ type HandleUsageResult = {
3
+ activeHandles: number;
4
+ activeHandlesTimers: number;
5
+ activeHandlesSockets: number;
6
+ activeLibuvHandles: number;
7
+ timers: number;
8
+ fileDescriptors: number;
9
+ };
10
+ declare class HandlesCollector implements ICollector<HandleUsageResult> {
11
+ collect(): {
12
+ activeHandles: any;
13
+ activeHandlesTimers: number;
14
+ activeHandlesSockets: number;
15
+ activeLibuvHandles: any;
16
+ timers: number;
17
+ fileDescriptors: any;
18
+ };
19
+ }
20
+ export { HandlesCollector, HandleUsageResult };
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HandlesCollector = void 0;
4
+ class HandlesCollector {
5
+ collect() {
6
+ const handles = process._getActiveHandles ? process._getActiveHandles() : [];
7
+ let timers = 0;
8
+ let sockets = 0;
9
+ for (const h of handles) {
10
+ if (h.constructor && h.constructor.name === 'Timeout')
11
+ timers++;
12
+ if (h.constructor && (h.constructor.name === 'Socket' || h.constructor.name === 'TCPSocket'))
13
+ sockets++;
14
+ }
15
+ return {
16
+ activeHandles: handles.length,
17
+ activeHandlesTimers: timers,
18
+ activeHandlesSockets: sockets,
19
+ activeLibuvHandles: handles.length,
20
+ timers,
21
+ fileDescriptors: handles.length
22
+ };
23
+ }
24
+ }
25
+ exports.HandlesCollector = HandlesCollector;
26
+ ;
@@ -0,0 +1,6 @@
1
+ export * from './cpu.collector';
2
+ export * from './memory.collector';
3
+ export * from './event-loop.collector';
4
+ export * from './gc.collector';
5
+ export * from './handles.collector';
6
+ export * from './runtime.collector';
@@ -0,0 +1,22 @@
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("./cpu.collector"), exports);
18
+ __exportStar(require("./memory.collector"), exports);
19
+ __exportStar(require("./event-loop.collector"), exports);
20
+ __exportStar(require("./gc.collector"), exports);
21
+ __exportStar(require("./handles.collector"), exports);
22
+ __exportStar(require("./runtime.collector"), exports);
@@ -0,0 +1,3 @@
1
+ export interface ICollector<T> {
2
+ collect(): T;
3
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,18 @@
1
+ import { ICollector } from './interface';
2
+ type MemoryUsageResult = {
3
+ heapUsage: number;
4
+ heapSize: number;
5
+ rssMemory: number;
6
+ rssMemoryTotal: number;
7
+ externalMemory: number;
8
+ };
9
+ declare class MemoryCollector implements ICollector<MemoryUsageResult> {
10
+ collect(): {
11
+ heapUsage: number;
12
+ heapSize: number;
13
+ rssMemory: number;
14
+ rssMemoryTotal: number;
15
+ externalMemory: number;
16
+ };
17
+ }
18
+ export { MemoryCollector, MemoryUsageResult };
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MemoryCollector = void 0;
7
+ const node_os_1 = __importDefault(require("node:os"));
8
+ const node_process_1 = __importDefault(require("node:process"));
9
+ const utility_1 = require("../../utility");
10
+ class MemoryCollector {
11
+ collect() {
12
+ const toMB = (bytes) => (0, utility_1.convertBytes)(bytes, 'MB');
13
+ const memoryUsage = node_process_1.default.memoryUsage();
14
+ const totalMemory = node_os_1.default.totalmem();
15
+ return {
16
+ heapUsage: toMB(memoryUsage.heapUsed),
17
+ heapSize: toMB(memoryUsage.heapTotal),
18
+ rssMemory: toMB(memoryUsage.rss),
19
+ rssMemoryTotal: toMB(totalMemory),
20
+ externalMemory: toMB(memoryUsage.external),
21
+ };
22
+ }
23
+ }
24
+ exports.MemoryCollector = MemoryCollector;
@@ -0,0 +1,32 @@
1
+ import { ICollector } from './interface';
2
+ type RuntimeUsageResult = {
3
+ pid: number;
4
+ platform: NodeJS.Platform;
5
+ nodeVersion: string;
6
+ v8Version: string;
7
+ libuvVersion: string;
8
+ openSSLVersion: string;
9
+ threadPoolSize: number;
10
+ activeThreads: number;
11
+ startup: {
12
+ bootstrapTime: number;
13
+ requiredModules: number;
14
+ };
15
+ };
16
+ declare class RuntimeCollector implements ICollector<RuntimeUsageResult> {
17
+ collect(): {
18
+ pid: number;
19
+ platform: NodeJS.Platform;
20
+ nodeVersion: string;
21
+ v8Version: string;
22
+ libuvVersion: string;
23
+ openSSLVersion: string;
24
+ threadPoolSize: number;
25
+ activeThreads: any;
26
+ startup: {
27
+ bootstrapTime: number;
28
+ requiredModules: number;
29
+ };
30
+ };
31
+ }
32
+ export { RuntimeCollector, RuntimeUsageResult };
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.RuntimeCollector = void 0;
7
+ const node_process_1 = __importDefault(require("node:process"));
8
+ class RuntimeCollector {
9
+ collect() {
10
+ const threadPoolSize = node_process_1.default.env.UV_THREADPOOL_SIZE ? parseInt(node_process_1.default.env.UV_THREADPOOL_SIZE) : 4;
11
+ const activeThreads = node_process_1.default._getActiveRequests().length ?? 0;
12
+ return {
13
+ pid: node_process_1.default.pid,
14
+ platform: node_process_1.default.platform,
15
+ nodeVersion: node_process_1.default.version,
16
+ v8Version: node_process_1.default.versions.v8,
17
+ libuvVersion: node_process_1.default.versions.uv,
18
+ openSSLVersion: node_process_1.default.versions.openssl,
19
+ threadPoolSize: threadPoolSize,
20
+ activeThreads: activeThreads,
21
+ startup: {
22
+ bootstrapTime: performance.now(),
23
+ requiredModules: Object.keys(require.cache).length,
24
+ }
25
+ };
26
+ }
27
+ }
28
+ exports.RuntimeCollector = RuntimeCollector;
29
+ ;
@@ -0,0 +1,9 @@
1
+ declare class CorrelationService {
2
+ private readonly sampleSize;
3
+ constructor();
4
+ tick(): void;
5
+ private testCorrelation;
6
+ private handleReport;
7
+ }
8
+ export declare const correlationService: CorrelationService;
9
+ export {};
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.correlationService = void 0;
4
+ const local_repository_1 = require("../storage/local.repository");
5
+ const statistics_1 = require("../utility/statistics");
6
+ class CorrelationService {
7
+ sampleSize;
8
+ constructor() {
9
+ this.sampleSize =
10
+ (0, statistics_1.calculateSampleSizeProportion)(0.05, 0.95); //! This maybe from config?
11
+ }
12
+ tick() {
13
+ const totalHistory = local_repository_1.storage.bucket.getHistory();
14
+ const size = totalHistory.length;
15
+ if (size < this.sampleSize) {
16
+ return;
17
+ }
18
+ const rps = totalHistory.map(e => e.rps.count);
19
+ const errorRate = totalHistory.map(e => e.error.rate);
20
+ const heapUsage = totalHistory.map(e => e.health.memory.heapUsage);
21
+ const p95Latency = totalHistory.map(e => e.latency.p95);
22
+ const eventLoopLag = totalHistory.map(e => e.health.eventLoop.lag);
23
+ const averageLatency = totalHistory.map(e => e.latency.average);
24
+ // 1. eventLoopLag <-> p95 latency
25
+ this.handleReport(this.testCorrelation(eventLoopLag, p95Latency));
26
+ // 2. eventLoopLag <-> average latency
27
+ this.handleReport(this.testCorrelation(eventLoopLag, averageLatency));
28
+ // 3. heapUsage <-> eventLoopLag
29
+ this.handleReport(this.testCorrelation(heapUsage, eventLoopLag));
30
+ // 4. heapUsage <-> p95 latency
31
+ this.handleReport(this.testCorrelation(heapUsage, p95Latency));
32
+ // 5. rps <-> errorRate
33
+ this.handleReport(this.testCorrelation(rps, errorRate));
34
+ // 6. rps <-> latency
35
+ this.handleReport(this.testCorrelation(rps, averageLatency));
36
+ }
37
+ testCorrelation(x, y) {
38
+ const pearsonR = (0, statistics_1.pearsonCorrelation)(x, y);
39
+ const spearmanR = (0, statistics_1.spearmanCorrelation)(x, y);
40
+ const { determination, alienation } = (0, statistics_1.determinationAndAlienation)(pearsonR);
41
+ if (Math.abs(spearmanR) > 0.7 && Math.abs(pearsonR) <= 0.6) {
42
+ return {
43
+ status: 'NON_LINEAR_BURST',
44
+ recommendation: 'Kritično! Detektovan nelinearan (eksponencijalni) skok. Sistem ulazi u zonu zasićenja resursa.'
45
+ };
46
+ }
47
+ else if (spearmanR > 0.7 && determination > 0.5) {
48
+ if (alienation > 0.4) {
49
+ return {
50
+ status: 'EXTERNAL_INFLUENCE',
51
+ recommendation: `Uočena je povezanost (r=${spearmanR.toFixed(2)}), ali eksterni faktori utiču sa ${(alienation * 100).toFixed(1)}%. Ne donositi ishitren zaključak o uzročnosti.`
52
+ };
53
+ }
54
+ else {
55
+ return {
56
+ status: 'SYSTEMIC_LINEAR_DEGRADATION',
57
+ recommendation: `Linearna degradacija. Varijable zajednički rastu.`
58
+ };
59
+ }
60
+ }
61
+ return {
62
+ status: 'STABLE',
63
+ recommendation: 'Sistem je stabilan. Nema detektovanih uzročnih veza između posmatranih varijabli.'
64
+ };
65
+ }
66
+ handleReport(report) {
67
+ if (report.status === 'STABLE')
68
+ return;
69
+ local_repository_1.storage.alerts.warning(report.recommendation);
70
+ }
71
+ }
72
+ exports.correlationService = new CorrelationService();
@@ -0,0 +1,11 @@
1
+ import { Request, Response } from 'express';
2
+ declare class Logger {
3
+ private static readonly RESET;
4
+ private static readonly BOLD;
5
+ private static readonly DIM;
6
+ private static readonly COLORS;
7
+ static log(req: Request, res: Response, duration: number): void;
8
+ static debug(message: string): void;
9
+ static duration(message: string, duration: number): void;
10
+ }
11
+ export default Logger;