@oneuptime/common 8.0.5516 → 8.0.5544

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 (80) hide show
  1. package/Models/DatabaseModels/AcmeChallenge.ts +3 -0
  2. package/Models/DatabaseModels/Domain.ts +6 -1
  3. package/Server/API/AcmeChallengeAPI.ts +64 -0
  4. package/Server/EnvironmentConfig.ts +54 -0
  5. package/Server/Infrastructure/Queue.ts +12 -16
  6. package/Server/Infrastructure/QueueWorker.ts +2 -6
  7. package/Server/Services/DomainService.ts +48 -40
  8. package/Server/Utils/AnalyticsDatabase/Statement.ts +8 -4
  9. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +47 -15
  10. package/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.ts +13 -12
  11. package/Server/Utils/Monitor/MonitorAlert.ts +46 -1
  12. package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +208 -0
  13. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +439 -0
  14. package/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.ts +141 -0
  15. package/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.ts +88 -0
  16. package/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.ts +196 -0
  17. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +1123 -0
  18. package/Server/Utils/Monitor/MonitorIncident.ts +46 -1
  19. package/Server/Utils/Monitor/MonitorLogUtil.ts +44 -0
  20. package/Server/Utils/Monitor/MonitorMetricUtil.ts +482 -0
  21. package/Server/Utils/Monitor/MonitorResource.ts +185 -914
  22. package/Server/Utils/StartServer.ts +14 -6
  23. package/Types/Email.ts +3 -7
  24. package/Types/Monitor/IncomingMonitor/IncomingMonitorRequest.ts +2 -0
  25. package/Types/Monitor/LogMonitor/LogMonitorResponse.ts +2 -0
  26. package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +2 -0
  27. package/Types/Monitor/MonitorEvaluationSummary.ts +48 -0
  28. package/Types/Monitor/ServerMonitor/ServerMonitorResponse.ts +2 -0
  29. package/Types/Monitor/TraceMonitor/TraceMonitorResponse.ts +2 -0
  30. package/Types/Probe/ProbeApiIngestResponse.ts +2 -0
  31. package/Types/Probe/ProbeMonitorResponse.ts +2 -0
  32. package/build/dist/Models/DatabaseModels/AcmeChallenge.js +3 -0
  33. package/build/dist/Models/DatabaseModels/AcmeChallenge.js.map +1 -1
  34. package/build/dist/Models/DatabaseModels/Domain.js +6 -1
  35. package/build/dist/Models/DatabaseModels/Domain.js.map +1 -1
  36. package/build/dist/Server/API/AcmeChallengeAPI.js +39 -0
  37. package/build/dist/Server/API/AcmeChallengeAPI.js.map +1 -0
  38. package/build/dist/Server/EnvironmentConfig.js +44 -0
  39. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  40. package/build/dist/Server/Infrastructure/Queue.js +8 -11
  41. package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
  42. package/build/dist/Server/Infrastructure/QueueWorker.js +2 -6
  43. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  44. package/build/dist/Server/Services/DomainService.js +31 -29
  45. package/build/dist/Server/Services/DomainService.js.map +1 -1
  46. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +2 -1
  47. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
  48. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +34 -16
  49. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  50. package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js +12 -12
  51. package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js.map +1 -1
  52. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +42 -4
  53. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  54. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js +119 -0
  55. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js.map +1 -0
  56. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +312 -0
  57. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -0
  58. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js +109 -0
  59. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js.map +1 -0
  60. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.js +45 -0
  61. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.js.map +1 -0
  62. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.js +132 -0
  63. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.js.map +1 -0
  64. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +583 -0
  65. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -0
  66. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +42 -4
  67. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  68. package/build/dist/Server/Utils/Monitor/MonitorLogUtil.js +32 -0
  69. package/build/dist/Server/Utils/Monitor/MonitorLogUtil.js.map +1 -0
  70. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +361 -0
  71. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -0
  72. package/build/dist/Server/Utils/Monitor/MonitorResource.js +133 -666
  73. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  74. package/build/dist/Server/Utils/StartServer.js +7 -4
  75. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  76. package/build/dist/Types/Email.js +2 -5
  77. package/build/dist/Types/Email.js.map +1 -1
  78. package/build/dist/Types/Monitor/MonitorEvaluationSummary.js +2 -0
  79. package/build/dist/Types/Monitor/MonitorEvaluationSummary.js.map +1 -0
  80. package/package.json +5 -5
@@ -2,22 +2,14 @@ import MonitorProbeService from "../../Services/MonitorProbeService";
2
2
  import MonitorService from "../../Services/MonitorService";
3
3
  import MonitorStatusTimelineService from "../../Services/MonitorStatusTimelineService";
4
4
  import logger from "../Logger";
5
- import VMUtil from "../VM/VMAPI";
6
- import APIRequestCriteria from "./Criteria/APIRequestCriteria";
7
- import CustomCodeMonitoringCriteria from "./Criteria/CustomCodeMonitorCriteria";
8
- import IncomingRequestCriteria from "./Criteria/IncomingRequestCriteria";
9
- import SSLMonitorCriteria from "./Criteria/SSLMonitorCriteria";
10
- import ServerMonitorCriteria from "./Criteria/ServerMonitorCriteria";
11
- import SyntheticMonitoringCriteria from "./Criteria/SyntheticMonitor";
5
+ import MonitorCriteriaEvaluator from "./MonitorCriteriaEvaluator";
6
+ import MonitorLogUtil from "./MonitorLogUtil";
7
+ import MonitorMetricUtil from "./MonitorMetricUtil";
12
8
  import DataToProcess from "./DataToProcess";
13
9
  import SortOrder from "../../../Types/BaseDatabase/SortOrder";
14
10
  import Dictionary from "../../../Types/Dictionary";
15
11
  import BadDataException from "../../../Types/Exception/BadDataException";
16
- import BasicInfrastructureMetrics from "../../../Types/Infrastructure/BasicMetrics";
17
- import ReturnResult from "../../../Types/IsolatedVM/ReturnResult";
18
12
  import Semaphore, { SemaphoreMutex } from "../../Infrastructure/Semaphore";
19
- import { JSONObject } from "../../../Types/JSON";
20
- import { CheckOn, CriteriaFilter } from "../../../Types/Monitor/CriteriaFilter";
21
13
  import IncomingMonitorRequest from "../../../Types/Monitor/IncomingMonitor/IncomingMonitorRequest";
22
14
  import MonitorCriteria from "../../../Types/Monitor/MonitorCriteria";
23
15
  import MonitorCriteriaInstance from "../../../Types/Monitor/MonitorCriteriaInstance";
@@ -30,108 +22,25 @@ import ServerMonitorResponse from "../../../Types/Monitor/ServerMonitor/ServerMo
30
22
  import ObjectID from "../../../Types/ObjectID";
31
23
  import ProbeApiIngestResponse from "../../../Types/Probe/ProbeApiIngestResponse";
32
24
  import ProbeMonitorResponse from "../../../Types/Probe/ProbeMonitorResponse";
