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,119 @@
1
+ /**
2
+ * Represents CPU metrics, including usage rate, number of cores, per-core usage, and breakdown of user, system, and idle usage.
3
+ * @property {number} usageRate - The overall CPU usage rate (as a percentage).
4
+ * @property {number} numberOfCores - The total number of CPU cores.
5
+ * @property {number[]} perCoreUsage - An array representing the usage rate for each individual core (as percentages).
6
+ * @property {number} userUsage - The CPU usage attributed to user processes (as a percentage).
7
+ * @property {number} systemUsage - The CPU usage attributed to system processes (as a percentage).
8
+ * @property {number} idleUsage - The CPU usage attributed to idle time (as a percentage).
9
+ */
10
+ export interface CpuMetrics {
11
+ usageRate: number;
12
+ numberOfCores: number;
13
+ perCoreUsage: number[];
14
+ userUsage: number;
15
+ systemUsage: number;
16
+ idleUsage: number;
17
+ }
18
+ /**
19
+ * Represents memory metrics, including heap usage, heap size, resident set size (RSS) memory, total RSS memory, and external memory usage.
20
+ * @property {number} heapUsage - The amount of memory currently used by the V8 heap (in bytes).
21
+ * @property {number} heapSize - The total size of the V8 heap (in bytes).
22
+ * @property {number} rssMemory - The amount of resident set size (RSS) memory currently used by the process (in bytes).
23
+ * @property {number} rssMemoryTotal - The total amount of RSS memory available to the process (in bytes).
24
+ * @property {number} externalMemory - The amount of memory used by C++ objects bound to JavaScript objects managed by V8 (in bytes).
25
+ */
26
+ export interface MemoryMetrics {
27
+ heapUsage: number;
28
+ heapSize: number;
29
+ rssMemory: number;
30
+ rssMemoryTotal: number;
31
+ externalMemory: number;
32
+ }
33
+ /**
34
+ * Represents event loop metrics, including the current lag and the threshold for acceptable lag.
35
+ * @property {number} lag - The current event loop lag (in milliseconds).
36
+ * @property {number} threshold - The threshold for acceptable event loop lag (in milliseconds).
37
+ */
38
+ export interface EventLoopMetrics {
39
+ lag: number;
40
+ threshold: number;
41
+ }
42
+ /**
43
+ * Represents garbage collection (GC) metrics, including counts, times, pause averages, summaries for different GC types, heap space allocations, and overall GC totals.
44
+ * @property {number} gcCount - The total number of garbage collection runs.
45
+ * @property {number} gcTime - The total time spent in garbage collection (in milliseconds).
46
+ * @property {number} gcPauseAverage - The average pause time during garbage collection (in milliseconds).
47
+ * @property {GCRunSummary} minorGC - Summary metrics for minor garbage collections.
48
+ * @property {GCRunSummary} majorGC - Summary metrics for major garbage collections.
49
+ * @property {GCRunSummary} incrementalGC - Summary metrics for incremental garbage collections.
50
+ * @property {HeapSpaceAllocation[]} heapSpaces - An array of heap space allocations, each representing a specific heap space and its used memory.
51
+ * @property {GCTotals} gcTotals - Overall totals for garbage collection, including total pause time, freed memory, promotions, and tenured size.
52
+ */
53
+ export interface GCMetrics {
54
+ gcCount: number;
55
+ gcTime: number;
56
+ gcPauseAverage: number;
57
+ minorGC: GCRunSummary;
58
+ majorGC: GCRunSummary;
59
+ incrementalGC: GCRunSummary;
60
+ heapSpaces: HeapSpaceAllocation[];
61
+ gcTotals: GCTotals;
62
+ }
63
+ interface GCRunSummary {
64
+ runCount: number;
65
+ averageTime: number;
66
+ }
67
+ interface HeapSpaceAllocation {
68
+ label: string;
69
+ used: number;
70
+ }
71
+ interface GCTotals {
72
+ totalPauseTime: number;
73
+ freedMemory: number;
74
+ promotions: number;
75
+ tenuredSize: number;
76
+ }
77
+ /**
78
+ * Represents libuv metrics, including counts of active handles, timers, sockets, and file descriptors.
79
+ * @property {number} activeHandles - The total number of active libuv handles.
80
+ * @property {number} activeHandlesTimers - The number of active libuv timer handles.
81
+ * @property {number} activeHandlesSockets - The number of active libuv socket handles.
82
+ * @property {number} activeLibuvHandles - The total number of active libuv handles (including timers and sockets).
83
+ * @property {number} timers - The total number of libuv timers.
84
+ * @property {number} fileDescriptors - The total number of file descriptors used by the process.
85
+ */
86
+ export interface LibuvHandles {
87
+ activeHandles: number;
88
+ activeHandlesTimers: number;
89
+ activeHandlesSockets: number;
90
+ activeLibuvHandles: number;
91
+ timers: number;
92
+ fileDescriptors: number;
93
+ }
94
+ /**
95
+ * Represents historic time series data for various metrics, including requests per second (RPS), latency, error rate, event loop lag, heap usage, heap size, resident set size (RSS) memory, total heap memory, and optional percentiles (p95 and p99).
96
+ * @property {number[]} rps - An array of requests per second (RPS) values over time.
97
+ * @property {number[]} latency - An array of latency values over time.
98
+ * @property {number[]} errorRate - An array of error rate values over time.
99
+ * @property {number[]} eventLoopLag - An array of event loop lag values over time.
100
+ * @property {number[]} heapUsage - An array of heap usage values over time.
101
+ * @property {number[]} heapSize - An array of heap size values over time.
102
+ * @property {number[]} rssMemory - An array of resident set size (RSS) memory values over time.
103
+ * @property {number[]} totalHeap - An array of total heap memory values over time (from health memory breakdown).
104
+ * @property {number[]} [p95] - Optional array of 95th percentile latency values over time.
105
+ * @property {number[]} [p99] - Optional array of 99th percentile latency values over time.
106
+ */
107
+ export interface HistoricTimeSeries {
108
+ rps: number[];
109
+ latency: number[];
110
+ errorRate: number[];
111
+ eventLoopLag: number[];
112
+ heapUsage: number[];
113
+ heapSize: number[];
114
+ rssMemory: number[];
115
+ totalHeap: number[];
116
+ p95?: number[];
117
+ p99?: number[];
118
+ }
119
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,51 @@
1
+ import type { ConnectionStatus, HealthStatus } from './common.types';
2
+ /**
3
+ * Represents the overall system status, including connection status, health status, and WebSocket connection status.
4
+ * @property {ConnectionStatus} connectionStatus - The current connection status of the system (ONLINE, OFFLINE, CONNECTING, DISCONNECTED).
5
+ * @property {HealthStatus} healthStatus - The current health status of the system (HEALTHY, DEGRADED, UNHEALTHY, UNKNOWN).
6
+ * @property {ConnectionStatus} webSocketStatus - The current WebSocket connection status (ONLINE, OFFLINE, CONNECTING, DISCONNECTED).
7
+ */
8
+ export interface SystemStatus {
9
+ connectionStatus: ConnectionStatus;
10
+ healthStatus: HealthStatus;
11
+ webSocketStatus: ConnectionStatus;
12
+ }
13
+ /**
14
+ * Represents static information about the system, including uptime, Node.js version, and environment.
15
+ * @property {number} uptime - The system uptime in seconds.
16
+ * @property {string} nodeVersion - The version of Node.js running the system.
17
+ * @property {string} env - The current environment (e.g., 'development', 'production').
18
+ */
19
+ export interface SystemStaticInfo {
20
+ uptime: number;
21
+ nodeVersion: string;
22
+ env: string;
23
+ }
24
+ /**
25
+ * Represents detailed information about the V8 runtime environment, including process ID, platform, Node.js version, V8 version, libuv version, OpenSSL version, thread pool size, active threads, and startup metrics.
26
+ * @property {number} pid - The process ID of the Node.js process.
27
+ * @property {string} platform - The operating system platform (e.g., 'linux', 'darwin', 'win32').
28
+ * @property {string} nodeVersion - The version of Node.js running the system.
29
+ * @property {string} v8Version - The version of the V8 JavaScript engine.
30
+ * @property {string} libuvVersion - The version of the libuv library used by Node.js.
31
+ * @property {string} openSSLVersion - The version of OpenSSL used by Node.js.
32
+ * @property {number} threadPoolSize - The size of the libuv thread pool.
33
+ * @property {number} activeThreads - The number of active threads in the thread pool.
34
+ * @property {object} startup - An object containing startup metrics, including bootstrap time and required modules count.
35
+ * @property {number} startup.bootstrapTime - The time taken for the Node.js process to bootstrap (in milliseconds).
36
+ * @property {number} startup.requiredModules - The number of modules required during startup.
37
+ */
38
+ export interface V8RuntimeInfo {
39
+ pid: number;
40
+ platform: string;
41
+ nodeVersion: string;
42
+ v8Version: string;
43
+ libuvVersion: string;
44
+ openSSLVersion: string;
45
+ threadPoolSize: number;
46
+ activeThreads: number;
47
+ startup: {
48
+ bootstrapTime: number;
49
+ requiredModules: number;
50
+ };
51
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,8 @@
1
+ export interface TelemetryRequest {
2
+ timestamp: number;
3
+ endpoint: string;
4
+ method: string;
5
+ statusCode: number;
6
+ responseTime: number;
7
+ clientIp?: string;
8
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,3 @@
1
+ export * from './stores';
2
+ export * from './utility';
3
+ export * from './local.repository';
@@ -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
+ __exportStar(require("./stores"), exports);
18
+ __exportStar(require("./utility"), exports);
19
+ __exportStar(require("./local.repository"), exports);
@@ -0,0 +1,17 @@
1
+ import type { TelemetryRequest } from '../domain';
2
+ import { BucketStore, DashboardStore, AnalyticsStore, HealthStore, SystemStore, EndpointStore, AlertStore, MetricsStore } from './stores';
3
+ declare class LocalRepository {
4
+ readonly endpoint: EndpointStore;
5
+ readonly alerts: AlertStore;
6
+ readonly metrics: MetricsStore;
7
+ readonly health: HealthStore;
8
+ readonly bucket: BucketStore;
9
+ readonly dashboard: DashboardStore;
10
+ readonly analytics: AnalyticsStore;
11
+ readonly system: SystemStore;
12
+ constructor();
13
+ record(request: TelemetryRequest): void;
14
+ tick(): void;
15
+ }
16
+ export declare const storage: LocalRepository;
17
+ export {};
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.storage = void 0;
4
+ const config_1 = require("../../config");
5
+ const stores_1 = require("./stores");
6
+ class LocalRepository {
7
+ // Standard Stores
8
+ endpoint;
9
+ alerts;
10
+ metrics;
11
+ // Historics Store
12
+ health;
13
+ bucket;
14
+ // Core Stores
15
+ dashboard;
16
+ analytics;
17
+ system;
18
+ constructor() {
19
+ const config = (0, config_1.getConfig)();
20
+ // Standard
21
+ this.endpoint = new stores_1.EndpointStore();
22
+ this.alerts = new stores_1.AlertStore(config.alertBufferSize);
23
+ this.metrics = new stores_1.MetricsStore();
24
+ // Historic
25
+ this.health = new stores_1.HealthStore(config.ringBufferSize, config.publisher.eventLoopLagThresholdMs);
26
+ this.bucket = new stores_1.BucketStore(this.endpoint, this.health, this.metrics, config.ringBufferSize);
27
+ this.dashboard = new stores_1.DashboardStore(this.bucket, this.health, this.endpoint, this.alerts);
28
+ this.analytics = new stores_1.AnalyticsStore(this.bucket, this.endpoint, config.publisher.slowLatencyThresholdMs);
29
+ this.system = new stores_1.SystemStore();
30
+ }
31
+ record(request) {
32
+ const data = {
33
+ method: request.method,
34
+ route: request.endpoint,
35
+ duration: request.responseTime,
36
+ statusCode: request.statusCode
37
+ };
38
+ this.endpoint.record(data);
39
+ const status = this.metrics.record({
40
+ duration: request.responseTime,
41
+ statusCode: request.statusCode
42
+ });
43
+ if (status === 'ANOMALY') {
44
+ this.alerts.warning(`Anomaly detected: ${request.method} ${request.endpoint} took ${request.responseTime}ms`);
45
+ }
46
+ this.bucket.recordRequest(request.method, request.endpoint);
47
+ }
48
+ tick() {
49
+ this.bucket.flush();
50
+ }
51
+ }
52
+ exports.storage = new LocalRepository();
@@ -0,0 +1,13 @@
1
+ import type { AlertMessage } from '../../domain';
2
+ declare class AlertStore {
3
+ private readonly alerts;
4
+ constructor(bufferSize?: number);
5
+ add(alert: AlertMessage): void;
6
+ critical(title: string): void;
7
+ warning(title: string): void;
8
+ info(title: string): void;
9
+ get(count?: number): AlertMessage[];
10
+ latest(): AlertMessage | undefined;
11
+ clear(): void;
12
+ }
13
+ export { AlertStore };
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AlertStore = void 0;
4
+ const utility_1 = require("../utility");
5
+ const SEVERITY_PRIORITY = {
6
+ info: 0,
7
+ advisory: 1,
8
+ warning: 2,
9
+ critical: 3,
10
+ };
11
+ class AlertStore {
12
+ alerts;
13
+ constructor(bufferSize = 100) {
14
+ this.alerts =
15
+ new utility_1.RingBuffer(bufferSize);
16
+ }
17
+ add(alert) {
18
+ this.alerts.push({
19
+ ...alert,
20
+ id: crypto.randomUUID(),
21
+ });
22
+ }
23
+ critical(title) {
24
+ this.add({
25
+ title,
26
+ timestamp: new Date().toISOString(),
27
+ severity: "critical",
28
+ });
29
+ }
30
+ warning(title) {
31
+ this.add({
32
+ title,
33
+ timestamp: new Date().toISOString(),
34
+ severity: "warning",
35
+ });
36
+ }
37
+ info(title) {
38
+ this.add({
39
+ title,
40
+ timestamp: new Date().toISOString(),
41
+ severity: "info",
42
+ });
43
+ }
44
+ get(count) {
45
+ return this.alerts
46
+ .values()
47
+ .sort((a, b) => SEVERITY_PRIORITY[b.severity] -
48
+ SEVERITY_PRIORITY[a.severity])
49
+ .slice(0, count === undefined ? undefined : count)
50
+ .map(alert => ({
51
+ title: alert.title,
52
+ timestamp: alert.timestamp,
53
+ severity: alert.severity,
54
+ }));
55
+ }
56
+ latest() {
57
+ const alert = this.alerts.latest();
58
+ if (!alert) {
59
+ return undefined;
60
+ }
61
+ return {
62
+ title: alert.title,
63
+ timestamp: alert.timestamp,
64
+ severity: alert.severity,
65
+ };
66
+ }
67
+ clear() {
68
+ this.alerts.clear();
69
+ }
70
+ }
71
+ exports.AlertStore = AlertStore;
@@ -0,0 +1,15 @@
1
+ import type { AnalyticsData } from "../../domain";
2
+ import { EndpointStore } from "./endpoint.store";
3
+ import type { BucketStore } from "./bucket.store";
4
+ declare class AnalyticsStore {
5
+ private readonly buckets;
6
+ private readonly endpoints;
7
+ private readonly slowLatencyThreshold;
8
+ constructor(buckets: BucketStore, endpoints: EndpointStore, slowLatencyThreshold?: number);
9
+ get(page?: number, pageSize?: number): AnalyticsData;
10
+ private calculateSummary;
11
+ private latencyDistribution;
12
+ private requestVolume;
13
+ private endpointName;
14
+ }
15
+ export { AnalyticsStore };
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AnalyticsStore = void 0;
4
+ const utility_1 = require("../../utility");
5
+ class AnalyticsStore {
6
+ buckets;
7
+ endpoints;
8
+ slowLatencyThreshold;
9
+ constructor(buckets, endpoints, slowLatencyThreshold = 500) {
10
+ this.buckets = buckets;
11
+ this.endpoints = endpoints;
12
+ this.slowLatencyThreshold = slowLatencyThreshold;
13
+ }
14
+ get(page = 1, pageSize = 20) {
15
+ const history = this.buckets.getHistory();
16
+ const endpointList = this.endpoints.all();
17
+ const pagination = (0, utility_1.paginate)(endpointList, page, pageSize);
18
+ return {
19
+ summary: this.calculateSummary(endpointList),
20
+ latencyDistribution: this.latencyDistribution(endpointList),
21
+ requestVolume: this.requestVolume(endpointList),
22
+ endpointsTable: {
23
+ data: pagination.data,
24
+ pagination: pagination.meta,
25
+ },
26
+ history: history.map(bucket => bucket.endpoints),
27
+ };
28
+ }
29
+ calculateSummary(endpoints) {
30
+ return {
31
+ totalEndpoints: endpoints.length,
32
+ healthyEndpoints: endpoints.filter(e => e.errorRate === 0 && (e.p95 ?? 0) < this.slowLatencyThreshold).length,
33
+ slowEndpoints: endpoints.filter(e => (e.p95 ?? 0) >= this.slowLatencyThreshold).length,
34
+ slowEndpointsThreshold: this.slowLatencyThreshold,
35
+ errorEndpoints: endpoints.filter(e => e.errorRate > 0).length,
36
+ };
37
+ }
38
+ latencyDistribution(endpoints) {
39
+ return endpoints.map(endpoint => ({
40
+ endpoint: this.endpointName(endpoint),
41
+ p50: endpoint.averageLatency ?? 0,
42
+ p95: endpoint.p95 ?? 0,
43
+ p99: endpoint.p99 ?? 0,
44
+ }));
45
+ }
46
+ requestVolume(endpoints) {
47
+ return endpoints
48
+ .map(endpoint => ({
49
+ endpoint: this.endpointName(endpoint),
50
+ volume: endpoint.requestCount ?? 0,
51
+ rps: endpoint.rps,
52
+ }))
53
+ .sort((a, b) => b.volume - a.volume);
54
+ }
55
+ endpointName(endpoint) {
56
+ return `${endpoint.method} ${endpoint.route}`;
57
+ }
58
+ }
59
+ exports.AnalyticsStore = AnalyticsStore;
@@ -0,0 +1,40 @@
1
+ import type { EndpointTelemetry } from '../../domain';
2
+ import { HealthStore } from "../stores/health.store";
3
+ import type { EndpointStore } from "../stores/endpoint.store";
4
+ import type { MetricsStore } from "../stores/metrics.store";
5
+ export interface TelemetryBucket {
6
+ timestamp: number;
7
+ rps: {
8
+ count: number;
9
+ perEndpoints: Map<string, number>;
10
+ };
11
+ latency: {
12
+ average: number;
13
+ p50: number;
14
+ p95: number;
15
+ p99: number;
16
+ };
17
+ error: {
18
+ rate: number;
19
+ clientCount: number;
20
+ serverCount: number;
21
+ };
22
+ endpoints: EndpointTelemetry[];
23
+ health: ReturnType<HealthStore["get"]>;
24
+ }
25
+ export declare class BucketStore {
26
+ private readonly endpointStore;
27
+ private readonly healthStore;
28
+ private readonly metricsStore;
29
+ private readonly history;
30
+ private currentSecond;
31
+ private requestCount;
32
+ private endpointRequests;
33
+ constructor(endpointStore: EndpointStore, healthStore: HealthStore, metricsStore: MetricsStore, bufferSize?: number);
34
+ recordRequest(method: string, route: string): void;
35
+ flush(): void;
36
+ getHistory(): TelemetryBucket[];
37
+ latest(): TelemetryBucket | undefined;
38
+ private reset;
39
+ private getSecond;
40
+ }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BucketStore = void 0;
4
+ const utility_1 = require("../utility");
5
+ class BucketStore {
6
+ endpointStore;
7
+ healthStore;
8
+ metricsStore;
9
+ history;
10
+ currentSecond;
11
+ requestCount;
12
+ endpointRequests;
13
+ constructor(endpointStore, healthStore, metricsStore, bufferSize = 60) {
14
+ this.endpointStore = endpointStore;
15
+ this.healthStore = healthStore;
16
+ this.metricsStore = metricsStore;
17
+ this.history = new utility_1.RingBuffer(bufferSize);
18
+ this.currentSecond = this.getSecond();
19
+ this.requestCount = 0;
20
+ this.endpointRequests = new Map();
21
+ }
22
+ recordRequest(method, route) {
23
+ this.requestCount++;
24
+ const key = `${method}:${route}`;
25
+ const count = this.endpointRequests.get(key) ?? 0;
26
+ this.endpointRequests.set(key, count + 1);
27
+ }
28
+ flush() {
29
+ const now = this.getSecond();
30
+ // same second
31
+ if (now === this.currentSecond) {
32
+ return;
33
+ }
34
+ const endpoints = this.endpointStore.all();
35
+ const metrics = this.metricsStore.snapshot();
36
+ const bucket = {
37
+ timestamp: this.currentSecond,
38
+ rps: {
39
+ count: this.requestCount,
40
+ perEndpoints: new Map(this.endpointRequests),
41
+ },
42
+ latency: {
43
+ average: metrics.averageLatency,
44
+ p50: metrics.latency.p50,
45
+ p95: metrics.latency.p95,
46
+ p99: metrics.latency.p99,
47
+ },
48
+ error: {
49
+ rate: metrics.errorRate,
50
+ clientCount: metrics.errorClientCount,
51
+ serverCount: metrics.errorServerCount,
52
+ },
53
+ endpoints,
54
+ health: this.healthStore.get(),
55
+ };
56
+ this.history.push(bucket);
57
+ this.reset();
58
+ this.metricsStore.reset();
59
+ this.currentSecond = now;
60
+ }
61
+ getHistory() {
62
+ return this.history.values();
63
+ }
64
+ latest() {
65
+ return this.history.latest();
66
+ }
67
+ reset() {
68
+ this.requestCount = 0;
69
+ this.endpointRequests.clear();
70
+ }
71
+ getSecond() {
72
+ return (Math.floor(Date.now() / 1000) * 1000);
73
+ }
74
+ }
75
+ exports.BucketStore = BucketStore;
@@ -0,0 +1,15 @@
1
+ import type { DashboardData } from '../../domain';
2
+ import type { BucketStore } from './bucket.store';
3
+ import type { HealthStore } from './health.store';
4
+ import type { EndpointStore } from './endpoint.store';
5
+ import type { AlertStore } from './alert.store';
6
+ declare class DashboardStore {
7
+ private readonly buckets;
8
+ private readonly health;
9
+ private readonly endpoints;
10
+ private readonly alerts;
11
+ constructor(buckets: BucketStore, health: HealthStore, endpoints: EndpointStore, alerts: AlertStore);
12
+ get(): DashboardData;
13
+ private getImpactEndpoints;
14
+ }
15
+ export { DashboardStore };
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DashboardStore = void 0;
4
+ class DashboardStore {
5
+ buckets;
6
+ health;
7
+ endpoints;
8
+ alerts;
9
+ constructor(buckets, health, endpoints, alerts) {
10
+ this.buckets = buckets;
11
+ this.health = health;
12
+ this.endpoints = endpoints;
13
+ this.alerts = alerts;
14
+ }
15
+ get() {
16
+ const history = this.buckets.getHistory();
17
+ const latest = history[history.length - 1];
18
+ const health = this.health.get();
19
+ return {
20
+ current: {
21
+ rps: latest?.rps.count ?? 0,
22
+ latency: latest?.latency.average ?? 0,
23
+ errorRate: latest?.error.rate ?? 0,
24
+ eventLoopLag: health.eventLoop.lag,
25
+ heapUsage: health.memory.heapUsage,
26
+ heapSize: health.memory.heapSize
27
+ },
28
+ history: {
29
+ rps: history.map(bucket => bucket.rps.count),
30
+ latency: history.map(bucket => bucket.latency.average),
31
+ errorRate: history.map(bucket => bucket.error.rate),
32
+ eventLoopLag: history.map(bucket => bucket.health.eventLoop.lag),
33
+ heapUsage: history.map(bucket => bucket.health.memory.heapUsage),
34
+ heapSize: history.map(bucket => bucket.health.memory.heapSize),
35
+ rssMemory: history.map(bucket => bucket.health.memory.rssMemory),
36
+ totalHeap: history.map(bucket => bucket.health.memory.heapSize),
37
+ p95: history.map(bucket => bucket.latency.p95),
38
+ p99: history.map(bucket => bucket.latency.p99)
39
+ },
40
+ charts: {
41
+ throughput: {
42
+ rps: history.map(bucket => bucket.rps.count),
43
+ errorClient: history.map(bucket => bucket.error.clientCount),
44
+ errorServer: history.map(bucket => bucket.error.serverCount),
45
+ totalCount: history.reduce((acc, bucket) => acc + bucket.rps.count, 0)
46
+ },
47
+ percentiles: {
48
+ p50: history.map(bucket => bucket.latency.p50),
49
+ p95: history.map(bucket => bucket.latency.p95),
50
+ p99: history.map(bucket => bucket.latency.p99),
51
+ totalCount: history.reduce((acc, bucket) => acc + bucket.rps.count, 0)
52
+ },
53
+ runtimePerformance: {
54
+ heapUsage: history.map(bucket => bucket.health.memory.heapUsage),
55
+ heapSize: history.map(bucket => bucket.health.memory.heapSize),
56
+ lag: history.map(bucket => bucket.health.eventLoop.lag),
57
+ totalCount: history.reduce((acc, bucket) => acc + bucket.rps.count, 0)
58
+ }
59
+ },
60
+ impactEndpoints: this.getImpactEndpoints(),
61
+ alerts: this.alerts.get(5)
62
+ };
63
+ }
64
+ getImpactEndpoints() {
65
+ return this.endpoints
66
+ .all()
67
+ .filter(endpoint => {
68
+ return (endpoint.errorRate > 0 ||
69
+ endpoint.p95 > 500);
70
+ })
71
+ .sort((a, b) => {
72
+ const aScore = a.errorRate * 1000 + (a.p95 ?? 0);
73
+ const bScore = b.errorRate * 1000 + (b.p95 ?? 0);
74
+ return bScore - aScore;
75
+ }).slice(0, 10);
76
+ }
77
+ }
78
+ exports.DashboardStore = DashboardStore;