@oneuptime/common 10.0.71 → 10.0.73

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 (115) hide show
  1. package/Models/DatabaseModels/Alert.ts +55 -0
  2. package/Models/DatabaseModels/Incident.ts +55 -0
  3. package/Models/DatabaseModels/Project.ts +26 -0
  4. package/Models/DatabaseModels/Service.ts +2 -2
  5. package/Models/DatabaseModels/StatusPage.ts +80 -0
  6. package/Server/API/StatusPageAPI.ts +4 -0
  7. package/Server/Infrastructure/Postgres/SchemaMigrations/1776940714709-MigrationName.ts +41 -0
  8. package/Server/Infrastructure/Postgres/SchemaMigrations/1776971364783-AddStatusPageLanguageSettings.ts +25 -0
  9. package/Server/Infrastructure/Postgres/SchemaMigrations/1777018175127-AddTelemetryRetentionSettings.ts +25 -0
  10. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  11. package/Server/Services/AnalyticsDatabaseService.ts +17 -7
  12. package/Server/Services/OpenTelemetryIngestService.ts +36 -5
  13. package/Server/Services/ServiceService.ts +27 -1
  14. package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +175 -29
  15. package/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.ts +71 -0
  16. package/Server/Utils/Monitor/MonitorAlert.ts +91 -7
  17. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +171 -2
  18. package/Server/Utils/Monitor/MonitorIncident.ts +133 -8
  19. package/Server/Utils/Monitor/MonitorMetricUtil.ts +423 -1
  20. package/Server/Utils/Monitor/MonitorResource.ts +2 -0
  21. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +99 -0
  22. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.ts +268 -0
  23. package/Types/AdminDashboard/AdminDashboardLanguage.ts +33 -0
  24. package/Types/Infrastructure/BasicMetrics.ts +75 -0
  25. package/Types/Metrics/MetricQueryData.ts +11 -0
  26. package/Types/Monitor/CriteriaFilter.ts +10 -0
  27. package/Types/Monitor/MetricMonitor/MetricCriteriaContext.ts +11 -0
  28. package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +10 -0
  29. package/Types/Monitor/MetricMonitor/MetricSeriesResult.ts +20 -0
  30. package/Types/Monitor/MonitorMetricType.ts +34 -0
  31. package/Types/Monitor/ServerMonitor/ServerMonitorResponse.ts +8 -0
  32. package/Types/Probe/ProbeApiIngestResponse.ts +25 -0
  33. package/Types/StatusPage/StatusPageLanguage.ts +30 -0
  34. package/UI/Components/Charts/Area/AreaChart.tsx +17 -12
  35. package/UI/Components/Charts/Bar/BarChart.tsx +16 -11
  36. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +23 -0
  37. package/UI/Components/Charts/Line/LineChart.tsx +16 -11
  38. package/UI/Components/Filters/FiltersForm.tsx +26 -2
  39. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +453 -0
  40. package/UI/Components/MonitorTemplateVariables/TemplateVariablesModal.tsx +229 -0
  41. package/Utils/Metrics/MetricSeriesFingerprint.ts +97 -0
  42. package/Utils/Monitor/MonitorMetricType.ts +309 -19
  43. package/build/dist/Models/DatabaseModels/Alert.js +57 -0
  44. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  45. package/build/dist/Models/DatabaseModels/Incident.js +57 -0
  46. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  47. package/build/dist/Models/DatabaseModels/Project.js +27 -0
  48. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  49. package/build/dist/Models/DatabaseModels/Service.js +1 -2
  50. package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
  51. package/build/dist/Models/DatabaseModels/StatusPage.js +82 -0
  52. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  53. package/build/dist/Server/API/StatusPageAPI.js +4 -0
  54. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  55. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776940714709-MigrationName.js +22 -0
  56. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776940714709-MigrationName.js.map +1 -0
  57. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776971364783-AddStatusPageLanguageSettings.js +14 -0
  58. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776971364783-AddStatusPageLanguageSettings.js.map +1 -0
  59. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1777018175127-AddTelemetryRetentionSettings.js +14 -0
  60. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1777018175127-AddTelemetryRetentionSettings.js.map +1 -0
  61. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  62. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  63. package/build/dist/Server/Services/AnalyticsDatabaseService.js +14 -4
  64. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  65. package/build/dist/Server/Services/OpenTelemetryIngestService.js +30 -4
  66. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  67. package/build/dist/Server/Services/ServiceService.js +22 -1
  68. package/build/dist/Server/Services/ServiceService.js.map +1 -1
  69. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +132 -30
  70. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js.map +1 -1
  71. package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js +58 -7
  72. package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js.map +1 -1
  73. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +66 -12
  74. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  75. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +112 -0
  76. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  77. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +91 -15
  78. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  79. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +373 -0
  80. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  81. package/build/dist/Server/Utils/Monitor/MonitorResource.js +2 -0
  82. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  83. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +65 -0
  84. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  85. package/build/dist/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.js +199 -0
  86. package/build/dist/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.js.map +1 -1
  87. package/build/dist/Types/AdminDashboard/AdminDashboardLanguage.js +22 -0
  88. package/build/dist/Types/AdminDashboard/AdminDashboardLanguage.js.map +1 -0
  89. package/build/dist/Types/Monitor/CriteriaFilter.js +10 -0
  90. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  91. package/build/dist/Types/Monitor/MetricMonitor/MetricSeriesResult.js +2 -0
  92. package/build/dist/Types/Monitor/MetricMonitor/MetricSeriesResult.js.map +1 -0
  93. package/build/dist/Types/Monitor/MonitorMetricType.js +28 -0
  94. package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
  95. package/build/dist/Types/StatusPage/StatusPageLanguage.js +22 -0
  96. package/build/dist/Types/StatusPage/StatusPageLanguage.js.map +1 -0
  97. package/build/dist/UI/Components/Charts/Area/AreaChart.js +13 -12
  98. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  99. package/build/dist/UI/Components/Charts/Bar/BarChart.js +12 -11
  100. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  101. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +11 -3
  102. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  103. package/build/dist/UI/Components/Charts/Line/LineChart.js +12 -11
  104. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  105. package/build/dist/UI/Components/Filters/FiltersForm.js +6 -2
  106. package/build/dist/UI/Components/Filters/FiltersForm.js.map +1 -1
  107. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +383 -0
  108. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -0
  109. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesModal.js +109 -0
  110. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesModal.js.map +1 -0
  111. package/build/dist/Utils/Metrics/MetricSeriesFingerprint.js +81 -0
  112. package/build/dist/Utils/Metrics/MetricSeriesFingerprint.js.map +1 -0
  113. package/build/dist/Utils/Monitor/MonitorMetricType.js +287 -19
  114. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  115. package/package.json +1 -1