33
- import Typeof from "../../../Types/Typeof";
34
25
  import Monitor from "../../../Models/DatabaseModels/Monitor";
35
26
  import MonitorProbe from "../../../Models/DatabaseModels/MonitorProbe";
27
+ import MonitorStatus from "../../../Models/DatabaseModels/MonitorStatus";
36
28
  import MonitorStatusTimeline from "../../../Models/DatabaseModels/MonitorStatusTimeline";
37
29
  import OneUptimeDate from "../../../Types/Date";
38
- import LogMonitorCriteria from "./Criteria/LogMonitorCriteria";
39
30
  import LogMonitorResponse from "../../../Types/Monitor/LogMonitor/LogMonitorResponse";
31
+ import MetricMonitorResponse from "../../../Types/Monitor/MetricMonitor/MetricMonitorResponse";
40
32
  import TelemetryType from "../../../Types/Telemetry/TelemetryType";
41
33
  import TraceMonitorResponse from "../../../Types/Monitor/TraceMonitor/TraceMonitorResponse";
42
- import TraceMonitorCriteria from "./Criteria/TraceMonitorCriteria";
43
34
  import { TelemetryQuery } from "../../../Types/Telemetry/TelemetryQuery";
44
35
  import MonitorIncident from "./MonitorIncident";
45
36
  import MonitorAlert from "./MonitorAlert";
46
37
  import MonitorStatusTimelineUtil from "./MonitorStatusTimeline";
47
- import {
48
- MetricPointType,
49
- ServiceType,
50
- } from "../../../Models/AnalyticsModels/Metric";
51
- import MetricService from "../../Services/MetricService";
52
- import MonitorMetricType from "../../../Types/Monitor/MonitorMetricType";
53
- import TelemetryUtil from "../Telemetry/Telemetry";
54
- import MetricMonitorCriteria from "./Criteria/MetricMonitorCriteria";
55
- import MetricMonitorResponse from "../../../Types/Monitor/MetricMonitor/MetricMonitorResponse";
56
- import FilterCondition from "../../../Types/Filter/FilterCondition";
57
38
  import CaptureSpan from "../Telemetry/CaptureSpan";
58
- import MetricType from "../../../Models/DatabaseModels/MetricType";
59
- import MonitorLogService from "../../Services/MonitorLogService";
60
39
  import ExceptionMessages from "../../../Types/Exception/ExceptionMessages";
40
+ import MonitorEvaluationSummary from "../../../Types/Monitor/MonitorEvaluationSummary";
41
+ import MonitorStatusService from "../../Services/MonitorStatusService";
61
42
 
