apm-optima 1.0.5 → 2.0.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 (177) hide show
  1. package/README.md +54 -23
  2. package/dashboard-out/404/index.html +1 -1
  3. package/dashboard-out/404.html +1 -1
  4. package/dashboard-out/__next.__PAGE__.txt +4 -4
  5. package/dashboard-out/__next._full.txt +17 -17
  6. package/dashboard-out/__next._head.txt +4 -4
  7. package/dashboard-out/__next._index.txt +10 -10
  8. package/dashboard-out/__next._tree.txt +2 -2
  9. package/dashboard-out/_next/static/chunks/{2xjcsu4pgp14_.js → 062oipeclh9bq.js} +1 -1
  10. package/dashboard-out/_next/static/chunks/0ncbimuip0-o7.css +3 -0
  11. package/dashboard-out/_next/static/chunks/0xtgenoch3q77.js +1 -0
  12. package/dashboard-out/_next/static/chunks/1xln1-s87x5yp.js +27 -0
  13. package/dashboard-out/_not-found/__next._full.txt +15 -15
  14. package/dashboard-out/_not-found/__next._head.txt +4 -4
  15. package/dashboard-out/_not-found/__next._index.txt +10 -10
  16. package/dashboard-out/_not-found/__next._not-found.__PAGE__.txt +2 -2
  17. package/dashboard-out/_not-found/__next._not-found.txt +3 -3
  18. package/dashboard-out/_not-found/__next._tree.txt +2 -2
  19. package/dashboard-out/_not-found/index.html +1 -1
  20. package/dashboard-out/_not-found/index.txt +15 -15
  21. package/dashboard-out/index.html +1 -1
  22. package/dashboard-out/index.txt +17 -17
  23. package/dist/adapters/session-export.handler.d.ts +4 -0
  24. package/dist/adapters/session-export.handler.js +29 -0
  25. package/dist/adapters/socket.options.d.ts +3 -0
  26. package/dist/adapters/socket.options.js +16 -0
  27. package/dist/config/config.manager.d.ts +80 -3
  28. package/dist/config/config.manager.js +269 -89
  29. package/dist/config/config.types.d.ts +89 -13
  30. package/dist/core/delivery/buckets-request.d.ts +2 -0
  31. package/dist/core/delivery/buckets-request.js +18 -0
  32. package/dist/core/delivery/index.d.ts +1 -0
  33. package/dist/core/delivery/index.js +1 -0
  34. package/dist/core/delivery/metrics.publisher.d.ts +23 -10
  35. package/dist/core/delivery/metrics.publisher.js +22 -22
  36. package/dist/core/delivery/websocket.events.d.ts +14 -3
  37. package/dist/core/delivery/websocket.events.js +13 -2
  38. package/dist/core/domain/correlation.types.d.ts +37 -0
  39. package/dist/core/domain/correlation.types.js +2 -0
  40. package/dist/core/domain/dashboard.types.d.ts +16 -69
  41. package/dist/core/domain/dashboard.types.js +29 -0
  42. package/dist/core/domain/endpoints.types.d.ts +3 -0
  43. package/dist/core/domain/event.types.d.ts +14 -0
  44. package/dist/core/domain/event.types.js +2 -0
  45. package/dist/core/domain/incident.types.d.ts +50 -0
  46. package/dist/core/domain/incident.types.js +2 -0
  47. package/dist/core/domain/index.d.ts +5 -0
  48. package/dist/core/domain/index.js +5 -0
  49. package/dist/core/domain/live-bucket.types.d.ts +86 -0
  50. package/dist/core/domain/live-bucket.types.js +2 -0
  51. package/dist/core/domain/metrics.types.d.ts +41 -11
  52. package/dist/core/domain/session.types.d.ts +93 -0
  53. package/dist/core/domain/session.types.js +2 -0
  54. package/dist/core/domain/telemetry.types.d.ts +1 -0
  55. package/dist/core/organizers/event.manager.d.ts +19 -0
  56. package/dist/core/organizers/event.manager.js +73 -0
  57. package/dist/core/organizers/index.d.ts +2 -0
  58. package/dist/core/organizers/index.js +18 -0
  59. package/dist/core/organizers/interval.manager.d.ts +18 -0
  60. package/dist/core/organizers/interval.manager.js +54 -0
  61. package/dist/core/storage/index.d.ts +1 -0
  62. package/dist/core/storage/index.js +1 -0
  63. package/dist/core/storage/local.repository.d.ts +12 -12
  64. package/dist/core/storage/local.repository.js +38 -38
  65. package/dist/core/storage/persistence/persistence-writer.d.ts +48 -0
  66. package/dist/core/storage/persistence/persistence-writer.js +191 -0
  67. package/dist/core/storage/persistence/segment-index.d.ts +27 -0
  68. package/dist/core/storage/persistence/segment-index.js +206 -0
  69. package/dist/core/storage/persistence/session-registry.d.ts +28 -0
  70. package/dist/core/storage/persistence/session-registry.js +127 -0
  71. package/dist/core/storage/persistence/session-summary.d.ts +3 -0
  72. package/dist/core/storage/persistence/session-summary.js +112 -0
  73. package/dist/core/storage/persistence.layer.d.ts +69 -0
  74. package/dist/core/storage/persistence.layer.js +404 -0
  75. package/dist/core/storage/runtime/anomaly-detector.d.ts +11 -0
  76. package/dist/core/storage/runtime/anomaly-detector.js +42 -0
  77. package/dist/core/storage/stores/analytics.store.d.ts +5 -5
  78. package/dist/core/storage/stores/analytics.store.js +39 -12
  79. package/dist/core/storage/stores/bucket-metric.d.ts +85 -0
  80. package/dist/core/storage/stores/bucket-metric.js +168 -0
  81. package/dist/core/storage/stores/bucket-view.d.ts +44 -0
  82. package/dist/core/storage/stores/bucket-view.js +63 -0
  83. package/dist/core/storage/stores/bucket.store.d.ts +39 -36
  84. package/dist/core/storage/stores/bucket.store.js +112 -60
  85. package/dist/core/storage/stores/dashboard.store.d.ts +11 -4
  86. package/dist/core/storage/stores/dashboard.store.js +179 -47
  87. package/dist/core/storage/stores/endpoint.store.d.ts +1 -0
  88. package/dist/core/storage/stores/endpoint.store.js +21 -5
  89. package/dist/core/storage/stores/index.d.ts +0 -7
  90. package/dist/core/storage/stores/index.js +0 -7
  91. package/dist/core/storage/stores/metrics.store.d.ts +1 -1
  92. package/dist/core/storage/stores/metrics.store.js +1 -0
  93. package/dist/core/storage/stores/runtime.store.d.ts +77 -0
  94. package/dist/core/storage/stores/runtime.store.js +222 -0
  95. package/dist/core/storage/utility/common.d.ts +1 -0
  96. package/dist/core/storage/utility/common.js +11 -0
  97. package/dist/core/storage/utility/file-buffer.d.ts +31 -0
  98. package/dist/core/storage/utility/file-buffer.js +238 -0
  99. package/dist/core/storage/utility/histogram.d.ts +1 -2
  100. package/dist/core/storage/utility/histogram.js +1 -2
  101. package/dist/core/storage/utility/index.d.ts +2 -0
  102. package/dist/core/storage/utility/index.js +2 -0
  103. package/dist/core/storage/utility/persistence-files.d.ts +3 -0
  104. package/dist/core/storage/utility/persistence-files.js +34 -0
  105. package/dist/core/storage/utility/persistence-writer.d.ts +39 -0
  106. package/dist/core/storage/utility/persistence-writer.js +183 -0
  107. package/dist/core/storage/utility/session-export.d.ts +3 -0
  108. package/dist/core/storage/utility/session-export.js +31 -0
  109. package/dist/core/storage/utility/session-registry.d.ts +21 -0
  110. package/dist/core/storage/utility/session-registry.js +91 -0
  111. package/dist/core/storage/utility/session-window.d.ts +8 -0
  112. package/dist/core/storage/utility/session-window.js +43 -0
  113. package/dist/core/telemetry/analytics.service.d.ts +18 -0
  114. package/dist/core/telemetry/analytics.service.js +100 -0
  115. package/dist/core/telemetry/collector.service.d.ts +17 -15
  116. package/dist/core/telemetry/collector.service.js +23 -80
  117. package/dist/core/telemetry/correlation.service.d.ts +57 -9
  118. package/dist/core/telemetry/correlation.service.js +246 -54
  119. package/dist/core/telemetry/dashboard-live.service.d.ts +10 -0
  120. package/dist/core/telemetry/dashboard-live.service.js +110 -0
  121. package/dist/core/telemetry/dashboard.service.d.ts +20 -0
  122. package/dist/core/telemetry/dashboard.service.js +140 -0
  123. package/dist/core/telemetry/incident.service.d.ts +71 -0
  124. package/dist/core/telemetry/incident.service.js +239 -0
  125. package/dist/core/telemetry/logger.d.ts +4 -0
  126. package/dist/core/telemetry/logger.js +5 -2
  127. package/dist/core/telemetry/runtime.service.d.ts +14 -0
  128. package/dist/core/telemetry/runtime.service.js +56 -0
  129. package/dist/core/telemetry/telemetry-query.service.d.ts +82 -0
  130. package/dist/core/telemetry/telemetry-query.service.js +231 -0
  131. package/dist/core/telemetry/telemetry.service.d.ts +10 -4
  132. package/dist/core/telemetry/telemetry.service.js +60 -10
  133. package/dist/core/telemetry/utility/correlation-analysis.d.ts +9 -0
  134. package/dist/core/telemetry/utility/correlation-analysis.js +143 -0
  135. package/dist/core/telemetry/utility/correlation-finding.d.ts +70 -0
  136. package/dist/core/telemetry/utility/correlation-finding.js +41 -0
  137. package/dist/core/telemetry/utility/correlation-input.d.ts +59 -0
  138. package/dist/core/telemetry/utility/correlation-input.js +139 -0
  139. package/dist/core/telemetry/utility/correlation-replay.d.ts +24 -0
  140. package/dist/core/telemetry/utility/correlation-replay.js +46 -0
  141. package/dist/core/utility/correlation.analysis.d.ts +9 -0
  142. package/dist/core/utility/correlation.analysis.js +144 -0
  143. package/dist/core/utility/statistics.d.ts +65 -0
  144. package/dist/core/utility/statistics.js +141 -0
  145. package/dist/express/index.d.ts +1 -1
  146. package/dist/express/index.js +7 -5
  147. package/dist/express/metrics-websocket.adapter.d.ts +8 -2
  148. package/dist/express/metrics-websocket.adapter.js +52 -19
  149. package/dist/express/metrics.adapter.d.ts +1 -0
  150. package/dist/express/metrics.adapter.js +8 -1
  151. package/dist/express/metrics.bootstrap.d.ts +6 -1
  152. package/dist/express/metrics.bootstrap.js +48 -22
  153. package/dist/express/metrics.dashboard.d.ts +2 -1
  154. package/dist/express/metrics.dashboard.js +4 -1
  155. package/dist/express/metrics.middleware.d.ts +2 -1
  156. package/dist/express/metrics.middleware.js +23 -20
  157. package/dist/nest/metrics-websocket.adapter.d.ts +19 -3
  158. package/dist/nest/metrics-websocket.adapter.js +101 -21
  159. package/dist/nest/metrics.adapter.d.ts +4 -1
  160. package/dist/nest/metrics.adapter.js +24 -1
  161. package/dist/nest/metrics.bootstrap.service.d.ts +7 -3
  162. package/dist/nest/metrics.bootstrap.service.js +56 -21
  163. package/dist/nest/metrics.interceptor.d.ts +3 -3
  164. package/dist/nest/metrics.interceptor.js +11 -8
  165. package/dist/nest/metrics.module.d.ts +3 -0
  166. package/dist/nest/metrics.module.js +27 -9
  167. package/dist/runtime/index.d.ts +32 -0
  168. package/dist/runtime/index.js +104 -0
  169. package/dist/simulation/simulation.d.ts +5 -16
  170. package/dist/simulation/simulation.js +5 -8
  171. package/package.json +2 -1
  172. package/dashboard-out/_next/static/chunks/23soo6qkun-yv.js +0 -1
  173. package/dashboard-out/_next/static/chunks/3xoopocxi2vi8.css +0 -3
  174. package/dashboard-out/_next/static/chunks/3z-nzyp9z8vih.js +0 -3
  175. /package/dashboard-out/_next/static/{kFIRZt4fuL4Zsh38-jGui → 17egwqgk36_DSRF55LJZG}/_buildManifest.js +0 -0
  176. /package/dashboard-out/_next/static/{kFIRZt4fuL4Zsh38-jGui → 17egwqgk36_DSRF55LJZG}/_clientMiddlewareManifest.js +0 -0
  177. /package/dashboard-out/_next/static/{kFIRZt4fuL4Zsh38-jGui → 17egwqgk36_DSRF55LJZG}/_ssgManifest.js +0 -0
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SessionRegistry = void 0;
4
+ const crypto_1 = require("crypto");
5
+ const index_1 = require("./index");
6
+ const emptyManifest = () => ({ version: 2, sessions: [] });
7
+ class SessionRegistry {
8
+ manifestPath;
9
+ writer;
10
+ manifest = emptyManifest();
11
+ dirty = false;
12
+ _current = null;
13
+ _recoveredFromCrash = false;
14
+ constructor(manifestPath, writer) {
15
+ this.manifestPath = manifestPath;
16
+ this.writer = writer;
17
+ }
18
+ get current() { return this._current; }
19
+ get all() { return this.manifest.sessions; }
20
+ get recoveredFromCrash() { return this._recoveredFromCrash; }
21
+ async start() {
22
+ const raw = await (0, index_1.tryOrDefault)(() => (0, index_1.readJSON)(this.manifestPath), null);
23
+ this.manifest = this.migrate(raw);
24
+ for (const s of this.manifest.sessions) {
25
+ if (s.status === 'RUNNING') {
26
+ s.status = 'INTERRUPTED';
27
+ s.endedAt = s.lastPersistedAt ?? s.startedAt;
28
+ this._recoveredFromCrash = true;
29
+ }
30
+ }
31
+ const number = this.manifest.sessions.reduce((m, s) => Math.max(m, s.sessionNumber), 0) + 1;
32
+ this._current = {
33
+ sessionId: (0, crypto_1.randomUUID)(),
34
+ sessionNumber: number,
35
+ startedAt: new Date().toISOString(),
36
+ endedAt: null,
37
+ lastPersistedAt: null,
38
+ lastCommitedSequence: 0,
39
+ status: 'RUNNING',
40
+ };
41
+ this.manifest.sessions.push(this._current);
42
+ await this.save('manifest: session start');
43
+ return this._current;
44
+ }
45
+ notePersisted() {
46
+ if (!this._current)
47
+ return;
48
+ this._current.lastPersistedAt = new Date().toISOString();
49
+ this._current.lastCommitedSequence = this.writer.commitedSequence;
50
+ this.dirty = true;
51
+ }
52
+ async heartbeat() {
53
+ if (!this.dirty)
54
+ return;
55
+ this.dirty = false;
56
+ await this.save('manifest: heartbeat').catch(() => { this.dirty = true; });
57
+ }
58
+ async complete() {
59
+ if (!this._current)
60
+ return;
61
+ await this.writer.whenIdle();
62
+ const now = new Date().toISOString();
63
+ this._current.status = 'COMPLETED';
64
+ this._current.endedAt = now;
65
+ this._current.lastPersistedAt = now;
66
+ this._current.lastCommitedSequence = this.writer.commitedSequence;
67
+ await this.save('manifest: session complete');
68
+ }
69
+ static windowEnd(s) {
70
+ return s.status === 'RUNNING' ? null : (s.endedAt ?? s.lastPersistedAt);
71
+ }
72
+ save(description) {
73
+ const snapshot = structuredClone(this.manifest);
74
+ return this.writer.enqueueTask(description, () => (0, index_1.writeJSONAtomic)(this.manifestPath, snapshot));
75
+ }
76
+ migrate(raw) {
77
+ if (raw?.version === 2 && Array.isArray(raw.sessions))
78
+ return raw;
79
+ const sessions = (raw?.sessionHistory ?? []).map((h) => ({
80
+ sessionId: `legacy-${h.sessionNumber}`,
81
+ sessionNumber: h.sessionNumber,
82
+ startedAt: h.startedAt,
83
+ endedAt: h.endedAt ?? null,
84
+ lastPersistedAt: h.endedAt ?? null,
85
+ lastCommittedSequence: 0,
86
+ status: h.endedAt ? 'COMPLETED' : 'INTERRUPTED',
87
+ }));
88
+ return { version: 2, sessions };
89
+ }
90
+ }
91
+ exports.SessionRegistry = SessionRegistry;
@@ -0,0 +1,8 @@
1
+ export interface SessionWindow {
2
+ start: Date;
3
+ end: Date;
4
+ }
5
+ export declare function getSessionWindow(startedAt: string, endedAt: string | null): SessionWindow;
6
+ export declare function getSessionDatesFromWindow(window: SessionWindow): string[];
7
+ export declare function getSessionHoursFromWindow(window: SessionWindow): string[];
8
+ export declare function hourKeyFor(date: Date | string): string;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSessionWindow = getSessionWindow;
4
+ exports.getSessionDatesFromWindow = getSessionDatesFromWindow;
5
+ exports.getSessionHoursFromWindow = getSessionHoursFromWindow;
6
+ exports.hourKeyFor = hourKeyFor;
7
+ function getSessionWindow(startedAt, endedAt) {
8
+ return {
9
+ start: new Date(startedAt),
10
+ end: endedAt ? new Date(endedAt) : new Date(),
11
+ };
12
+ }
13
+ function enumerateDates(start, end) {
14
+ const dates = [];
15
+ const cursor = new Date(Date.UTC(start.getUTCFullYear(), start.getUTCMonth(), start.getUTCDate()));
16
+ const last = new Date(Date.UTC(end.getUTCFullYear(), end.getUTCMonth(), end.getUTCDate()));
17
+ while (cursor <= last) {
18
+ dates.push(cursor.toISOString().slice(0, 10));
19
+ cursor.setUTCDate(cursor.getUTCDate() + 1);
20
+ }
21
+ return dates;
22
+ }
23
+ function getSessionDatesFromWindow(window) {
24
+ return enumerateDates(window.start, window.end);
25
+ }
26
+ function enumerateHours(start, end) {
27
+ const hours = [];
28
+ const cursor = new Date(Date.UTC(start.getUTCFullYear(), start.getUTCMonth(), start.getUTCDate(), start.getUTCHours()));
29
+ const last = new Date(Date.UTC(end.getUTCFullYear(), end.getUTCMonth(), end.getUTCDate(), end.getUTCHours()));
30
+ while (cursor <= last) {
31
+ hours.push(cursor.toISOString());
32
+ cursor.setUTCHours(cursor.getUTCHours() + 1);
33
+ }
34
+ return hours;
35
+ }
36
+ function getSessionHoursFromWindow(window) {
37
+ return enumerateHours(window.start, window.end);
38
+ }
39
+ function hourKeyFor(date) {
40
+ if (typeof date === 'string')
41
+ date = new Date(date);
42
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours())).toISOString();
43
+ }
@@ -0,0 +1,18 @@
1
+ import { type ReadonlyConfig } from "../../config";
2
+ import type { AnalyticsData, AnalyticsFilterSettings } from "../domain";
3
+ import type { TelemetryQueryService } from "./telemetry-query.service";
4
+ export declare class AnalyticsService {
5
+ private readonly queries;
6
+ readonly slowLatencyThreshold: number;
7
+ private readonly viewWindowBuckets;
8
+ private readonly topImpactRoutes;
9
+ constructor(queries: TelemetryQueryService, config: ReadonlyConfig);
10
+ private matchesFilters;
11
+ private toTelemetry;
12
+ get(page?: number, pageSize?: number, filters?: AnalyticsFilterSettings | undefined): AnalyticsData;
13
+ private impactEndpoints;
14
+ private calculateSummary;
15
+ private latencyDistribution;
16
+ private requestVolume;
17
+ private endpointName;
18
+ }
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AnalyticsService = void 0;
4
+ const config_1 = require("../../config");
5
+ const bucket_view_1 = require("../storage/stores/bucket-view");
6
+ const utility_1 = require("../utility");
7
+ class AnalyticsService {
8
+ queries;
9
+ slowLatencyThreshold;
10
+ viewWindowBuckets;
11
+ topImpactRoutes;
12
+ constructor(queries, config) {
13
+ this.queries = queries;
14
+ const dashboard = config.dashboard === false ? config_1.DEFAULT_CONFIG.dashboard : config.dashboard;
15
+ this.slowLatencyThreshold = config.thresholds.slowLatencyMs;
16
+ this.viewWindowBuckets = config.cache.viewWindowBuckets;
17
+ this.topImpactRoutes = dashboard.topImpactRoutes;
18
+ }
19
+ matchesFilters(endpoint, filters) {
20
+ if (!filters)
21
+ return true;
22
+ if (filters.method !== 'ALL' && endpoint.method !== filters.method)
23
+ return false;
24
+ if (filters.query && !endpoint.route.includes(filters.query))
25
+ return false;
26
+ return true;
27
+ }
28
+ toTelemetry(derived) {
29
+ return {
30
+ method: derived.method,
31
+ route: derived.route,
32
+ rps: derived.rps,
33
+ requestCount: derived.requestCount,
34
+ averageLatency: derived.averageLatency,
35
+ minLatency: derived.minLatency,
36
+ p50: derived.p50,
37
+ p95: derived.p95,
38
+ p99: derived.p99,
39
+ errorRate: derived.errorRate,
40
+ impactedRequests: derived.impactedRequests,
41
+ status: derived.status,
42
+ };
43
+ }
44
+ get(page = 1, pageSize = 20, filters = undefined) {
45
+ const recent = this.queries.recent(this.viewWindowBuckets, { consistency: 'live', includeEndpoints: true });
46
+ const endpointViews = (0, bucket_view_1.deriveEndpointView)(recent.points, this.slowLatencyThreshold);
47
+ const endpointList = endpointViews.filter(e => this.matchesFilters(e, filters))
48
+ .sort((a, b) => a.method.localeCompare(b.method));
49
+ const telemetryList = endpointList.map(e => this.toTelemetry(e));
50
+ const pagination = (0, utility_1.paginate)(telemetryList, page, pageSize);
51
+ return {
52
+ summary: this.calculateSummary(endpointList),
53
+ latencyDistribution: this.latencyDistribution(endpointList),
54
+ requestVolume: this.requestVolume(endpointList),
55
+ endpointsTable: {
56
+ data: pagination.data,
57
+ pagination: pagination.meta,
58
+ },
59
+ impactEndpoints: this.impactEndpoints(endpointViews),
60
+ history: [] // TODO: Remove in future, as history is not currently being used in the analytics dashboard
61
+ };
62
+ }
63
+ impactEndpoints(endpoints) {
64
+ return endpoints
65
+ .filter(e => e.impactedRequests > 0)
66
+ .sort((a, b) => b.impactedRequests - a.impactedRequests || b.requestCount - a.requestCount)
67
+ .slice(0, this.topImpactRoutes)
68
+ .map(e => this.toTelemetry(e));
69
+ }
70
+ calculateSummary(endpoints) {
71
+ return {
72
+ totalEndpoints: endpoints.length,
73
+ healthyEndpoints: endpoints.filter(e => e.errorRate === 0 && e.p95 < this.slowLatencyThreshold).length,
74
+ slowEndpoints: endpoints.filter(e => e.p95 >= this.slowLatencyThreshold).length,
75
+ slowEndpointsThreshold: this.slowLatencyThreshold,
76
+ errorEndpoints: endpoints.filter(e => e.errorRate > 0).length,
77
+ };
78
+ }
79
+ latencyDistribution(endpoints) {
80
+ return endpoints.map(endpoint => ({
81
+ endpoint: this.endpointName(endpoint),
82
+ p50: endpoint.p50,
83
+ p95: endpoint.p95,
84
+ p99: endpoint.p99,
85
+ }));
86
+ }
87
+ requestVolume(endpoints) {
88
+ return endpoints
89
+ .map(endpoint => ({
90
+ endpoint: this.endpointName(endpoint),
91
+ volume: endpoint.requestCount,
92
+ rps: endpoint.rps,
93
+ }))
94
+ .sort((a, b) => b.volume - a.volume);
95
+ }
96
+ endpointName(endpoint) {
97
+ return `${endpoint.method} ${endpoint.route}`;
98
+ }
99
+ }
100
+ exports.AnalyticsService = AnalyticsService;
@@ -1,18 +1,20 @@
1
- import type { SystemStaticInfo, AnalyticsData, DashboardData, HealthData } from '../domain';
2
- import { CPUCollector, MemoryCollector, EventLoopCollector, GCCollector, HandlesCollector, RuntimeCollector } from './collectors';
3
- declare class CollectorService {
4
- private readonly cpuCollector;
5
- private readonly memoryCollector;
6
- private readonly eventLoopCollector;
7
- private readonly gcCollector;
8
- private readonly handlesCollector;
9
- private readonly runtimeCollector;
10
- constructor(cpuCollector: CPUCollector, memoryCollector: MemoryCollector, eventLoopCollector: EventLoopCollector, gcCollector: GCCollector, handlesCollector: HandlesCollector, runtimeCollector: RuntimeCollector);
1
+ import { type SystemStaticInfo, type AnalyticsData, type HealthDetails, type AnalyticsFilterSettings, type BucketsMessage, type BucketsRequest } from '../domain';
2
+ import type { LocalRepository } from "../storage";
3
+ import { type ReadonlyConfig } from '../../config';
4
+ import type { DashboardService } from './dashboard.service';
5
+ import type { AnalyticsService } from './analytics.service';
6
+ import type { RuntimeService } from './runtime.service';
7
+ export declare class CollectorService {
8
+ private readonly storage;
9
+ private readonly dashboardService;
10
+ private readonly analyticsService;
11
+ private readonly runtimeService;
12
+ private readonly analyticsPageSize;
13
+ constructor(storage: LocalRepository, dashboardService: DashboardService, analyticsService: AnalyticsService, runtimeService: RuntimeService, config: ReadonlyConfig);
11
14
  getSystemStaticInfo(): SystemStaticInfo;
12
- getDashboardData(): DashboardData;
13
- getAnalyticsData(): AnalyticsData;
14
- getHealthData(): HealthData;
15
+ getAnalyticsData(filters?: AnalyticsFilterSettings): AnalyticsData;
16
+ getHealthData(): HealthDetails;
17
+ getLiveBuckets(): BucketsMessage | null;
18
+ getBackFill(req: BucketsRequest): Promise<BucketsMessage>;
15
19
  tick(): void;
16
20
  }
17
- export declare const collectorService: CollectorService;
18
- export {};
@@ -1,92 +1,35 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.collectorService = void 0;
4
- const storage_1 = require("../storage");
5
- const collectors_1 = require("./collectors");
3
+ exports.CollectorService = void 0;
6
4
  const config_1 = require("../../config");
7
5
  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;
6
+ storage;
7
+ dashboardService;
8
+ analyticsService;
9
+ runtimeService;
10
+ analyticsPageSize;
11
+ constructor(storage, dashboardService, analyticsService, runtimeService, config) {
12
+ this.storage = storage;
13
+ this.dashboardService = dashboardService;
14
+ this.analyticsService = analyticsService;
15
+ this.runtimeService = runtimeService;
16
+ this.analyticsPageSize = (config.dashboard === false ? config_1.DEFAULT_CONFIG.dashboard : config.dashboard).analyticsPageSize;
21
17
  }
22
18
  getSystemStaticInfo() {
23
- return storage_1.storage.system.get();
19
+ return this.runtimeService.getSystemStaticInfo();
24
20
  }
25
- getDashboardData() {
26
- return storage_1.storage.dashboard.get();
27
- }
28
- getAnalyticsData() {
29
- return storage_1.storage.analytics.get();
21
+ getAnalyticsData(filters) {
22
+ return this.analyticsService.get(filters?.page || 1, this.analyticsPageSize, filters);
30
23
  }
31
24
  getHealthData() {
32
- return storage_1.storage.health.get();
25
+ return this.runtimeService.get();
26
+ }
27
+ getLiveBuckets() {
28
+ return this.dashboardService.getLive();
33
29
  }
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();
30
+ getBackFill(req) {
31
+ return this.dashboardService.getBackFill(req);
90
32
  }
33
+ tick() { this.storage.tick(); }
91
34
  }
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());
35
+ exports.CollectorService = CollectorService;
@@ -1,9 +1,57 @@
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 {};
1
+ import { SystemAssessment, CorrelationPairResult, type CorrelationData, type RelatedFinding } from '../domain';
2
+ import type { TelemetryQueryService } from './telemetry-query.service';
3
+ import { type ReplayOutcome } from './utility/correlation-replay';
4
+ import { type CorrelationFinding, type CorrelationParameters } from './utility/correlation-finding';
5
+ export interface FindingStore {
6
+ save(finding: CorrelationFinding): Promise<boolean>;
7
+ find(findingId: string): Promise<CorrelationFinding | null>;
8
+ readonly durable: boolean;
9
+ }
10
+ export interface CorrelationDeps {
11
+ queries: TelemetryQueryService;
12
+ finding: FindingStore;
13
+ identity: {
14
+ sessionId: () => string;
15
+ instanceId: string;
16
+ };
17
+ }
18
+ export interface CorrelationServiceOptions {
19
+ minCorrelation: number;
20
+ alpha: number;
21
+ power: number;
22
+ strongThreshold: number;
23
+ maxLag: number;
24
+ maxWindow: number;
25
+ minCoverage: number;
26
+ evaluateEveryIntervals: number;
27
+ analysisIntervalMs: number;
28
+ }
29
+ export declare class CorrelationService {
30
+ readonly requiredSampleSize: number;
31
+ readonly parameters: CorrelationParameters;
32
+ private readonly deps;
33
+ private readonly transform;
34
+ private readonly scopes;
35
+ private readonly analysisIntervalMs;
36
+ private readonly evaluateEvery;
37
+ private busy;
38
+ private lastRunAt;
39
+ private readonly lastEvaluated;
40
+ private results;
41
+ private lowCoverage;
42
+ private assessment;
43
+ constructor(deps: CorrelationDeps, options: CorrelationServiceOptions);
44
+ getResults(): CorrelationPairResult[];
45
+ getAssessment(): SystemAssessment;
46
+ pack(): CorrelationData;
47
+ tick(now?: number): void;
48
+ private evaluate;
49
+ private seriesFor;
50
+ private buildFinding;
51
+ replay(findingId: string): Promise<ReplayOutcome>;
52
+ private publish;
53
+ private toUiResult;
54
+ private isStrongPositive;
55
+ private assess;
56
+ relatedFindings(metric: string): RelatedFinding[];
57
+ }