@@ -0,0 +1,97 @@
1
+ import { createHash } from "crypto";
2
+ import AggregatedModel from "../../Types/BaseDatabase/AggregatedModel";
3
+ import { JSONObject, JSONValue } from "../../Types/JSON";
4
+
5
+ /**
6
+ * Canonicalize a label dictionary (key/value string pairs identifying a
7
+ * metric series) into a stable short hash. Used to key incidents/alerts
8
+ * by the series that breached so one incident is created per host (or
9
+ * per whatever attribute combination the user grouped by) rather than a
10
+ * single incident per monitor.
11
+ */
12
+ export default class MetricSeriesFingerprint {
13
+ /**
14
+ * Sentinel fingerprint used when a metric monitor has no group-by
15
+ * configured — i.e. traditional whole-monitor evaluation. Using an
16
+ * explicit sentinel (rather than undefined) lets callers store a
17
+ * single value and still use the same dedupe query shape.
18
+ */
19
+ public static readonly WholeMonitorFingerprint: string = "__all__";
20
+
21
+ /**
22
+ * Compute a deterministic 16-char hex fingerprint from a label map.
23
+ * Keys are sorted so `{a,b}` and `{b,a}` hash identically. Null and
24
+ * undefined values canonicalize to the empty string so a series that
25
+ * occasionally drops an attribute still maps to the same bucket.
26
+ */
27
+ public static computeFingerprint(labels: JSONObject): string {
28
+ const keys: Array<string> = Object.keys(labels || {}).sort();
29
+
30
+ if (keys.length === 0) {
31
+ return MetricSeriesFingerprint.WholeMonitorFingerprint;
32
+ }
33
+
34
+ const parts: Array<string> = [];
35
+
36
+ for (const key of keys) {
37
+ const raw: JSONValue | undefined = labels[key];
38
+ const value: string =
39
+ raw === undefined || raw === null ? "" : String(raw);
40
+ parts.push(`${key}=${value}`);
41
+ }
42
+
43
+ return createHash("sha256")
44
+ .update(parts.join("|"))
45
+ .digest("hex")
46
+ .slice(0, 16);
47
+ }
48
+
49
+ /**
50
+ * Extract the series labels from an aggregated sample. When
51
+ * `attributeKeys` is provided, pulls those specific keys out of the
52
+ * sample's `attributes` map (OpenTelemetry attributes live nested in
53
+ * a MapStringString column, so users group by "host.name" as an
54
+ * attribute KEY rather than a top-level column). When no keys are
55
+ * provided, falls back to every non-reserved key on the sample so
56
+ * callers that pass top-level group-by columns still work.
57
+ */
58
+ public static extractSeriesLabels(input: {
59
+ sample: AggregatedModel;
60
+ attributeKeys?: Array<string> | undefined;
61
+ }): JSONObject {
62
+ const result: JSONObject = {};
63
+
64
+ const sampleAttributes: JSONObject =
65
+ ((input.sample as unknown as JSONObject)["attributes"] as
66
+ | JSONObject
67
+ | undefined) || {};
68
+
69
+ if (input.attributeKeys && input.attributeKeys.length > 0) {
70
+ for (const key of input.attributeKeys) {
71
+ const value: JSONValue | undefined = sampleAttributes[key];
72
+ if (value !== undefined && value !== null) {
73
+ result[key] = value;
74
+ } else {
75
+ /*
76
+ * Preserve the key even when missing so the fingerprint stays
77
+ * stable across evaluations that happen to drop the attribute.
78
+ */
79
+ result[key] = "";
80
+ }
81
+ }
82
+ return result;
83
+ }
84
+
85
+ for (const key of Object.keys(input.sample)) {
86
+ if (key === "timestamp" || key === "value") {
87
+ continue;
88
+ }
89
+ const value: unknown = (input.sample as unknown as JSONObject)[key];
90
+ if (value === undefined || value === null) {
91
+ continue;
92
+ }
93
+ result[key] = value as JSONValue;
94
+ }
95
+ return result;
96
+ }
97
+ }
@@ -3,6 +3,17 @@ import { CheckOn } from "../../Types/Monitor/CriteriaFilter";
3
3
  import MonitorMetricType from "../../Types/Monitor/MonitorMetricType";