62
43
  export default class MonitorResourceUtil {
63
- private static buildMonitorMetricAttributes(data: {
64
- monitorId: ObjectID;
65
- projectId: ObjectID;
66
- monitorName?: string | undefined;
67
- probeName?: string | undefined;
68
- extraAttributes?: JSONObject;
69
- }): JSONObject {
70
- const attributes: JSONObject = {
71
- monitorId: data.monitorId.toString(),
72
- projectId: data.projectId.toString(),
73
- };
74
-
75
- if (data.extraAttributes) {
76
- Object.assign(attributes, data.extraAttributes);
77
- }
78
-
79
- if (data.monitorName) {
80
- attributes["monitorName"] = data.monitorName;
81
- }
82
-
83
- if (data.probeName) {
84
- attributes["probeName"] = data.probeName;
85
- }
86
-
87
- return attributes;
88
- }
89
-
90
- private static buildMonitorMetricRow(data: {
91
- projectId: ObjectID;
92
- monitorId: ObjectID;
93
- metricName: string;
94
- value: number | null | undefined;
95
- attributes: JSONObject;
96
- metricPointType?: MetricPointType;
97
- }): JSONObject {
98
- const ingestionDate: Date = OneUptimeDate.getCurrentDate();
99
- const ingestionTimestamp: string =
100
- OneUptimeDate.toClickhouseDateTime(ingestionDate);
101
- const timeUnixNano: string =
102
- OneUptimeDate.toUnixNano(ingestionDate).toString();
103
-
104
- const attributes: JSONObject = { ...data.attributes };
105
- const attributeKeys: Array<string> =
106
- TelemetryUtil.getAttributeKeys(attributes);
107
-
108
- return {
109
- _id: ObjectID.generate().toString(),
110
- createdAt: ingestionTimestamp,
111
- updatedAt: ingestionTimestamp,
112
- projectId: data.projectId.toString(),
113
- serviceId: data.monitorId.toString(),
114
- serviceType: ServiceType.Monitor,
115
- name: data.metricName,
116
- aggregationTemporality: null,
117
- metricPointType: data.metricPointType || MetricPointType.Sum,
118
- time: ingestionTimestamp,
119
- startTime: null,
120
- timeUnixNano: timeUnixNano,
121
- startTimeUnixNano: null,
122
- attributes: attributes,
123
- attributeKeys: attributeKeys,
124
- isMonotonic: null,
125
- count: null,
126
- sum: null,
127
- min: null,
128
- max: null,
129
- bucketCounts: [],
130
- explicitBounds: [],
131
- value: data.value ?? null,
132
- } as JSONObject;
133
- }
134
-
135
44
  @CaptureSpan()
136
45
  public static async monitorResource(
137
46
  dataToProcess: DataToProcess,
@@ -153,6 +62,51 @@ export default class MonitorResourceUtil {
153
62
  rootCause: null,
154
63
  };
155
64
 
65
+ const evaluationSummary: MonitorEvaluationSummary = {
66
+ evaluatedAt: OneUptimeDate.getCurrentDate(),
67
+ criteriaResults: [],
68
+ events: [],
69
+ };
70
+
71
+ response.evaluationSummary = evaluationSummary;
72
+ dataToProcess.evaluationSummary = evaluationSummary;
73
+
74
+ const monitorStatusNameCache: Dictionary<string | null> = {};
75
+
76
+ const getMonitorStatusName: (
77
+ statusId: ObjectID | undefined | null,
78
+ ) => Promise<string | null> = async (
79
+ statusId: ObjectID | undefined | null,
80
+ ): Promise<string | null> => {
81
+ if (!statusId) {
82
+ return null;
83
+ }
84
+
85
+ const cacheKey: string = statusId.toString();
86
+
87
+ if (monitorStatusNameCache[cacheKey] !== undefined) {
88
+ return monitorStatusNameCache[cacheKey];
89
+ }
90
+
91
+ const monitorStatus: MonitorStatus | null =
92
+ await MonitorStatusService.findOneBy({
93
+ query: {
94
+ _id: statusId,
95
+ },
96
+ select: {
97
+ name: true,
98
+ },
99
+ props: {
100
+ isRoot: true,
101
+ },
102
+ });
103
+
104
+ const statusName: string | null = monitorStatus?.name || null;
105
+ monitorStatusNameCache[cacheKey] = statusName;
106
+
107
+ return statusName;
108
+ };
109
+
156
110
  logger.debug("Processing probe response");
157
111
  logger.debug("Monitor ID: " + dataToProcess.monitorId);
158
112
  logger.debug("Fetching Monitor...");
@@ -200,7 +154,6 @@ export default class MonitorResourceUtil {
200
154
 
201
155
  throw new BadDataException(ExceptionMessages.MonitorDisabled);
202
156
  }
203
-
204
157
  if (monitor.disableActiveMonitoringBecauseOfManualIncident) {
205
158
  logger.debug(
206
159
  `${dataToProcess.monitorId.toString()} Monitor is disabled because an incident which is created manually is not resolved. Please resolve the incident to start monitoring again.`,
@@ -285,66 +238,86 @@ export default class MonitorResourceUtil {
285
238
  }
286
239
  }
287
240
 
288
- if (
241
+ const serverMonitorResponse: ServerMonitorResponse | undefined =
242
+ monitor.monitorType === MonitorType.Server &&
243
+ (dataToProcess as ServerMonitorResponse).requestReceivedAt
244
+ ? (dataToProcess as ServerMonitorResponse)
245
+ : undefined;
246
+
247
+ const incomingMonitorRequest: IncomingMonitorRequest | undefined =
289
248
  monitor.monitorType === MonitorType.IncomingRequest &&
290
249
  (dataToProcess as IncomingMonitorRequest).incomingRequestReceivedAt &&
291
250
  !(dataToProcess as IncomingMonitorRequest)
292
251
  .onlyCheckForIncomingRequestReceivedAt
293
- ) {
294
- logger.debug(
295
- `${dataToProcess.monitorId.toString()} - Incoming request received at ${(dataToProcess as IncomingMonitorRequest).incomingRequestReceivedAt}`,
296
- );
252
+ ? (dataToProcess as IncomingMonitorRequest)
253
+ : undefined;
297
254
 
298
- await MonitorService.updateOneById({
299
- id: monitor.id!,
300
- data: {
301
- incomingRequestMonitorHeartbeatCheckedAt:
302
- OneUptimeDate.getCurrentDate(),
303
- incomingMonitorRequest: {
304
- ...dataToProcess,
305
- } as any,
306
- },
307
- props: {
308
- isRoot: true,
309
- },
310
- });
255
+ let hasPersistedMonitorData: boolean = false;
311
256
 
312
- logger.debug(`${dataToProcess.monitorId.toString()} - Monitor Updated`);
313
- }
257
+ const persistLatestMonitorPayload: () => Promise<void> = async () => {
258
+ if (hasPersistedMonitorData) {
259
+ return;
260
+ }
314
261
 
315
- if (
316
- monitor.monitorType === MonitorType.Server &&
317
- (dataToProcess as ServerMonitorResponse).requestReceivedAt
318
- ) {
319
- logger.debug(
320
- `${dataToProcess.monitorId.toString()} - Server request received at ${(dataToProcess as ServerMonitorResponse).requestReceivedAt}`,
321
- );
262
+ if (serverMonitorResponse) {
263
+ logger.debug(
264
+ `${dataToProcess.monitorId.toString()} - Server request received at ${serverMonitorResponse.requestReceivedAt}`,
265
+ );
322
266
 
323
- logger.debug(dataToProcess);
267
+ logger.debug(dataToProcess);
324
268
 
325
- await MonitorService.updateOneById({
326
- id: monitor.id!,
327
- data: {
328
- serverMonitorRequestReceivedAt: (
329
- dataToProcess as ServerMonitorResponse
330
- ).requestReceivedAt!,
331
- serverMonitorResponse: dataToProcess as ServerMonitorResponse, // this could be redundant as we are already saving this in the incomingMonitorRequest. we should remove this in the future.
332
- },
333
- props: {
334
- isRoot: true,
335
- ignoreHooks: true,
336
- },
337
- });
269
+ await MonitorService.updateOneById({
270
+ id: monitor.id!,
271
+ data: {
272
+ serverMonitorRequestReceivedAt:
273
+ serverMonitorResponse.requestReceivedAt!,
274
+ serverMonitorResponse,
275
+ },
276
+ props: {
277
+ isRoot: true,
278
+ ignoreHooks: true,
279
+ },
280
+ });
338
281
 
339
- logger.debug(`${dataToProcess.monitorId.toString()} - Monitor Updated`);
340
- }
282
+ logger.debug(
283
+ `${dataToProcess.monitorId.toString()} - Monitor Server Response Updated`,
284
+ );
285
+ }
286
+
287
+ if (incomingMonitorRequest) {
288
+ logger.debug(
289
+ `${dataToProcess.monitorId.toString()} - Incoming request received at ${incomingMonitorRequest.incomingRequestReceivedAt}`,
290
+ );
291
+
292
+ await MonitorService.updateOneById({
293
+ id: monitor.id!,
294
+ data: {
295
+ incomingRequestMonitorHeartbeatCheckedAt:
296
+ OneUptimeDate.getCurrentDate(),
297
+ incomingMonitorRequest: JSON.parse(
298
+ JSON.stringify(incomingMonitorRequest),
299
+ ) as IncomingMonitorRequest,
300
+ } as any,
301
+ props: {
302
+ isRoot: true,
303
+ ignoreHooks: true,
304
+ },
305
+ });
306
+
307
+ logger.debug(
308
+ `${dataToProcess.monitorId.toString()} - Monitor Incoming Request Updated`,
309
+ );
310
+ }
311
+
312
+ hasPersistedMonitorData = true;
313
+ };
341
314
 
342
315
  logger.debug(
343
316
  `${dataToProcess.monitorId.toString()} - Saving monitor metrics`,
344
317
  );
345
318
 
346
319
  try {
347
- await this.saveMonitorMetrics({
320
+ await MonitorMetricUtil.saveMonitorMetrics({
348
321
  monitorId: monitor.id!,
349
322
  projectId: monitor.projectId!,
350
323
  dataToProcess: dataToProcess,
@@ -369,6 +342,13 @@ export default class MonitorResourceUtil {
369
342
  logger.debug(
370
343
  `${dataToProcess.monitorId.toString()} - No monitoring steps.`,
371
344
  );
345
+ await persistLatestMonitorPayload();
346
+
347
+ MonitorLogUtil.saveMonitorLog({
348
+ monitorId: monitor.id!,
349
+ projectId: monitor.projectId!,
350
+ dataToProcess: dataToProcess,
351
+ });
372
352
  return response;
373
353
  }
374
354
 
@@ -479,6 +459,13 @@ export default class MonitorResourceUtil {
479
459
 
480
460
  if (!monitorStep) {
481
461
  logger.debug("No steps found, ignoring everything.");
462
+ await persistLatestMonitorPayload();
463
+
464
+ MonitorLogUtil.saveMonitorLog({
465
+ monitorId: monitor.id!,
466
+ projectId: monitor.projectId!,
467
+ dataToProcess: dataToProcess,
468
+ });
482
469
  return response;
483
470
  }
484
471
 
@@ -504,11 +491,12 @@ export default class MonitorResourceUtil {
504
491
  `${dataToProcess.monitorId.toString()} - Processing monitor step...`,
505
492
  );
506
493
 
507
- response = await MonitorResourceUtil.processMonitorStep({
494
+ response = await MonitorCriteriaEvaluator.processMonitorStep({
508
495
  dataToProcess: dataToProcess,
509
496
  monitorStep: monitorStep,
510
497
  monitor: monitor,
511
498
  probeApiIngestResponse: response,
499
+ evaluationSummary: evaluationSummary,
512
500
  });
513
501
 
514
502
  if (response.criteriaMetId && response.rootCause) {
@@ -569,22 +557,44 @@ export default class MonitorResourceUtil {
569
557
  );
570
558
  }
571
559
 
572
- await MonitorStatusTimelineUtil.updateMonitorStatusTimeline({
573
- monitor: monitor,
574
- rootCause: response.rootCause,
575
- dataToProcess: dataToProcess,
576
- criteriaInstance: criteriaInstanceMap[response.criteriaMetId!]!,
577
- props: {
578
- telemetryQuery: telemetryQuery,
579
- },
580
- });
560
+ const matchedCriteriaInstance: MonitorCriteriaInstance =
561
+ criteriaInstanceMap[response.criteriaMetId!]!;
562
+
563
+ const monitorStatusTimelineChange: MonitorStatusTimeline | null =
564
+ await MonitorStatusTimelineUtil.updateMonitorStatusTimeline({
565
+ monitor: monitor,
566
+ rootCause: response.rootCause,
567
+ dataToProcess: dataToProcess,
568
+ criteriaInstance: matchedCriteriaInstance,
569
+ props: {
570
+ telemetryQuery: telemetryQuery,
571
+ },
572
+ });
573
+
574
+ if (monitorStatusTimelineChange) {
575
+ const changedStatusName: string | null = await getMonitorStatusName(
576
+ matchedCriteriaInstance.data?.monitorStatusId ||
577
+ monitorStatusTimelineChange.monitorStatusId,
578
+ );
579
+
580
+ evaluationSummary.events.push({
581
+ type: "monitor-status-changed",
582
+ title: "Monitor status updated",
583
+ message: changedStatusName
584
+ ? `Monitor status changed to "${changedStatusName}" because criteria "${matchedCriteriaInstance.data?.name || "Unnamed criteria"}" was met.`
585
+ : `Monitor status changed because criteria "${matchedCriteriaInstance.data?.name || "Unnamed criteria"}" was met.`,
586
+ relatedCriteriaId: matchedCriteriaInstance.data?.id,
587
+ at: OneUptimeDate.getCurrentDate(),
588
+ });
589
+ }
581
590
 
582
591
  await MonitorIncident.criteriaMetCreateIncidentsAndUpdateMonitorStatus({
583
592
  monitor: monitor,
584
593
  rootCause: response.rootCause,
585
594
  dataToProcess: dataToProcess,
586
595
  autoResolveCriteriaInstanceIdIncidentIdsDictionary,
587
- criteriaInstance: criteriaInstanceMap[response.criteriaMetId!]!,
596
+ criteriaInstance: matchedCriteriaInstance,
597
+ evaluationSummary: evaluationSummary,
588
598
  props: {
589
599
  telemetryQuery: telemetryQuery,
590
600
  },
@@ -596,6 +606,7 @@ export default class MonitorResourceUtil {
596
606
  dataToProcess: dataToProcess,
597
607
  autoResolveCriteriaInstanceIdAlertIdsDictionary,
598
608
  criteriaInstance: criteriaInstanceAlertMap[response.criteriaMetId!]!,
609
+ evaluationSummary: evaluationSummary,
599
610
  props: {
600
611
  telemetryQuery: telemetryQuery,
601
612
  },
@@ -616,6 +627,7 @@ export default class MonitorResourceUtil {
616
627
  rootCause: "No monitoring criteria met. Change to default status.",
617
628
  criteriaInstance: null, // no criteria met!
618
629
  dataToProcess: dataToProcess,
630
+ evaluationSummary: evaluationSummary,
619
631
  });
620
632
 
621
633
  // get last monitor status timeline.
@@ -671,779 +683,38 @@ export default class MonitorResourceUtil {
671
683
  logger.debug(
672
684
  `${dataToProcess.monitorId.toString()} - Monitor status updated to default.`,
673
685
  );
674
- }
675
- }
676
-
677
- if (mutex) {
678
- try {
679
- await Semaphore.release(mutex);
680
- } catch (err) {
681
- logger.error(err);
682
- }
683
- }
684
-
685
- return response;
686
- }
687
-
688
- @CaptureSpan()
689
- public static async saveMonitorMetrics(data: {
690
- monitorId: ObjectID;
691
- projectId: ObjectID;
692
- dataToProcess: DataToProcess;
693
- probeName: string | undefined;
694
- monitorName: string | undefined;
695
- }): Promise<void> {
696
- if (!data.monitorId) {
697
- return;
698
- }
699
-
700
- if (!data.projectId) {
701
- return;
702
- }
703
-
704
- if (!data.dataToProcess) {
705
- return;
706
- }
707
-
708
- const metricRows: Array<JSONObject> = [];
709
-
710
- /*
711
- * Metric name to serviceId map
712
- * example: "cpu.usage" -> [serviceId1, serviceId2]
713
- * since these are monitor metrics. They dont belong to any service so we can keep the array empty.
714
- */
715
- const metricNameServiceNameMap: Dictionary<MetricType> = {};
716
-
717
- if (
718
- (data.dataToProcess as ServerMonitorResponse).basicInfrastructureMetrics
719
- ) {
720
- // store cpu, memory, disk metrics.
721
-
722
- if ((data.dataToProcess as ServerMonitorResponse).requestReceivedAt) {
723
- let isOnline: boolean = true;
724
-
725
- const differenceInMinutes: number =
726
- OneUptimeDate.getDifferenceInMinutes(
727
- (data.dataToProcess as ServerMonitorResponse).requestReceivedAt,
728
- OneUptimeDate.getCurrentDate(),
729
- );
730
-
731
- if (differenceInMinutes > 2) {
732
- isOnline = false;
733
- }
734
-
735
- const attributes: JSONObject = this.buildMonitorMetricAttributes({
736
- monitorId: data.monitorId,
737
- projectId: data.projectId,
738
- monitorName: data.monitorName,
739
- probeName: data.probeName,
740
- });
741
-
742
- const metricRow: JSONObject = this.buildMonitorMetricRow({
743
- projectId: data.projectId,
744
- monitorId: data.monitorId,
745
- metricName: MonitorMetricType.IsOnline,
746
- value: isOnline ? 1 : 0,
747
- attributes: attributes,
748
- metricPointType: MetricPointType.Sum,
749
- });
750
-
751
- metricRows.push(metricRow);
752
-
753
- // add MetricType
754
- const metricType: MetricType = new MetricType();
755
- metricType.name = MonitorMetricType.IsOnline;
756
- metricType.description = CheckOn.IsOnline + " status for monitor";
757
- metricType.unit = "";
758
-
759
- // add to map
760
- metricNameServiceNameMap[MonitorMetricType.IsOnline] = metricType;
761
- }
762
-
763
- const basicMetrics: BasicInfrastructureMetrics | undefined = (
764
- data.dataToProcess as ServerMonitorResponse
765
- ).basicInfrastructureMetrics;
766
-
767
- if (!basicMetrics) {
768
- return;
769
- }
770
-
771
- if (basicMetrics.cpuMetrics) {
772
- const attributes: JSONObject = this.buildMonitorMetricAttributes({
773
- monitorId: data.monitorId,
774
- projectId: data.projectId,
775
- monitorName: data.monitorName,
776
- probeName: data.probeName,
777
- });
778
-
779
- const metricRow: JSONObject = this.buildMonitorMetricRow({
780
- projectId: data.projectId,
781
- monitorId: data.monitorId,
782
- metricName: MonitorMetricType.CPUUsagePercent,
783
- value: basicMetrics.cpuMetrics.percentUsed ?? null,
784
- attributes: attributes,
785
- metricPointType: MetricPointType.Sum,
786
- });
787
-
788
- metricRows.push(metricRow);
789
-
790
- const metricType: MetricType = new MetricType();
791
- metricType.name = MonitorMetricType.CPUUsagePercent;
792
- metricType.description = CheckOn.CPUUsagePercent + " of Server/VM";
793
- metricType.unit = "%";
794
-
795
- metricNameServiceNameMap[MonitorMetricType.CPUUsagePercent] =
796
- metricType;
797
- }
798
-
799
- if (basicMetrics.memoryMetrics) {
800
- const attributes: JSONObject = this.buildMonitorMetricAttributes({
801
- monitorId: data.monitorId,
802
- projectId: data.projectId,
803
- monitorName: data.monitorName,
804
- probeName: data.probeName,
805
- });
806
-
807
- const metricRow: JSONObject = this.buildMonitorMetricRow({
808
- projectId: data.projectId,
809
- monitorId: data.monitorId,
810
- metricName: MonitorMetricType.MemoryUsagePercent,
811
- value: basicMetrics.memoryMetrics.percentUsed ?? null,
812
- attributes: attributes,
813
- metricPointType: MetricPointType.Sum,
814
- });
815
-
816
- metricRows.push(metricRow);
817
-
818
- const metricType: MetricType = new MetricType();
819
- metricType.name = MonitorMetricType.MemoryUsagePercent;
820
- metricType.description = CheckOn.MemoryUsagePercent + " of Server/VM";
821
- metricType.unit = "%";
822
-
823
- metricNameServiceNameMap[MonitorMetricType.MemoryUsagePercent] =
824
- metricType;
825
- }
826
-
827
- if (basicMetrics.diskMetrics && basicMetrics.diskMetrics.length > 0) {
828
- for (const diskMetric of basicMetrics.diskMetrics) {
829
- const extraAttributes: JSONObject = {};
830
-
831
- if (diskMetric.diskPath) {
832
- extraAttributes["diskPath"] = diskMetric.diskPath;
833
- }
834
-
835
- const attributes: JSONObject = this.buildMonitorMetricAttributes({
836
- monitorId: data.monitorId,
837
- projectId: data.projectId,
838
- monitorName: data.monitorName,
839
- probeName: data.probeName,
840
- extraAttributes: extraAttributes,
841
- });
842
-
843
- const metricRow: JSONObject = this.buildMonitorMetricRow({
844
- projectId: data.projectId,
845
- monitorId: data.monitorId,
846
- metricName: MonitorMetricType.DiskUsagePercent,
847
- value: diskMetric.percentUsed ?? null,
848
- attributes: attributes,
849
- metricPointType: MetricPointType.Sum,
850
- });
851
-
852
- metricRows.push(metricRow);
853
686
 
854
- const metricType: MetricType = new MetricType();
855
- metricType.name = MonitorMetricType.DiskUsagePercent;
856
- metricType.description = CheckOn.DiskUsagePercent + " of Server/VM";
857
- metricType.unit = "%";
858
-
859
- metricNameServiceNameMap[MonitorMetricType.DiskUsagePercent] =
860
- metricType;
861
- }
862
- }
863
- }
864
-
865
- if (
866
- (data.dataToProcess as ProbeMonitorResponse).customCodeMonitorResponse
867
- ?.executionTimeInMS
868
- ) {
869
- const extraAttributes: JSONObject = {
870
- probeId: (
871
- data.dataToProcess as ProbeMonitorResponse
872
- ).probeId.toString(),
873
- };
874
-
875
- const attributes: JSONObject = this.buildMonitorMetricAttributes({
876
- monitorId: data.monitorId,
877
- projectId: data.projectId,
878
- extraAttributes: extraAttributes,
879
- });
880
-
881
- const metricRow: JSONObject = this.buildMonitorMetricRow({
882
- projectId: data.projectId,
883
- monitorId: data.monitorId,
884
- metricName: MonitorMetricType.ExecutionTime,
885
- value:
886
- (data.dataToProcess as ProbeMonitorResponse).customCodeMonitorResponse
887
- ?.executionTimeInMS ?? null,
888
- attributes: attributes,
889
- metricPointType: MetricPointType.Sum,
890
- });
891
-
892
- metricRows.push(metricRow);
893
-
894
- const metricType: MetricType = new MetricType();
895
- metricType.name = MonitorMetricType.ExecutionTime;
896
- metricType.description = CheckOn.ExecutionTime + " of this monitor";
897
- metricType.unit = "ms";
898
-
899
- metricNameServiceNameMap[MonitorMetricType.ExecutionTime] = metricType;
900
- }
901
-
902
- if (
903
- (data.dataToProcess as ProbeMonitorResponse) &&
904
- (data.dataToProcess as ProbeMonitorResponse).syntheticMonitorResponse &&
905
- (
906
- (data.dataToProcess as ProbeMonitorResponse).syntheticMonitorResponse ||
907
- []
908
- ).length > 0
909
- ) {
910
- for (const syntheticMonitorResponse of (
911
- data.dataToProcess as ProbeMonitorResponse
912
- ).syntheticMonitorResponse || []) {
913
- const extraAttributes: JSONObject = {
914
- probeId: (
915
- data.dataToProcess as ProbeMonitorResponse
916
- ).probeId.toString(),
917
- };
918
-
919
- if (syntheticMonitorResponse.browserType) {
920
- extraAttributes["browserType"] = syntheticMonitorResponse.browserType;
921
- }
922
-
923
- if (syntheticMonitorResponse.screenSizeType) {
924
- extraAttributes["screenSizeType"] =
925
- syntheticMonitorResponse.screenSizeType;
926
- }
927
-
928
- const attributes: JSONObject = this.buildMonitorMetricAttributes({
929
- monitorId: data.monitorId,
930
- projectId: data.projectId,
931
- monitorName: data.monitorName,
932
- probeName: data.probeName,
933
- extraAttributes: extraAttributes,
934
- });
935
-
936
- const metricRow: JSONObject = this.buildMonitorMetricRow({
937
- projectId: data.projectId,
938
- monitorId: data.monitorId,
939
- metricName: MonitorMetricType.ExecutionTime,
940
- value: syntheticMonitorResponse.executionTimeInMS ?? null,
941
- attributes: attributes,
942
- metricPointType: MetricPointType.Sum,
943
- });
944
-
945
- metricRows.push(metricRow);
946
-
947
- const metricType: MetricType = new MetricType();
948
- metricType.name = MonitorMetricType.ExecutionTime;
949
- metricType.description = CheckOn.ExecutionTime + " of this monitor";
950
- metricType.unit = "ms";
951
-
952
- metricNameServiceNameMap[MonitorMetricType.ExecutionTime] = metricType;
953
- }
954
- }
955
-
956
- if ((data.dataToProcess as ProbeMonitorResponse).responseTimeInMs) {
957
- const extraAttributes: JSONObject = {
958
- probeId: (
959
- data.dataToProcess as ProbeMonitorResponse
960
- ).probeId.toString(),
961
- };
962
-
963
- const attributes: JSONObject = this.buildMonitorMetricAttributes({
964
- monitorId: data.monitorId,
965
- projectId: data.projectId,
966
- monitorName: data.monitorName,
967
- probeName: data.probeName,
968
- extraAttributes: extraAttributes,
969
- });
970
-
971
- const metricRow: JSONObject = this.buildMonitorMetricRow({
972
- projectId: data.projectId,
973
- monitorId: data.monitorId,
974
- metricName: MonitorMetricType.ResponseTime,
975
- value:
976
- (data.dataToProcess as ProbeMonitorResponse).responseTimeInMs ?? null,
977
- attributes: attributes,
978
- metricPointType: MetricPointType.Sum,
979
- });
980
-
981
- metricRows.push(metricRow);
982
-
983
- const metricType: MetricType = new MetricType();
984
- metricType.name = MonitorMetricType.ResponseTime;
985
- metricType.description = CheckOn.ResponseTime + " of this monitor";
986
- metricType.unit = "ms";
987
-
988
- metricNameServiceNameMap[MonitorMetricType.ResponseTime] = metricType;
989
- }
990
-
991
- if ((data.dataToProcess as ProbeMonitorResponse).isOnline !== undefined) {
992
- const extraAttributes: JSONObject = {
993
- probeId: (
994
- data.dataToProcess as ProbeMonitorResponse
995
- ).probeId.toString(),
996
- };
997
-
998
- const attributes: JSONObject = this.buildMonitorMetricAttributes({
999
- monitorId: data.monitorId,
1000
- projectId: data.projectId,
1001
- monitorName: data.monitorName,
1002
- probeName: data.probeName,
1003
- extraAttributes: extraAttributes,
1004
- });
1005
-
1006
- const metricRow: JSONObject = this.buildMonitorMetricRow({
1007
- projectId: data.projectId,
1008
- monitorId: data.monitorId,
1009
- metricName: MonitorMetricType.IsOnline,
1010
- value: (data.dataToProcess as ProbeMonitorResponse).isOnline ? 1 : 0,
1011
- attributes: attributes,
1012
- metricPointType: MetricPointType.Sum,
1013
- });
1014
-
1015
- metricRows.push(metricRow);
1016
-
1017
- const metricType: MetricType = new MetricType();
1018
- metricType.name = MonitorMetricType.IsOnline;
1019
- metricType.description = CheckOn.IsOnline + " status for monitor";
1020
- metricType.unit = "";
1021
-
1022
- metricNameServiceNameMap[MonitorMetricType.IsOnline] = metricType;
1023
- }
1024
-
1025
- if ((data.dataToProcess as ProbeMonitorResponse).responseCode) {
1026
- const extraAttributes: JSONObject = {
1027
- probeId: (
1028
- data.dataToProcess as ProbeMonitorResponse
1029
- ).probeId.toString(),
1030
- };
1031
-
1032
- const attributes: JSONObject = this.buildMonitorMetricAttributes({
1033
- monitorId: data.monitorId,
1034
- projectId: data.projectId,
1035
- monitorName: data.monitorName,
1036
- probeName: data.probeName,
1037
- extraAttributes: extraAttributes,
1038
- });
1039
-
1040
- const metricRow: JSONObject = this.buildMonitorMetricRow({
1041
- projectId: data.projectId,
1042
- monitorId: data.monitorId,
1043
- metricName: MonitorMetricType.ResponseStatusCode,
1044
- value:
1045
- (data.dataToProcess as ProbeMonitorResponse).responseCode ?? null,
1046
- attributes: attributes,
1047
- metricPointType: MetricPointType.Sum,
1048
- });
1049
-
1050
- metricRows.push(metricRow);
1051
-
1052
- const metricType: MetricType = new MetricType();
1053
- metricType.name = MonitorMetricType.ResponseStatusCode;
1054
- metricType.description = CheckOn.ResponseStatusCode + " for this monitor";
1055
- metricType.unit = "Status Code";
1056
-
1057
- metricNameServiceNameMap[MonitorMetricType.ResponseStatusCode] =
1058
- metricType;
1059
- }
1060
-
1061
- if (metricRows.length > 0) {
1062
- await MetricService.insertJsonRows(metricRows);
1063
- }
1064
-
1065
- // index metrics
1066
- TelemetryUtil.indexMetricNameServiceNameMap({
1067
- projectId: data.projectId,
1068
- metricNameServiceNameMap: metricNameServiceNameMap,
1069
- }).catch((err: Error) => {
1070
- logger.error(err);
1071
- });
1072
-
1073
- // save monitor log.
1074
- const logIngestionDate: Date = OneUptimeDate.getCurrentDate();
1075
- const logTimestamp: string =
1076
- OneUptimeDate.toClickhouseDateTime(logIngestionDate);
1077
-
1078
- const monitorLogRow: JSONObject = {
1079
- _id: ObjectID.generate().toString(),
1080
- createdAt: logTimestamp,
1081
- updatedAt: logTimestamp,
1082
- projectId: data.projectId.toString(),
1083
- monitorId: data.monitorId.toString(),
1084
- time: logTimestamp,
1085
- logBody: JSON.parse(JSON.stringify(data.dataToProcess)),
1086
- };
1087
-
1088
- MonitorLogService.insertJsonRows([monitorLogRow]).catch((err: Error) => {
1089
- logger.error(err);
1090
- });
1091
- }
1092
-
1093
- private static async processMonitorStep(input: {
1094
- dataToProcess: DataToProcess;
1095
- monitorStep: MonitorStep;
1096
- monitor: Monitor;
1097
- probeApiIngestResponse: ProbeApiIngestResponse;
1098
- }): Promise<ProbeApiIngestResponse> {
1099
- // process monitor step here.
1100
-
1101
- const criteria: MonitorCriteria | undefined =
1102
- input.monitorStep.data?.monitorCriteria;
1103
-
1104
- if (!criteria || !criteria.data) {
1105
- // do nothing as there's no criteria to process.
1106
- return input.probeApiIngestResponse;
1107
- }
1108
-
1109
- for (const criteriaInstance of criteria.data.monitorCriteriaInstanceArray) {
1110
- const rootCause: string | null =
1111
- await MonitorResourceUtil.processMonitorCriteiaInstance({
1112
- dataToProcess: input.dataToProcess,
1113
- monitorStep: input.monitorStep,
1114
- monitor: input.monitor,
1115
- probeApiIngestResponse: input.probeApiIngestResponse,
1116
- criteriaInstance: criteriaInstance,
1117
- });
1118
-
1119
- if (rootCause) {
1120
- input.probeApiIngestResponse.criteriaMetId = criteriaInstance.data?.id;
1121
- input.probeApiIngestResponse.rootCause = `
1122
- **Created because the following criteria was met**:
1123
-
1124
- **Criteria Name**: ${criteriaInstance.data?.name}
1125
- `;
1126
-
1127
- if (rootCause) {
1128
- input.probeApiIngestResponse.rootCause += `
1129
- **Filter Conditions Met**: ${rootCause}
1130
- `;
1131
- }
1132
-
1133
- if ((input.dataToProcess as ProbeMonitorResponse).failureCause) {
1134
- input.probeApiIngestResponse.rootCause += `
1135
- **Cause**: ${(input.dataToProcess as ProbeMonitorResponse).failureCause || ""}
1136
- `;
1137
- }
1138
- break;
1139
- }
1140
- }
1141
-
1142
- return input.probeApiIngestResponse;
1143
- }
1144
-
1145
- private static async processMonitorCriteiaInstance(input: {
1146
- dataToProcess: DataToProcess;
1147
- monitorStep: MonitorStep;
1148
- monitor: Monitor;
1149
- probeApiIngestResponse: ProbeApiIngestResponse;
1150
- criteriaInstance: MonitorCriteriaInstance;
1151
- }): Promise<string | null> {
1152
- /*
1153
- * returns root cause if any. Otherwise criteria is not met.
1154
- * process monitor criteria instance here.
1155
- */
1156
-
1157
- const rootCause: string | null =
1158
- await MonitorResourceUtil.isMonitorInstanceCriteriaFiltersMet({
1159
- dataToProcess: input.dataToProcess,
1160
- monitorStep: input.monitorStep,
1161
- monitor: input.monitor,
1162
- probeApiIngestResponse: input.probeApiIngestResponse,
1163
- criteriaInstance: input.criteriaInstance,
1164
- });
1165
-
1166
- // do nothing as there's no criteria to process.
1167
- return rootCause;
1168
- }
1169
-
1170
- private static async isMonitorInstanceCriteriaFiltersMet(input: {
1171
- dataToProcess: DataToProcess;
1172
- monitorStep: MonitorStep;
1173
- monitor: Monitor;
1174
- probeApiIngestResponse: ProbeApiIngestResponse;
1175
- criteriaInstance: MonitorCriteriaInstance;
1176
- }): Promise<string | null> {
1177
- // returns root cause if any. Otherwise criteria is not met.
1178
- let finalResult: string | null = "All filters met. ";
1179
-
1180
- if (FilterCondition.Any === input.criteriaInstance.data?.filterCondition) {
1181
- finalResult = null; // set to false as we need to check if any of the filters are met.
1182
- }
687
+ const defaultStatusName: string | null = await getMonitorStatusName(
688
+ monitorSteps.data.defaultMonitorStatusId,
689
+ );
1183
690
 
1184
- for (const criteriaFilter of input.criteriaInstance.data?.filters || []) {
1185
- const rootCause: string | null =
1186
- await MonitorResourceUtil.isMonitorInstanceCriteriaFilterMet({
1187
- dataToProcess: input.dataToProcess,
1188
- monitorStep: input.monitorStep,
1189
- monitor: input.monitor,
1190
- probeApiIngestResponse: input.probeApiIngestResponse,
1191
- criteriaInstance: input.criteriaInstance,
1192
- criteriaFilter: criteriaFilter,
691
+ evaluationSummary.events.push({
692
+ type: "monitor-status-changed",
693
+ title: "Monitor status reverted",
694
+ message: defaultStatusName
695
+ ? `Monitor status reverted to "${defaultStatusName}" because no monitoring criteria were met.`
696
+ : "Monitor status reverted to its default state because no monitoring criteria were met.",
697
+ at: OneUptimeDate.getCurrentDate(),
1193
698
  });
1194
-
1195
- const didMeetCriteria: boolean = Boolean(rootCause);
1196
-
1197
- if (
1198
- FilterCondition.Any === input.criteriaInstance.data?.filterCondition &&
1199
- didMeetCriteria === true
1200
- ) {
1201
- finalResult = rootCause;
1202
- }
1203
-
1204
- if (
1205
- FilterCondition.All === input.criteriaInstance.data?.filterCondition &&
1206
- didMeetCriteria === false
1207
- ) {
1208
- finalResult = null;
1209
- break;
1210
- }
1211
-
1212
- if (
1213
- FilterCondition.All === input.criteriaInstance.data?.filterCondition &&
1214
- didMeetCriteria &&
1215
- rootCause
1216
- ) {
1217
- finalResult += `
1218
-
1219
- - ${rootCause}`; // in markdown format.
1220
699
  }
1221
700
  }
1222
701
 
1223
- return finalResult;
1224
- }
1225
-
1226
- private static async isMonitorInstanceCriteriaFilterMet(input: {
1227
- dataToProcess: DataToProcess;
1228
- monitorStep: MonitorStep;
1229
- monitor: Monitor;
1230
- probeApiIngestResponse: ProbeApiIngestResponse;
1231
- criteriaInstance: MonitorCriteriaInstance;
1232
- criteriaFilter: CriteriaFilter;
1233
- }): Promise<string | null> {
1234
- /*
1235
- * returns root cause if any. Otherwise criteria is not met.
1236
- * process monitor criteria filter here.
1237
- */
1238
-
1239
- if (input.criteriaFilter.checkOn === CheckOn.JavaScriptExpression) {
1240
- let storageMap: JSONObject = {};
1241
-
1242
- if (
1243
- input.monitor.monitorType === MonitorType.API ||
1244
- input.monitor.monitorType === MonitorType.Website
1245
- ) {
1246
- // try to parse json
1247
- let responseBody: JSONObject | null = null;
1248
- try {
1249
- responseBody = JSON.parse(
1250
- ((input.dataToProcess as ProbeMonitorResponse)
1251
- .responseBody as string) || "{}",
1252
- );
1253
- } catch (err) {
1254
- logger.error(err);
1255
- responseBody = (input.dataToProcess as ProbeMonitorResponse)
1256
- .responseBody as JSONObject;
1257
- }
1258
-
1259
- if (
1260
- typeof responseBody === Typeof.String &&
1261
- responseBody?.toString() === ""
1262
- ) {
1263
- // if empty string then set to empty object.
1264
- responseBody = {};
1265
- }
1266
-
1267
- storageMap = {
1268
- responseBody: responseBody,
1269
- responseHeaders: (input.dataToProcess as ProbeMonitorResponse)
1270
- .responseHeaders,
1271
- responseStatusCode: (input.dataToProcess as ProbeMonitorResponse)
1272
- .responseCode,
1273
- responseTimeInMs: (input.dataToProcess as ProbeMonitorResponse)
1274
- .responseTimeInMs,
1275
- isOnline: (input.dataToProcess as ProbeMonitorResponse).isOnline,
1276
- };
1277
- }
1278
-
1279
- if (input.monitor.monitorType === MonitorType.IncomingRequest) {
1280
- storageMap = {
1281
- requestBody: (input.dataToProcess as IncomingMonitorRequest)
1282
- .requestBody,
1283
- requestHeaders: (input.dataToProcess as IncomingMonitorRequest)
1284
- .requestHeaders,
1285
- };
1286
- }
1287
-
1288
- // now evaluate the expression.
1289
- let expression: string = input.criteriaFilter.value as string;
1290
- expression = VMUtil.replaceValueInPlace(storageMap, expression, false); // now pass this to the VM.
1291
-
1292
- const code: string = `return Boolean(${expression});`;
1293
- let result: ReturnResult | null = null;
1294
-
702
+ if (mutex) {
1295
703
  try {
1296
- result = await VMUtil.runCodeInSandbox({
1297
- code: code,
1298
- options: {
1299
- args: {},
1300
- },
1301
- });
704
+ await Semaphore.release(mutex);
1302
705
  } catch (err) {
1303
706
  logger.error(err);
1304
- return null;
1305
707
  }
1306
-
1307
- if (result && result.returnValue) {
1308
- return `JavaScript Expression - ${expression} - evaluated to true.`;
1309
- }
1310
-
1311
- return null; // if true then return null.
1312
708
  }
1313
709
 
1314
- if (
1315
- input.monitor.monitorType === MonitorType.API ||
1316
- input.monitor.monitorType === MonitorType.Website ||
1317
- input.monitor.monitorType === MonitorType.IP ||
1318
- input.monitor.monitorType === MonitorType.Ping ||
1319
- input.monitor.monitorType === MonitorType.Port
1320
- ) {
1321
- const apiRequestCriteriaResult: string | null =
1322
- await APIRequestCriteria.isMonitorInstanceCriteriaFilterMet({
1323
- dataToProcess: input.dataToProcess,
1324
- criteriaFilter: input.criteriaFilter,
1325
- });
710
+ await persistLatestMonitorPayload();
1326
711
 
1327
- if (apiRequestCriteriaResult) {
1328
- return apiRequestCriteriaResult;
1329
- }
1330
- }
1331
-
1332
- if (
1333
- input.monitor.monitorType === MonitorType.CustomJavaScriptCode &&
1334
- (input.dataToProcess as ProbeMonitorResponse).customCodeMonitorResponse
1335
- ) {
1336
- const criteriaResult: string | null =
1337
- await CustomCodeMonitoringCriteria.isMonitorInstanceCriteriaFilterMet({
1338
- monitorResponse: (input.dataToProcess as ProbeMonitorResponse)
1339
- .customCodeMonitorResponse!,
1340
- criteriaFilter: input.criteriaFilter,
1341
- });
1342
-
1343
- if (criteriaResult) {
1344
- return criteriaResult;
1345
- }
1346
- }
1347
-
1348
- if (
1349
- input.monitor.monitorType === MonitorType.SyntheticMonitor &&
1350
- (input.dataToProcess as ProbeMonitorResponse).syntheticMonitorResponse
1351
- ) {
1352
- const criteriaResult: string | null =
1353
- await SyntheticMonitoringCriteria.isMonitorInstanceCriteriaFilterMet({
1354
- monitorResponse:
1355
- (input.dataToProcess as ProbeMonitorResponse)
1356
- .syntheticMonitorResponse || [],
1357
- criteriaFilter: input.criteriaFilter,
1358
- });
1359
-
1360
- if (criteriaResult) {
1361
- return criteriaResult;
1362
- }
1363
- }
1364
-
1365
- if (input.monitor.monitorType === MonitorType.IncomingRequest) {
1366
- logger.debug(
1367
- `${input.monitor.id?.toString()} - Incoming Request Monitor. Checking criteria filter.`,
1368
- );
1369
- //check incoming request
1370
- const incomingRequestResult: string | null =
1371
- await IncomingRequestCriteria.isMonitorInstanceCriteriaFilterMet({
1372
- dataToProcess: input.dataToProcess,
1373
- criteriaFilter: input.criteriaFilter,
1374
- });
1375
-
1376
- if (incomingRequestResult) {
1377
- return incomingRequestResult;
1378
- }
1379
- }
1380
-
1381
- if (input.monitor.monitorType === MonitorType.SSLCertificate) {
1382
- // check SSL monitor
1383
- const sslMonitorResult: string | null =
1384
- await SSLMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
1385
- dataToProcess: input.dataToProcess,
1386
- criteriaFilter: input.criteriaFilter,
1387
- });
1388
-
1389
- if (sslMonitorResult) {
1390
- return sslMonitorResult;
1391
- }
1392
- }
1393
-
1394
- if (input.monitor.monitorType === MonitorType.Server) {
1395
- // check server monitor
1396
- const serverMonitorResult: string | null =
1397
- await ServerMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
1398
- dataToProcess: input.dataToProcess,
1399
- criteriaFilter: input.criteriaFilter,
1400
- });
1401
-
1402
- if (serverMonitorResult) {
1403
- return serverMonitorResult;
1404
- }
1405
- }
1406
-
1407
- if (input.monitor.monitorType === MonitorType.Logs) {
1408
- // check server monitor
1409
- const logMonitorResult: string | null =
1410
- await LogMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
1411
- dataToProcess: input.dataToProcess,
1412
- criteriaFilter: input.criteriaFilter,
1413
- });
1414
-
1415
- if (logMonitorResult) {
1416
- return logMonitorResult;
1417
- }
1418
- }
1419
-
1420
- if (input.monitor.monitorType === MonitorType.Metrics) {
1421
- // check server monitor
1422
- const logMonitorResult: string | null =
1423
- await MetricMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
1424
- dataToProcess: input.dataToProcess,
1425
- criteriaFilter: input.criteriaFilter,
1426
- monitorStep: input.monitorStep,
1427
- });
1428
-
1429
- if (logMonitorResult) {
1430
- return logMonitorResult;
1431
- }
1432
- }
1433
-
1434
- if (input.monitor.monitorType === MonitorType.Traces) {
1435
- // check server monitor
1436
- const traceMonitorResult: string | null =
1437
- await TraceMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
1438
- dataToProcess: input.dataToProcess,
1439
- criteriaFilter: input.criteriaFilter,
1440
- });
1441
-
1442
- if (traceMonitorResult) {
1443
- return traceMonitorResult;
1444
- }
1445
- }
712
+ MonitorLogUtil.saveMonitorLog({
713
+ monitorId: monitor.id!,
714
+ projectId: monitor.projectId!,
715
+ dataToProcess: dataToProcess,
716
+ });
1446
717
 
1447
- return null;
718
+ return response;
1448
719
  }
1449
720
  }