4
4
  import MonitorType from "../../Types/Monitor/MonitorType";
5
5
 
6
+ /*
7
+ * Groups of metrics rendered as separate cards on the monitor metrics page.
8
+ * Keeps the Server/VM page navigable — CPU / Memory / Disk / Network each
9
+ * get their own card rather than one 28-chart scroll.
10
+ */
11
+ export interface MonitorMetricCategory {
12
+ title: string;
13
+ description: string;
14
+ metrics: Array<MonitorMetricType>;
15
+ }
16
+
6
17
  class MonitorMetricTypeUtil {
7
18
  public static getAggregationTypeByMonitorMetricType(
8
19
  monitorMetricType: MonitorMetricType,
@@ -22,6 +33,41 @@ class MonitorMetricTypeUtil {
22
33
  return AggregationType.Avg;
23
34
  case MonitorMetricType.ExecutionTime:
24
35
  return AggregationType.Avg;
36
+
37
+ /*
38
+ * Extended server/VM metrics. Cumulative counters (bytes/packets/ops since
39
+ * boot) use Max so the latest value in a time bucket is returned, which the
40
+ * chart/UI can turn into a rate by differencing adjacent buckets. Gauges
41
+ * (percentages, counts, load averages) use Avg.
42
+ */
43
+ case MonitorMetricType.LoadAverage1Min:
44
+ case MonitorMetricType.LoadAverage5Min:
45
+ case MonitorMetricType.LoadAverage15Min:
46
+ case MonitorMetricType.SwapUsagePercent:
47
+ case MonitorMetricType.MemoryAvailableBytes:
48
+ case MonitorMetricType.CPUTimeUserPercent:
49
+ case MonitorMetricType.CPUTimeSystemPercent:
50
+ case MonitorMetricType.CPUTimeIoWaitPercent:
51
+ case MonitorMetricType.CPUTimeIdlePercent:
52
+ case MonitorMetricType.CPUTimeStealPercent:
53
+ case MonitorMetricType.NetworkConnectionsEstablished:
54
+ case MonitorMetricType.NetworkConnectionsListen:
55
+ case MonitorMetricType.ProcessCountTotal:
56
+ return AggregationType.Avg;
57
+
58
+ case MonitorMetricType.DiskReadBytesTotal:
59
+ case MonitorMetricType.DiskWriteBytesTotal:
60
+ case MonitorMetricType.DiskReadOpsTotal:
61
+ case MonitorMetricType.DiskWriteOpsTotal:
62
+ case MonitorMetricType.NetworkBytesReceivedTotal:
63
+ case MonitorMetricType.NetworkBytesSentTotal:
64
+ case MonitorMetricType.NetworkPacketsReceivedTotal:
65
+ case MonitorMetricType.NetworkPacketsSentTotal:
66
+ case MonitorMetricType.NetworkErrorsIn:
67
+ case MonitorMetricType.NetworkErrorsOut:
68
+ case MonitorMetricType.HostUptimeSeconds:
69
+ return AggregationType.Max;
70
+
25
71
  default:
26
72
  throw new Error("Invalid MonitorMetricType value");
27
73
  }
@@ -45,6 +91,16 @@ class MonitorMetricTypeUtil {
45
91
  return MonitorMetricType.MemoryUsagePercent;
46
92
  case CheckOn.ExecutionTime:
47
93
  return MonitorMetricType.ExecutionTime;
94
+ case CheckOn.LoadAverage1Min:
95
+ return MonitorMetricType.LoadAverage1Min;
96
+ case CheckOn.LoadAverage5Min:
97
+ return MonitorMetricType.LoadAverage5Min;
98
+ case CheckOn.LoadAverage15Min:
99
+ return MonitorMetricType.LoadAverage15Min;
100
+ case CheckOn.SwapUsagePercent:
101
+ return MonitorMetricType.SwapUsagePercent;
102
+ case CheckOn.CPUIoWaitPercent:
103
+ return MonitorMetricType.CPUTimeIoWaitPercent;
48
104
  default:
49
105
  throw new Error("Invalid CheckOn value");
50
106
  }
@@ -65,11 +121,39 @@ class MonitorMetricTypeUtil {
65
121
  }
66
122
 
67
123
  if (monitorType === MonitorType.Server) {
124
+ /*
125
+ * Order below reflects the chart display order on the monitor view.
126
+ * Core resource gauges first, then I/O counters, then diagnostics.
127
+ */
68
128
  return [
69
129
  MonitorMetricType.IsOnline,
70
- MonitorMetricType.DiskUsagePercent,
71
130
  MonitorMetricType.CPUUsagePercent,
72
131
  MonitorMetricType.MemoryUsagePercent,
132
+ MonitorMetricType.DiskUsagePercent,
133
+ MonitorMetricType.LoadAverage1Min,
134
+ MonitorMetricType.LoadAverage5Min,
135
+ MonitorMetricType.LoadAverage15Min,
136
+ MonitorMetricType.SwapUsagePercent,
137
+ MonitorMetricType.MemoryAvailableBytes,
138
+ MonitorMetricType.CPUTimeUserPercent,
139
+ MonitorMetricType.CPUTimeSystemPercent,
140
+ MonitorMetricType.CPUTimeIoWaitPercent,
141
+ MonitorMetricType.CPUTimeIdlePercent,
142
+ MonitorMetricType.CPUTimeStealPercent,
143
+ MonitorMetricType.DiskReadBytesTotal,
144
+ MonitorMetricType.DiskWriteBytesTotal,
145
+ MonitorMetricType.DiskReadOpsTotal,
146
+ MonitorMetricType.DiskWriteOpsTotal,
147
+ MonitorMetricType.NetworkBytesReceivedTotal,
148
+ MonitorMetricType.NetworkBytesSentTotal,
149
+ MonitorMetricType.NetworkPacketsReceivedTotal,
150
+ MonitorMetricType.NetworkPacketsSentTotal,
151
+ MonitorMetricType.NetworkErrorsIn,
152
+ MonitorMetricType.NetworkErrorsOut,
153
+ MonitorMetricType.NetworkConnectionsEstablished,
154
+ MonitorMetricType.NetworkConnectionsListen,
155
+ MonitorMetricType.ProcessCountTotal,
156
+ MonitorMetricType.HostUptimeSeconds,
73
157
  ];
74
158
  }
75
159
 
@@ -96,6 +180,95 @@ class MonitorMetricTypeUtil {
96
180
  return [];
97
181
  }
98
182
 
183
+ /*
184
+ * Returns the metrics grouped into display categories. Server monitors get
185
+ * a rich 5-card layout; every other monitor type falls through to a single
186
+ * "Monitor Metrics" category so existing pages look unchanged.
187
+ */
188
+ public static getMonitorMetricCategoriesByMonitorType(
189
+ monitorType: MonitorType,
190
+ ): Array<MonitorMetricCategory> {
191
+ if (monitorType === MonitorType.Server) {
192
+ return [
193
+ {
194
+ title: "Availability",
195
+ description:
196
+ "Heartbeat, uptime, and process count reported by the agent.",
197
+ metrics: [
198
+ MonitorMetricType.IsOnline,
199
+ MonitorMetricType.HostUptimeSeconds,
200
+ MonitorMetricType.ProcessCountTotal,
201
+ ],
202
+ },
203
+ {
204
+ title: "CPU",
205
+ description:
206
+ "CPU utilisation, load averages, and time-spent breakdown.",
207
+ metrics: [
208
+ MonitorMetricType.CPUUsagePercent,
209
+ MonitorMetricType.LoadAverage1Min,
210
+ MonitorMetricType.LoadAverage5Min,
211
+ MonitorMetricType.LoadAverage15Min,
212
+ MonitorMetricType.CPUTimeUserPercent,
213
+ MonitorMetricType.CPUTimeSystemPercent,
214
+ MonitorMetricType.CPUTimeIoWaitPercent,
215
+ MonitorMetricType.CPUTimeIdlePercent,
216
+ MonitorMetricType.CPUTimeStealPercent,
217
+ ],
218
+ },
219
+ {
220
+ title: "Memory",
221
+ description: "RAM usage, swap pressure, and bytes still available.",
222
+ metrics: [
223
+ MonitorMetricType.MemoryUsagePercent,
224
+ MonitorMetricType.SwapUsagePercent,
225
+ MonitorMetricType.MemoryAvailableBytes,
226
+ ],
227
+ },
228
+ {
229
+ title: "Disk",
230
+ description: "Space usage and I/O throughput per partition.",
231
+ metrics: [
232
+ MonitorMetricType.DiskUsagePercent,
233
+ MonitorMetricType.DiskReadBytesTotal,
234
+ MonitorMetricType.DiskWriteBytesTotal,
235
+ MonitorMetricType.DiskReadOpsTotal,
236
+ MonitorMetricType.DiskWriteOpsTotal,
237
+ ],
238
+ },
239
+ {
240
+ title: "Network",
241
+ description:
242
+ "Per-interface throughput, packet errors, and connection counts.",
243
+ metrics: [
244
+ MonitorMetricType.NetworkBytesReceivedTotal,
245
+ MonitorMetricType.NetworkBytesSentTotal,
246
+ MonitorMetricType.NetworkPacketsReceivedTotal,
247
+ MonitorMetricType.NetworkPacketsSentTotal,
248
+ MonitorMetricType.NetworkErrorsIn,
249
+ MonitorMetricType.NetworkErrorsOut,
250
+ MonitorMetricType.NetworkConnectionsEstablished,
251
+ MonitorMetricType.NetworkConnectionsListen,
252
+ ],
253
+ },
254
+ ];
255
+ }
256
+
257
+ // Other monitor types keep the single-card layout.
258
+ const metrics: Array<MonitorMetricType> =
259
+ this.getMonitorMetricTypesByMonitorType(monitorType);
260
+ if (metrics.length === 0) {
261
+ return [];
262
+ }
263
+ return [
264
+ {
265
+ title: "Monitor Metrics",
266
+ description: "Performance metrics collected from this monitor.",
267
+ metrics: metrics,
268
+ },
269
+ ];
270
+ }
271
+
99
272
  public static getTitleByMonitorMetricType(
100
273
  monitorMetricType: MonitorMetricType,
101
274
  ): string {
@@ -114,6 +287,54 @@ class MonitorMetricTypeUtil {
114
287
  return "Memory Usage Percent";
115
288
  case MonitorMetricType.ExecutionTime:
116
289
  return "Execution Time";
290
+ case MonitorMetricType.LoadAverage1Min:
291
+ return "Load Average (1 minute)";
292
+ case MonitorMetricType.LoadAverage5Min:
293
+ return "Load Average (5 minute)";
294
+ case MonitorMetricType.LoadAverage15Min:
295
+ return "Load Average (15 minute)";
296
+ case MonitorMetricType.SwapUsagePercent:
297
+ return "Swap Usage Percent";
298
+ case MonitorMetricType.MemoryAvailableBytes:
299
+ return "Memory Available";
300
+ case MonitorMetricType.CPUTimeUserPercent:
301
+ return "CPU Time - User";
302
+ case MonitorMetricType.CPUTimeSystemPercent:
303
+ return "CPU Time - System";
304
+ case MonitorMetricType.CPUTimeIoWaitPercent:
305
+ return "CPU Time - IO Wait";
306
+ case MonitorMetricType.CPUTimeIdlePercent:
307
+ return "CPU Time - Idle";
308
+ case MonitorMetricType.CPUTimeStealPercent:
309
+ return "CPU Time - Steal";
310
+ case MonitorMetricType.DiskReadBytesTotal:
311
+ return "Disk Read Bytes (cumulative)";
312
+ case MonitorMetricType.DiskWriteBytesTotal:
313
+ return "Disk Write Bytes (cumulative)";
314
+ case MonitorMetricType.DiskReadOpsTotal:
315
+ return "Disk Read Ops (cumulative)";
316
+ case MonitorMetricType.DiskWriteOpsTotal:
317
+ return "Disk Write Ops (cumulative)";
318
+ case MonitorMetricType.NetworkBytesReceivedTotal:
319
+ return "Network Bytes Received (cumulative)";
320
+ case MonitorMetricType.NetworkBytesSentTotal:
321
+ return "Network Bytes Sent (cumulative)";
322
+ case MonitorMetricType.NetworkPacketsReceivedTotal:
323
+ return "Network Packets Received (cumulative)";
324
+ case MonitorMetricType.NetworkPacketsSentTotal:
325
+ return "Network Packets Sent (cumulative)";
326
+ case MonitorMetricType.NetworkErrorsIn:
327
+ return "Network Receive Errors";
328
+ case MonitorMetricType.NetworkErrorsOut:
329
+ return "Network Transmit Errors";
330
+ case MonitorMetricType.NetworkConnectionsEstablished:
331
+ return "Network Connections - Established";
332
+ case MonitorMetricType.NetworkConnectionsListen:
333
+ return "Network Connections - Listening";
334
+ case MonitorMetricType.HostUptimeSeconds:
335
+ return "Host Uptime";
336
+ case MonitorMetricType.ProcessCountTotal:
337
+ return "Running Processes";
117
338
  default:
118
339
  return "";
119
340
  }
@@ -122,24 +343,12 @@ class MonitorMetricTypeUtil {
122
343
  public static getLegendByMonitorMetricType(
123
344
  monitorMetricType: MonitorMetricType,
124
345
  ): string {
125
- switch (monitorMetricType) {
126
- case MonitorMetricType.ResponseTime:
127
- return "Response Time";
128
- case MonitorMetricType.ResponseStatusCode:
129
- return "Response Status Code";
130
- case MonitorMetricType.IsOnline:
131
- return "Is Online";
132
- case MonitorMetricType.DiskUsagePercent:
133
- return "Disk Usage Percent";
134
- case MonitorMetricType.CPUUsagePercent:
135
- return "CPU Usage Percent";
136
- case MonitorMetricType.MemoryUsagePercent:
137
- return "Memory Usage Percent";
138
- case MonitorMetricType.ExecutionTime:
139
- return "Execution Time";
140
- default:
141
- return "";
142
- }
346
+ /*
347
+ * Legend labels default to the title, which also matches the existing behavior
348
+ * for every metric type. Keeping this as a separate function preserves the
349
+ * option to diverge later (e.g. shorter legend labels for dense charts).
350
+ */
351
+ return this.getTitleByMonitorMetricType(monitorMetricType);
143
352
  }
144
353
 
145
354
  public static getLegendUnitByMonitorMetricType(
@@ -160,6 +369,39 @@ class MonitorMetricTypeUtil {
160
369
  return "%";
161
370
  case MonitorMetricType.ExecutionTime:
162
371
  return "ms";
372
+ case MonitorMetricType.LoadAverage1Min:
373
+ case MonitorMetricType.LoadAverage5Min:
374
+ case MonitorMetricType.LoadAverage15Min:
375
+ return "";
376
+ case MonitorMetricType.SwapUsagePercent:
377
+ case MonitorMetricType.CPUTimeUserPercent:
378
+ case MonitorMetricType.CPUTimeSystemPercent:
379
+ case MonitorMetricType.CPUTimeIoWaitPercent:
380
+ case MonitorMetricType.CPUTimeIdlePercent:
381
+ case MonitorMetricType.CPUTimeStealPercent:
382
+ return "%";
383
+ case MonitorMetricType.MemoryAvailableBytes:
384
+ case MonitorMetricType.DiskReadBytesTotal:
385
+ case MonitorMetricType.DiskWriteBytesTotal:
386
+ case MonitorMetricType.NetworkBytesReceivedTotal:
387
+ case MonitorMetricType.NetworkBytesSentTotal:
388
+ return "bytes";
389
+ case MonitorMetricType.DiskReadOpsTotal:
390
+ case MonitorMetricType.DiskWriteOpsTotal:
391
+ return "ops";
392
+ case MonitorMetricType.NetworkPacketsReceivedTotal:
393
+ case MonitorMetricType.NetworkPacketsSentTotal:
394
+ return "packets";
395
+ case MonitorMetricType.NetworkErrorsIn:
396
+ case MonitorMetricType.NetworkErrorsOut:
397
+ return "errors";
398
+ case MonitorMetricType.NetworkConnectionsEstablished:
399
+ case MonitorMetricType.NetworkConnectionsListen:
400
+ return "connections";
401
+ case MonitorMetricType.HostUptimeSeconds:
402
+ return "seconds";
403
+ case MonitorMetricType.ProcessCountTotal:
404
+ return "processes";
163
405
  default:
164
406
  return "";
165
407
  }
@@ -183,6 +425,54 @@ class MonitorMetricTypeUtil {
183
425
  return "Memory usage percent is the percentage of memory that is currently being used on a server. It is a measure of how much of the server's memory is being used.";
184
426
  case MonitorMetricType.ExecutionTime:
185
427
  return "Execution time is the time taken for a custom JavaScript code or a synthetic monitor to execute.";
428
+ case MonitorMetricType.LoadAverage1Min:
429
+ return "Average number of runnable or uninterruptible processes over the last 1 minute. Values persistently above the number of CPU cores indicate CPU saturation.";
430
+ case MonitorMetricType.LoadAverage5Min:
431
+ return "Average number of runnable or uninterruptible processes over the last 5 minutes.";
432
+ case MonitorMetricType.LoadAverage15Min:
433
+ return "Average number of runnable or uninterruptible processes over the last 15 minutes — the most stable load indicator.";
434
+ case MonitorMetricType.SwapUsagePercent:
435
+ return "Percentage of swap space in use. Sustained non-zero values typically indicate memory pressure.";
436
+ case MonitorMetricType.MemoryAvailableBytes:
437
+ return "Estimated bytes of memory available for allocating to new processes without swapping.";
438
+ case MonitorMetricType.CPUTimeUserPercent:
439
+ return "Percentage of CPU time spent executing user-space processes.";
440
+ case MonitorMetricType.CPUTimeSystemPercent:
441
+ return "Percentage of CPU time spent executing kernel-space code (system calls, interrupts).";
442
+ case MonitorMetricType.CPUTimeIoWaitPercent:
443
+ return "Percentage of CPU time spent waiting on disk I/O. High iowait often indicates a storage bottleneck.";
444
+ case MonitorMetricType.CPUTimeIdlePercent:
445
+ return "Percentage of CPU time spent idle (not executing any work).";
446
+ case MonitorMetricType.CPUTimeStealPercent:
447
+ return "Percentage of CPU time the hypervisor stole from this VM to service other guests. Only relevant on virtualized hosts.";
448
+ case MonitorMetricType.DiskReadBytesTotal:
449
+ return "Cumulative bytes read from each disk since boot. Take a derivative over time to get read throughput.";
450
+ case MonitorMetricType.DiskWriteBytesTotal:
451
+ return "Cumulative bytes written to each disk since boot. Take a derivative over time to get write throughput.";
452
+ case MonitorMetricType.DiskReadOpsTotal:
453
+ return "Cumulative disk read operations since boot, per disk.";
454
+ case MonitorMetricType.DiskWriteOpsTotal:
455
+ return "Cumulative disk write operations since boot, per disk.";
456
+ case MonitorMetricType.NetworkBytesReceivedTotal:
457
+ return "Cumulative bytes received on each network interface since boot. Derivative over time yields receive throughput.";
458
+ case MonitorMetricType.NetworkBytesSentTotal:
459
+ return "Cumulative bytes transmitted on each network interface since boot. Derivative over time yields send throughput.";
460
+ case MonitorMetricType.NetworkPacketsReceivedTotal:
461
+ return "Cumulative packets received per interface since boot.";
462
+ case MonitorMetricType.NetworkPacketsSentTotal:
463
+ return "Cumulative packets transmitted per interface since boot.";
464
+ case MonitorMetricType.NetworkErrorsIn:
465
+ return "Cumulative receive errors per interface. Increases typically point to cabling, NIC, or driver issues.";
466
+ case MonitorMetricType.NetworkErrorsOut:
467
+ return "Cumulative transmit errors per interface.";
468
+ case MonitorMetricType.NetworkConnectionsEstablished:
469
+ return "Count of network connections currently in ESTABLISHED state.";
470
+ case MonitorMetricType.NetworkConnectionsListen:
471
+ return "Count of sockets currently in LISTEN state — one per service accepting connections.";
472
+ case MonitorMetricType.HostUptimeSeconds:
473
+ return "Seconds since the host was last booted.";
474
+ case MonitorMetricType.ProcessCountTotal:
475
+ return "Number of running processes reported by the agent.";
186
476
  default:
187
477
  return "";
188
478
  }
@@ -65,6 +65,8 @@ let Alert = class Alert extends BaseModel {
65
65
  this.rootCause = undefined;
66
66
  this.createdStateLog = undefined;
67
67
  this.createdCriteriaId = undefined;
68
+ this.seriesFingerprint = undefined;
69
+ this.seriesLabels = undefined;
68
70
  this.createdByProbe = undefined;
69
71
  this.createdByProbeId = undefined;
70
72
  this.isCreatedAutomatically = undefined;
@@ -933,6 +935,61 @@ __decorate([
933
935
  }),
934
936
  __metadata("design:type", String)
935
937
  ], Alert.prototype, "createdCriteriaId", void 0);
938
+ __decorate([
939
+ ColumnAccessControl({
940
+ create: [],
941
+ read: [
942
+ Permission.ProjectOwner,
943
+ Permission.ProjectAdmin,
944
+ Permission.ProjectMember,
945
+ Permission.Viewer,
946
+ Permission.AlertManager,
947
+ Permission.ReadAlert,
948
+ Permission.ReadAllProjectResources,
949
+ ],
950
+ update: [],
951
+ }),
952
+ Index(),
953
+ TableColumn({
954
+ type: TableColumnType.LongText,
955
+ required: false,
956
+ isDefaultValueColumn: false,
957
+ title: "Series Fingerprint",
958
+ description: "For metric monitors with per-series alerting (e.g. grouped by host.name), this is a stable hash of the series label values so one alert is created per affected series.",
959
+ }),
960
+ Column({
961
+ type: ColumnType.LongText,
962
+ nullable: true,
963
+ }),
964
+ __metadata("design:type", String)
965
+ ], Alert.prototype, "seriesFingerprint", void 0);
966
+ __decorate([
967
+ ColumnAccessControl({
968
+ create: [],
969
+ read: [
970
+ Permission.ProjectOwner,
971
+ Permission.ProjectAdmin,
972
+ Permission.ProjectMember,
973
+ Permission.Viewer,
974
+ Permission.AlertManager,
975
+ Permission.ReadAlert,
976
+ Permission.ReadAllProjectResources,
977
+ ],
978
+ update: [],
979
+ }),
980
+ TableColumn({
981
+ type: TableColumnType.JSON,
982
+ required: false,
983
+ isDefaultValueColumn: false,
984
+ title: "Series Labels",
985
+ description: "Attribute key/value pairs that identify the affected series (e.g. {host.name: prod-db-01}) when this alert was created from a per-series metric breach.",
986
+ }),
987
+ Column({
988
+ type: ColumnType.JSON,
989
+ nullable: true,
990
+ }),
991
+ __metadata("design:type", Object)
992
+ ], Alert.prototype, "seriesLabels", void 0);
936
993
  __decorate([
937
994
  ColumnAccessControl({
938
995
  create: [],