@oneuptime/common 7.0.3148 → 7.0.3156

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 (225) hide show
  1. package/Models/DatabaseModels/Alert.ts +1010 -0
  2. package/Models/DatabaseModels/AlertCustomField.ts +340 -0
  3. package/Models/DatabaseModels/AlertInternalNote.ts +371 -0
  4. package/Models/DatabaseModels/AlertNoteTemplate.ts +352 -0
  5. package/Models/DatabaseModels/AlertOwnerTeam.ts +416 -0
  6. package/Models/DatabaseModels/AlertOwnerUser.ts +415 -0
  7. package/Models/DatabaseModels/AlertSeverity.ts +426 -0
  8. package/Models/DatabaseModels/AlertState.ts +502 -0
  9. package/Models/DatabaseModels/AlertStateTimeline.ts +525 -0
  10. package/Models/DatabaseModels/Incident.ts +2 -11
  11. package/Models/DatabaseModels/Index.ts +34 -12
  12. package/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.ts +55 -0
  13. package/Models/DatabaseModels/TableView.ts +452 -0
  14. package/Server/Infrastructure/Postgres/SchemaMigrations/1727894983857-MigrationName.ts +51 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/1727906598804-MigrationName.ts +553 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  17. package/Server/Infrastructure/Semaphore.ts +9 -4
  18. package/Server/Services/AlertCustomFieldService.ts +9 -0
  19. package/Server/Services/AlertInternalNoteService.ts +10 -0
  20. package/Server/Services/AlertNoteTemplateService.ts +9 -0
  21. package/Server/Services/AlertOwnerTeamService.ts +10 -0
  22. package/Server/Services/AlertOwnerUserService.ts +10 -0
  23. package/Server/Services/AlertService.ts +568 -0
  24. package/Server/Services/AlertSeverityService.ts +154 -0
  25. package/Server/Services/AlertStateService.ts +227 -0
  26. package/Server/Services/AlertStateTimelineService.ts +334 -0
  27. package/Server/Services/CallLogService.ts +4 -1
  28. package/Server/Services/DatabaseService.ts +17 -20
  29. package/Server/Services/EmailLogService.ts +4 -1
  30. package/Server/Services/IncidentService.ts +4 -1
  31. package/Server/Services/IncidentStateTimelineService.ts +4 -1
  32. package/Server/Services/Index.ts +23 -0
  33. package/Server/Services/MonitorStatusTimelineService.ts +5 -1
  34. package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +4 -1
  35. package/Server/Services/OnCallDutyPolicyService.ts +15 -0
  36. package/Server/Services/ProjectService.ts +99 -1
  37. package/Server/Services/ScheduledMaintenanceService.ts +4 -1
  38. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +4 -1
  39. package/Server/Services/ShortLinkService.ts +4 -1
  40. package/Server/Services/SmsLogService.ts +4 -1
  41. package/Server/Services/TableViewService.ts +10 -0
  42. package/Server/Services/TelemetryUsageBillingService.ts +4 -1
  43. package/Server/Services/UserNotificationSettingService.ts +58 -0
  44. package/Server/Services/UserOnCallLogService.ts +4 -1
  45. package/Server/Services/WorkflowLogService.ts +4 -1
  46. package/Server/Types/Workflow/Components/API/Post.ts +25 -0
  47. package/Server/Utils/Monitor/MonitorAlert.ts +273 -0
  48. package/Server/Utils/Monitor/MonitorIncident.ts +298 -0
  49. package/Server/Utils/Monitor/MonitorResource.ts +87 -387
  50. package/Server/Utils/Monitor/MonitorStatusTimeline.ts +120 -0
  51. package/Server/Utils/Realtime.ts +1 -35
  52. package/Types/Email/EmailTemplateType.ts +7 -0
  53. package/Types/Icon/IconProp.ts +1 -0
  54. package/Types/Monitor/CriteriaAlert.ts +11 -0
  55. package/Types/Monitor/MonitorCriteria.ts +2 -0
  56. package/Types/Monitor/MonitorCriteriaInstance.ts +134 -1
  57. package/Types/Monitor/MonitorStep.ts +1 -0
  58. package/Types/Monitor/MonitorSteps.ts +1 -0
  59. package/Types/NotificationSetting/NotificationSettingEventType.ts +7 -0
  60. package/Types/Permission.ts +369 -1
  61. package/Types/Telemetry/TelemetryQuery.ts +10 -0
  62. package/Types/UserNotification/UserNotificationEventType.ts +1 -0
  63. package/UI/Components/Card/Card.tsx +40 -31
  64. package/UI/Components/Card/CardButtons/MoreButton.ts +15 -0
  65. package/UI/Components/HeaderAlert/HeaderAlert.tsx +75 -16
  66. package/UI/Components/HeaderAlert/HeaderAlertGroup.tsx +50 -0
  67. package/UI/Components/HeaderAlert/HeaderModelAlert.tsx +5 -1
  68. package/UI/Components/Icon/Icon.tsx +8 -0
  69. package/UI/Components/ModelDetail/CardModelDetail.tsx +4 -2
  70. package/UI/Components/ModelTable/BaseModelTable.tsx +70 -2
  71. package/UI/Components/ModelTable/TableView.tsx +317 -0
  72. package/UI/Components/MoreMenu/Divider.tsx +7 -0
  73. package/UI/Components/MoreMenu/MoreMenu.tsx +54 -0
  74. package/UI/Components/MoreMenu/MoreMenuItem.tsx +37 -0
  75. package/UI/Components/MoreMenu/MoreMenuSection.tsx +22 -0
  76. package/UI/Components/Toggle/Toggle.tsx +14 -0
  77. package/build/dist/Models/DatabaseModels/Alert.js +1028 -0
  78. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -0
  79. package/build/dist/Models/DatabaseModels/AlertCustomField.js +360 -0
  80. package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -0
  81. package/build/dist/Models/DatabaseModels/AlertInternalNote.js +391 -0
  82. package/build/dist/Models/DatabaseModels/AlertInternalNote.js.map +1 -0
  83. package/build/dist/Models/DatabaseModels/AlertNoteTemplate.js +372 -0
  84. package/build/dist/Models/DatabaseModels/AlertNoteTemplate.js.map +1 -0
  85. package/build/dist/Models/DatabaseModels/AlertOwnerTeam.js +434 -0
  86. package/build/dist/Models/DatabaseModels/AlertOwnerTeam.js.map +1 -0
  87. package/build/dist/Models/DatabaseModels/AlertOwnerUser.js +433 -0
  88. package/build/dist/Models/DatabaseModels/AlertOwnerUser.js.map +1 -0
  89. package/build/dist/Models/DatabaseModels/AlertSeverity.js +450 -0
  90. package/build/dist/Models/DatabaseModels/AlertSeverity.js.map +1 -0
  91. package/build/dist/Models/DatabaseModels/AlertState.js +530 -0
  92. package/build/dist/Models/DatabaseModels/AlertState.js.map +1 -0
  93. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +548 -0
  94. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -0
  95. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  96. package/build/dist/Models/DatabaseModels/Index.js +29 -9
  97. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  98. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js +55 -0
  99. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js.map +1 -1
  100. package/build/dist/Models/DatabaseModels/TableView.js +475 -0
  101. package/build/dist/Models/DatabaseModels/TableView.js.map +1 -0
  102. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1727894983857-MigrationName.js +24 -0
  103. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1727894983857-MigrationName.js.map +1 -0
  104. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1727906598804-MigrationName.js +198 -0
  105. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1727906598804-MigrationName.js.map +1 -0
  106. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  107. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  108. package/build/dist/Server/Infrastructure/Semaphore.js +2 -2
  109. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  110. package/build/dist/Server/Services/AlertCustomFieldService.js +9 -0
  111. package/build/dist/Server/Services/AlertCustomFieldService.js.map +1 -0
  112. package/build/dist/Server/Services/AlertInternalNoteService.js +9 -0
  113. package/build/dist/Server/Services/AlertInternalNoteService.js.map +1 -0
  114. package/build/dist/Server/Services/AlertNoteTemplateService.js +9 -0
  115. package/build/dist/Server/Services/AlertNoteTemplateService.js.map +1 -0
  116. package/build/dist/Server/Services/AlertOwnerTeamService.js +9 -0
  117. package/build/dist/Server/Services/AlertOwnerTeamService.js.map +1 -0
  118. package/build/dist/Server/Services/AlertOwnerUserService.js +9 -0
  119. package/build/dist/Server/Services/AlertOwnerUserService.js.map +1 -0
  120. package/build/dist/Server/Services/AlertService.js +418 -0
  121. package/build/dist/Server/Services/AlertService.js.map +1 -0
  122. package/build/dist/Server/Services/AlertSeverityService.js +108 -0
  123. package/build/dist/Server/Services/AlertSeverityService.js.map +1 -0
  124. package/build/dist/Server/Services/AlertStateService.js +158 -0
  125. package/build/dist/Server/Services/AlertStateService.js.map +1 -0
  126. package/build/dist/Server/Services/AlertStateTimelineService.js +267 -0
  127. package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -0
  128. package/build/dist/Server/Services/CallLogService.js +4 -1
  129. package/build/dist/Server/Services/CallLogService.js.map +1 -1
  130. package/build/dist/Server/Services/DatabaseService.js +9 -9
  131. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  132. package/build/dist/Server/Services/EmailLogService.js +4 -1
  133. package/build/dist/Server/Services/EmailLogService.js.map +1 -1
  134. package/build/dist/Server/Services/IncidentService.js +4 -1
  135. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  136. package/build/dist/Server/Services/IncidentStateTimelineService.js +4 -1
  137. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  138. package/build/dist/Server/Services/Index.js +21 -0
  139. package/build/dist/Server/Services/Index.js.map +1 -1
  140. package/build/dist/Server/Services/MonitorStatusTimelineService.js +5 -1
  141. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  142. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +4 -1
  143. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
  144. package/build/dist/Server/Services/OnCallDutyPolicyService.js +8 -0
  145. package/build/dist/Server/Services/OnCallDutyPolicyService.js.map +1 -1
  146. package/build/dist/Server/Services/ProjectService.js +80 -1
  147. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  148. package/build/dist/Server/Services/ScheduledMaintenanceService.js +4 -1
  149. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  150. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +4 -1
  151. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  152. package/build/dist/Server/Services/ShortLinkService.js +4 -1
  153. package/build/dist/Server/Services/ShortLinkService.js.map +1 -1
  154. package/build/dist/Server/Services/SmsLogService.js +4 -1
  155. package/build/dist/Server/Services/SmsLogService.js.map +1 -1
  156. package/build/dist/Server/Services/TableViewService.js +9 -0
  157. package/build/dist/Server/Services/TableViewService.js.map +1 -0
  158. package/build/dist/Server/Services/TelemetryUsageBillingService.js +4 -1
  159. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  160. package/build/dist/Server/Services/UserNotificationSettingService.js +49 -0
  161. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  162. package/build/dist/Server/Services/UserOnCallLogService.js +4 -1
  163. package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
  164. package/build/dist/Server/Services/WorkflowLogService.js +4 -1
  165. package/build/dist/Server/Services/WorkflowLogService.js.map +1 -1
  166. package/build/dist/Server/Types/Workflow/Components/API/Post.js +14 -0
  167. package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
  168. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +177 -0
  169. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -0
  170. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +187 -0
  171. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -0
  172. package/build/dist/Server/Utils/Monitor/MonitorResource.js +65 -254
  173. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  174. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js +79 -0
  175. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js.map +1 -0
  176. package/build/dist/Server/Utils/Realtime.js +3 -28
  177. package/build/dist/Server/Utils/Realtime.js.map +1 -1
  178. package/build/dist/Types/Email/EmailTemplateType.js +4 -0
  179. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  180. package/build/dist/Types/Icon/IconProp.js +1 -0
  181. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  182. package/build/dist/Types/Monitor/CriteriaAlert.js +2 -0
  183. package/build/dist/Types/Monitor/CriteriaAlert.js.map +1 -0
  184. package/build/dist/Types/Monitor/MonitorCriteria.js +1 -0
  185. package/build/dist/Types/Monitor/MonitorCriteria.js.map +1 -1
  186. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +120 -1
  187. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  188. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  189. package/build/dist/Types/Monitor/MonitorSteps.js.map +1 -1
  190. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +5 -0
  191. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
  192. package/build/dist/Types/Permission.js +323 -1
  193. package/build/dist/Types/Permission.js.map +1 -1
  194. package/build/dist/Types/Telemetry/TelemetryQuery.js +2 -0
  195. package/build/dist/Types/Telemetry/TelemetryQuery.js.map +1 -0
  196. package/build/dist/Types/UserNotification/UserNotificationEventType.js +1 -0
  197. package/build/dist/Types/UserNotification/UserNotificationEventType.js.map +1 -1
  198. package/build/dist/UI/Components/Card/Card.js +3 -2
  199. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  200. package/build/dist/UI/Components/Card/CardButtons/MoreButton.js +12 -0
  201. package/build/dist/UI/Components/Card/CardButtons/MoreButton.js.map +1 -0
  202. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js +53 -9
  203. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js.map +1 -1
  204. package/build/dist/UI/Components/HeaderAlert/HeaderAlertGroup.js +25 -0
  205. package/build/dist/UI/Components/HeaderAlert/HeaderAlertGroup.js.map +1 -0
  206. package/build/dist/UI/Components/HeaderAlert/HeaderModelAlert.js +1 -1
  207. package/build/dist/UI/Components/HeaderAlert/HeaderModelAlert.js.map +1 -1
  208. package/build/dist/UI/Components/Icon/Icon.js +3 -0
  209. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  210. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  211. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +46 -0
  212. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  213. package/build/dist/UI/Components/ModelTable/TableView.js +183 -0
  214. package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -0
  215. package/build/dist/UI/Components/MoreMenu/Divider.js +6 -0
  216. package/build/dist/UI/Components/MoreMenu/Divider.js.map +1 -0
  217. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +19 -0
  218. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -0
  219. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +13 -0
  220. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -0
  221. package/build/dist/UI/Components/MoreMenu/MoreMenuSection.js +10 -0
  222. package/build/dist/UI/Components/MoreMenu/MoreMenuSection.js.map +1 -0
  223. package/build/dist/UI/Components/Toggle/Toggle.js +7 -1
  224. package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
  225. package/package.json +2 -2
@@ -1,6 +1,3 @@
1
- import IncidentService from "../../Services/IncidentService";
2
- import IncidentSeverityService from "../../Services/IncidentSeverityService";
3
- import IncidentStateTimelineService from "../../Services/IncidentStateTimelineService";
4
1
  import MonitorMetricsByMinuteService from "../../Services/MonitorMetricsByMinuteService";
5
2
  import MonitorProbeService from "../../Services/MonitorProbeService";
6
3
  import MonitorService from "../../Services/MonitorService";
@@ -15,7 +12,6 @@ import ServerMonitorCriteria from "./Criteria/ServerMonitorCriteria";
15
12
  import SyntheticMonitoringCriteria from "./Criteria/SyntheticMonitor";
16
13
  import DataToProcess from "./DataToProcess";
17
14
  import SortOrder from "Common/Types/BaseDatabase/SortOrder";
18
- import { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
19
15
  import Dictionary from "Common/Types/Dictionary";
20
16
  import BadDataException from "Common/Types/Exception/BadDataException";
21
17
  import BasicInfrastructureMetrics from "Common/Types/Infrastructure/BasicMetrics";
@@ -41,26 +37,36 @@ import ProbeApiIngestResponse from "Common/Types/Probe/ProbeApiIngestResponse";
41
37
  import ProbeMonitorResponse from "Common/Types/Probe/ProbeMonitorResponse";
42
38
  import Typeof from "Common/Types/Typeof";
43
39
  import MonitorMetricsByMinute from "Common/Models/AnalyticsModels/MonitorMetricsByMinute";
44
- import Incident, {
45
- TelemetryIncidentQuery,
46
- } from "Common/Models/DatabaseModels/Incident";
47
- import IncidentSeverity from "Common/Models/DatabaseModels/IncidentSeverity";
48
- import IncidentStateTimeline from "Common/Models/DatabaseModels/IncidentStateTimeline";
49
40
  import Monitor from "Common/Models/DatabaseModels/Monitor";
50
41
  import MonitorProbe from "Common/Models/DatabaseModels/MonitorProbe";
51
42
  import MonitorStatusTimeline from "Common/Models/DatabaseModels/MonitorStatusTimeline";
52
- import OnCallDutyPolicy from "Common/Models/DatabaseModels/OnCallDutyPolicy";
53
43
  import OneUptimeDate from "Common/Types/Date";
54
44
  import LogMonitorCriteria from "./Criteria/LogMonitorCriteria";
55
45
  import LogMonitorResponse from "Common/Types/Monitor/LogMonitor/LogMonitorResponse";
56
46
  import TelemetryType from "Common/Types/Telemetry/TelemetryType";
57
47
  import TraceMonitorResponse from "../../../Types/Monitor/TraceMonitor/TraceMonitorResponse";
58
48
  import TraceMonitorCriteria from "./Criteria/TraceMonitorCriteria";
49
+ import { TelemetryQuery } from "../../../Types/Telemetry/TelemetryQuery";
50
+ import MonitorIncident from "./MonitorIncident";
51
+ import MonitorAlert from "./MonitorAlert";
52
+ import MonitorStatusTimelineUtil from "./MonitorStatusTimeline";
53
+ import Semaphore, { SemaphoreMutex } from "../../Infrastructure/Semaphore";
59
54
 
60
55
  export default class MonitorResourceUtil {
61
56
  public static async monitorResource(
62
57
  dataToProcess: DataToProcess,
63
58
  ): Promise<ProbeApiIngestResponse> {
59
+ let mutex: SemaphoreMutex | null = null;
60
+
61
+ try {
62
+ mutex = await Semaphore.lock({
63
+ key: dataToProcess.monitorId.toString(),
64
+ namespace: "MonitorResourceUtil.monitorResource",
65
+ });
66
+ } catch (err) {
67
+ logger.error(err);
68
+ }
69
+
64
70
  let response: ProbeApiIngestResponse = {
65
71
  monitorId: dataToProcess.monitorId,
66
72
  criteriaMetId: undefined,
@@ -284,7 +290,9 @@ export default class MonitorResourceUtil {
284
290
  const autoResolveCriteriaInstanceIdIncidentIdsDictionary: Dictionary<
285
291
  Array<string>
286
292
  > = {};
293
+
287
294
  const criteriaInstanceMap: Dictionary<MonitorCriteriaInstance> = {};
295
+
288
296
  for (const criteriaInstance of criteriaInstances) {
289
297
  criteriaInstanceMap[criteriaInstance.data?.id || ""] = criteriaInstance;
290
298
 
@@ -312,6 +320,42 @@ export default class MonitorResourceUtil {
312
320
  }
313
321
  }
314
322
 
323
+ // alerts.
324
+
325
+ const autoResolveCriteriaInstanceIdAlertIdsDictionary: Dictionary<
326
+ Array<string>
327
+ > = {};
328
+
329
+ const criteriaInstanceAlertMap: Dictionary<MonitorCriteriaInstance> = {};
330
+
331
+ for (const criteriaInstance of criteriaInstances) {
332
+ criteriaInstanceAlertMap[criteriaInstance.data?.id || ""] =
333
+ criteriaInstance;
334
+
335
+ if (
336
+ criteriaInstance.data?.alerts &&
337
+ criteriaInstance.data?.alerts.length > 0
338
+ ) {
339
+ for (const alertTemplate of criteriaInstance.data!.alerts) {
340
+ if (alertTemplate.autoResolveAlert) {
341
+ if (
342
+ !autoResolveCriteriaInstanceIdAlertIdsDictionary[
343
+ criteriaInstance.data.id.toString()
344
+ ]
345
+ ) {
346
+ autoResolveCriteriaInstanceIdAlertIdsDictionary[
347
+ criteriaInstance.data.id.toString()
348
+ ] = [];
349
+ }
350
+
351
+ autoResolveCriteriaInstanceIdAlertIdsDictionary[
352
+ criteriaInstance.data.id.toString()
353
+ ]?.push(alertTemplate.id);
354
+ }
355
+ }
356
+ }
357
+ }
358
+
315
359
  const monitorStep: MonitorStep | undefined =
316
360
  monitorSteps.data.monitorStepsInstanceArray[0];
317
361
 
@@ -376,7 +420,7 @@ export default class MonitorResourceUtil {
376
420
  }`,
377
421
  );
378
422
 
379
- let telemetryQuery: TelemetryIncidentQuery | undefined = undefined;
423
+ let telemetryQuery: TelemetryQuery | undefined = undefined;
380
424
 
381
425
  if (dataToProcess && (dataToProcess as LogMonitorResponse).logQuery) {
382
426
  telemetryQuery = {
@@ -398,7 +442,17 @@ export default class MonitorResourceUtil {
398
442
  );
399
443
  }
400
444
 
401
- await this.criteriaMetCreateIncidentsAndUpdateMonitorStatus({
445
+ await MonitorStatusTimelineUtil.updateMonitorStatusTimeline({
446
+ monitor: monitor,
447
+ rootCause: response.rootCause,
448
+ dataToProcess: dataToProcess,
449
+ criteriaInstance: criteriaInstanceMap[response.criteriaMetId!]!,
450
+ props: {
451
+ telemetryQuery: telemetryQuery,
452
+ },
453
+ });
454
+
455
+ await MonitorIncident.criteriaMetCreateIncidentsAndUpdateMonitorStatus({
402
456
  monitor: monitor,
403
457
  rootCause: response.rootCause,
404
458
  dataToProcess: dataToProcess,
@@ -408,6 +462,17 @@ export default class MonitorResourceUtil {
408
462
  telemetryQuery: telemetryQuery,
409
463
  },
410
464
  });
465
+
466
+ await MonitorAlert.criteriaMetCreateAlertsAndUpdateMonitorStatus({
467
+ monitor: monitor,
468
+ rootCause: response.rootCause,
469
+ dataToProcess: dataToProcess,
470
+ autoResolveCriteriaInstanceIdAlertIdsDictionary,
471
+ criteriaInstance: criteriaInstanceAlertMap[response.criteriaMetId!]!,
472
+ props: {
473
+ telemetryQuery: telemetryQuery,
474
+ },
475
+ });
411
476
  } else if (
412
477
  !response.criteriaMetId &&
413
478
  monitorSteps.data.defaultMonitorStatusId &&
@@ -418,7 +483,7 @@ export default class MonitorResourceUtil {
418
483
  `${dataToProcess.monitorId.toString()} - No criteria met. Change to default status.`,
419
484
  );
420
485
 
421
- await this.checkOpenIncidentsAndCloseIfResolved({
486
+ await MonitorIncident.checkOpenIncidentsAndCloseIfResolved({
422
487
  monitorId: monitor.id!,
423
488
  autoResolveCriteriaInstanceIdIncidentIdsDictionary,
424
489
  rootCause: "No monitoring criteria met. Change to default status.",
@@ -479,6 +544,14 @@ export default class MonitorResourceUtil {
479
544
  }
480
545
  }
481
546
 
547
+ if (mutex) {
548
+ try {
549
+ await Semaphore.release(mutex);
550
+ } catch (err) {
551
+ logger.error(err);
552
+ }
553
+ }
554
+
482
555
  return response;
483
556
  }
484
557
 
@@ -689,379 +762,6 @@ export default class MonitorResourceUtil {
689
762
  });
690
763
  }
691
764
 
692
- private static async checkOpenIncidentsAndCloseIfResolved(input: {
693
- monitorId: ObjectID;
694
- autoResolveCriteriaInstanceIdIncidentIdsDictionary: Dictionary<
695
- Array<string>
696
- >;
697
- rootCause: string;
698
- criteriaInstance: MonitorCriteriaInstance | null;
699
- dataToProcess: DataToProcess;
700
- }): Promise<Array<Incident>> {
701
- // check active incidents and if there are open incidents, do not cretae anothr incident.
702
- const openIncidents: Array<Incident> = await IncidentService.findBy({
703
- query: {
704
- monitors: [input.monitorId] as any,
705
- currentIncidentState: {
706
- isResolvedState: false,
707
- },
708
- },
709
- skip: 0,
710
- limit: LIMIT_PER_PROJECT,
711
- select: {
712
- _id: true,
713
- createdCriteriaId: true,
714
- createdIncidentTemplateId: true,
715
- projectId: true,
716
- },
717
- props: {
718
- isRoot: true,
719
- },
720
- });
721
-
722
- // check if should close the incident.
723
-
724
- for (const openIncident of openIncidents) {
725
- const shouldClose: boolean = MonitorResourceUtil.shouldCloseIncident({
726
- openIncident,
727
- autoResolveCriteriaInstanceIdIncidentIdsDictionary:
728
- input.autoResolveCriteriaInstanceIdIncidentIdsDictionary,
729
- criteriaInstance: input.criteriaInstance,
730
- });
731
-
732
- if (shouldClose) {
733
- // then resolve incident.
734
- await MonitorResourceUtil.resolveOpenIncident({
735
- openIncident: openIncident,
736
- rootCause: input.rootCause,
737
- dataToProcess: input.dataToProcess,
738
- });
739
- }
740
- }
741
-
742
- return openIncidents;
743
- }
744
-
745
- private static async criteriaMetCreateIncidentsAndUpdateMonitorStatus(input: {
746
- criteriaInstance: MonitorCriteriaInstance;
747
- monitor: Monitor;
748
- dataToProcess: DataToProcess;
749
- rootCause: string;
750
- autoResolveCriteriaInstanceIdIncidentIdsDictionary: Dictionary<
751
- Array<string>
752
- >;
753
- props: {
754
- telemetryQuery?: TelemetryIncidentQuery | undefined;
755
- };
756
- }): Promise<void> {
757
- // criteria filters are met, now process the actions.
758
-
759
- const lastMonitorStatusTimeline: MonitorStatusTimeline | null =
760
- await MonitorStatusTimelineService.findOneBy({
761
- query: {
762
- monitorId: input.monitor.id!,
763
- projectId: input.monitor.projectId!,
764
- },
765
- select: {
766
- _id: true,
767
- monitorStatusId: true,
768
- },
769
- sort: {
770
- startsAt: SortOrder.Descending,
771
- },
772
- props: {
773
- isRoot: true,
774
- },
775
- });
776
-
777
- let shouldUpdateStatus: boolean = false;
778
-
779
- if (!lastMonitorStatusTimeline) {
780
- // if monitor does not have any status timeline, then create one.
781
- shouldUpdateStatus = true;
782
- }
783
-
784
- if (
785
- input.criteriaInstance.data?.changeMonitorStatus &&
786
- input.criteriaInstance.data?.monitorStatusId &&
787
- input.criteriaInstance.data?.monitorStatusId.toString() !==
788
- lastMonitorStatusTimeline?.id?.toString()
789
- ) {
790
- // if monitor status is changed, then create a new status timeline.
791
- shouldUpdateStatus = true;
792
- }
793
-
794
- // check if the current status is same as the last status.
795
-
796
- if (
797
- input.criteriaInstance.data?.changeMonitorStatus &&
798
- input.criteriaInstance.data?.monitorStatusId &&
799
- input.criteriaInstance.data?.monitorStatusId.toString() !==
800
- input.monitor.currentMonitorStatusId?.toString()
801
- ) {
802
- // if monitor status is changed, then create a new status timeline.
803
- shouldUpdateStatus = true;
804
- }
805
-
806
- if (shouldUpdateStatus) {
807
- logger.debug(
808
- `${input.monitor.id?.toString()} - Change monitor status to ${input.criteriaInstance.data?.monitorStatusId?.toString()}`,
809
- );
810
- // change monitor status
811
-
812
- const monitorStatusId: ObjectID | undefined =
813
- input.criteriaInstance.data?.monitorStatusId;
814
-
815
- if (!monitorStatusId) {
816
- throw new BadDataException("Monitor status is not defined.");
817
- }
818
-
819
- //change monitor status.
820
-
821
- // get last status of this monitor.
822
-
823
- // get last monitor status timeline.
824
-
825
- if (
826
- lastMonitorStatusTimeline &&
827
- lastMonitorStatusTimeline.monitorStatusId &&
828
- lastMonitorStatusTimeline.monitorStatusId.toString() ===
829
- monitorStatusId.toString()
830
- ) {
831
- // status is same as last status. do not create new status timeline.
832
- return;
833
- }
834
-
835
- const monitorStatusTimeline: MonitorStatusTimeline =
836
- new MonitorStatusTimeline();
837
- monitorStatusTimeline.monitorId = input.monitor.id!;
838
- monitorStatusTimeline.monitorStatusId = monitorStatusId;
839
- monitorStatusTimeline.projectId = input.monitor.projectId!;
840
- monitorStatusTimeline.statusChangeLog = JSON.parse(
841
- JSON.stringify(input.dataToProcess),
842
- );
843
- monitorStatusTimeline.rootCause = input.rootCause;
844
-
845
- await MonitorStatusTimelineService.create({
846
- data: monitorStatusTimeline,
847
- props: {
848
- isRoot: true,
849
- },
850
- });
851
- }
852
-
853
- // check open incidents
854
- logger.debug(`${input.monitor.id?.toString()} - Check open incidents.`);
855
- // check active incidents and if there are open incidents, do not cretae anothr incident.
856
- const openIncidents: Array<Incident> =
857
- await this.checkOpenIncidentsAndCloseIfResolved({
858
- monitorId: input.monitor.id!,
859
- autoResolveCriteriaInstanceIdIncidentIdsDictionary:
860
- input.autoResolveCriteriaInstanceIdIncidentIdsDictionary,
861
- rootCause: input.rootCause,
862
- criteriaInstance: input.criteriaInstance,
863
- dataToProcess: input.dataToProcess,
864
- });
865
-
866
- if (input.criteriaInstance.data?.createIncidents) {
867
- // create incidents
868
-
869
- for (const criteriaIncident of input.criteriaInstance.data?.incidents ||
870
- []) {
871
- // should create incident.
872
-
873
- const alreadyOpenIncident: Incident | undefined = openIncidents.find(
874
- (incident: Incident) => {
875
- return (
876
- incident.createdCriteriaId ===
877
- input.criteriaInstance.data?.id.toString() &&
878
- incident.createdIncidentTemplateId ===
879
- criteriaIncident.id.toString()
880
- );
881
- },
882
- );
883
-
884
- const hasAlreadyOpenIncident: boolean = Boolean(alreadyOpenIncident);
885
-
886
- logger.debug(
887
- `${input.monitor.id?.toString()} - Open Incident ${alreadyOpenIncident?.id?.toString()}`,
888
- );
889
-
890
- logger.debug(
891
- `${input.monitor.id?.toString()} - Has open incident ${hasAlreadyOpenIncident}`,
892
- );
893
-
894
- if (hasAlreadyOpenIncident) {
895
- continue;
896
- }
897
-
898
- // create incident here.
899
-
900
- logger.debug(`${input.monitor.id?.toString()} - Create incident.`);
901
-
902
- const incident: Incident = new Incident();
903
-
904
- incident.title = criteriaIncident.title;
905
- incident.description = criteriaIncident.description;
906
-
907
- if (!criteriaIncident.incidentSeverityId) {
908
- // pick the critical criteria.
909
-
910
- const severity: IncidentSeverity | null =
911
- await IncidentSeverityService.findOneBy({
912
- query: {
913
- projectId: input.monitor.projectId!,
914
- },
915
- sort: {
916
- order: SortOrder.Ascending,
917
- },
918
- props: {
919
- isRoot: true,
920
- },
921
- select: {
922
- _id: true,
923
- },
924
- });
925
-
926
- if (!severity) {
927
- throw new BadDataException(
928
- "Project does not have incident severity",
929
- );
930
- } else {
931
- incident.incidentSeverityId = severity.id!;
932
- }
933
- } else {
934
- incident.incidentSeverityId = criteriaIncident.incidentSeverityId!;
935
- }
936
-
937
- incident.monitors = [input.monitor];
938
- incident.projectId = input.monitor.projectId!;
939
- incident.rootCause = input.rootCause;
940
- incident.createdStateLog = JSON.parse(
941
- JSON.stringify(input.dataToProcess, null, 2),
942
- );
943
-
944
- incident.createdCriteriaId = input.criteriaInstance.data.id.toString();
945
-
946
- incident.createdIncidentTemplateId = criteriaIncident.id.toString();
947
-
948
- incident.onCallDutyPolicies =
949
- criteriaIncident.onCallPolicyIds?.map((id: ObjectID) => {
950
- const onCallPolicy: OnCallDutyPolicy = new OnCallDutyPolicy();
951
- onCallPolicy._id = id.toString();
952
- return onCallPolicy;
953
- }) || [];
954
-
955
- incident.isCreatedAutomatically = true;
956
-
957
- if (input.props.telemetryQuery) {
958
- incident.telemetryQuery = input.props.telemetryQuery;
959
- }
960
-
961
- if (
962
- input.dataToProcess &&
963
- (input.dataToProcess as ProbeMonitorResponse).probeId
964
- ) {
965
- incident.createdByProbeId = (
966
- input.dataToProcess as ProbeMonitorResponse
967
- ).probeId;
968
- }
969
-
970
- if (criteriaIncident.remediationNotes) {
971
- incident.remediationNotes = criteriaIncident.remediationNotes;
972
- }
973
-
974
- await IncidentService.create({
975
- data: incident,
976
- props: {
977
- isRoot: true,
978
- },
979
- });
980
- }
981
- }
982
- }
983
-
984
- private static async resolveOpenIncident(input: {
985
- openIncident: Incident;
986
- rootCause: string;
987
- dataToProcess:
988
- | ProbeMonitorResponse
989
- | IncomingMonitorRequest
990
- | DataToProcess;
991
- }): Promise<void> {
992
- const resolvedStateId: ObjectID =
993
- await IncidentStateTimelineService.getResolvedStateIdForProject(
994
- input.openIncident.projectId!,
995
- );
996
-
997
- const incidentStateTimeline: IncidentStateTimeline =
998
- new IncidentStateTimeline();
999
- incidentStateTimeline.incidentId = input.openIncident.id!;
1000
- incidentStateTimeline.incidentStateId = resolvedStateId;
1001
- incidentStateTimeline.projectId = input.openIncident.projectId!;
1002
-
1003
- if (input.rootCause) {
1004
- incidentStateTimeline.rootCause =
1005
- "Incident autoresolved because autoresolve is set to true in monitor criteria. " +
1006
- input.rootCause;
1007
- }
1008
-
1009
- if (input.dataToProcess) {
1010
- incidentStateTimeline.stateChangeLog = JSON.parse(
1011
- JSON.stringify(input.dataToProcess),
1012
- );
1013
- }
1014
-
1015
- await IncidentStateTimelineService.create({
1016
- data: incidentStateTimeline,
1017
- props: {
1018
- isRoot: true,
1019
- },
1020
- });
1021
- }
1022
-
1023
- private static shouldCloseIncident(input: {
1024
- openIncident: Incident;
1025
- autoResolveCriteriaInstanceIdIncidentIdsDictionary: Dictionary<
1026
- Array<string>
1027
- >;
1028
- criteriaInstance: MonitorCriteriaInstance | null; // null if no criteia met.
1029
- }): boolean {
1030
- if (
1031
- input.openIncident.createdCriteriaId?.toString() ===
1032
- input.criteriaInstance?.data?.id.toString()
1033
- ) {
1034
- // same incident active. So, do not close.
1035
- return false;
1036
- }
1037
-
1038
- // If antoher criteria is active then, check if the incident id is present in the map.
1039
-
1040
- if (!input.openIncident.createdCriteriaId?.toString()) {
1041
- return false;
1042
- }
1043
-
1044
- if (!input.openIncident.createdIncidentTemplateId?.toString()) {
1045
- return false;
1046
- }
1047
-
1048
- if (
1049
- input.autoResolveCriteriaInstanceIdIncidentIdsDictionary[
1050
- input.openIncident.createdCriteriaId?.toString()
1051
- ]
1052
- ) {
1053
- if (
1054
- input.autoResolveCriteriaInstanceIdIncidentIdsDictionary[
1055
- input.openIncident.createdCriteriaId?.toString()
1056
- ]?.includes(input.openIncident.createdIncidentTemplateId?.toString())
1057
- ) {
1058
- return true;
1059
- }
1060
- }
1061
-
1062
- return false;
1063
- }
1064
-
1065
765
  private static async processMonitorStep(input: {
1066
766
  dataToProcess: DataToProcess;
1067
767
  monitorStep: MonitorStep;
@@ -1091,7 +791,7 @@ export default class MonitorResourceUtil {
1091
791
  if (rootCause) {
1092
792
  input.probeApiIngestResponse.criteriaMetId = criteriaInstance.data?.id;
1093
793
  input.probeApiIngestResponse.rootCause = `
1094
- **This incident is created because the following criteria was met**:
794
+ **Created because the following criteria was met**:
1095
795
 
1096
796
  **Criteria Name**: ${criteriaInstance.data?.name}
1097
797
  `;
@@ -0,0 +1,120 @@
1
+ import Monitor from "../../../Models/DatabaseModels/Monitor";
2
+ import MonitorStatusTimeline from "../../../Models/DatabaseModels/MonitorStatusTimeline";
3
+ import SortOrder from "../../../Types/BaseDatabase/SortOrder";
4
+ import BadDataException from "../../../Types/Exception/BadDataException";
5
+ import MonitorCriteriaInstance from "../../../Types/Monitor/MonitorCriteriaInstance";
6
+ import ObjectID from "../../../Types/ObjectID";
7
+ import { TelemetryQuery } from "../../../Types/Telemetry/TelemetryQuery";
8
+ import MonitorStatusTimelineService from "../../Services/MonitorStatusTimelineService";
9
+ import logger from "../Logger";
10
+ import DataToProcess from "./DataToProcess";
11
+
12
+ export default class MonitorStatusTimelineUtil {
13
+ public static async updateMonitorStatusTimeline(input: {
14
+ criteriaInstance: MonitorCriteriaInstance;
15
+ monitor: Monitor;
16
+ dataToProcess: DataToProcess;
17
+ rootCause: string;
18
+ props: {
19
+ telemetryQuery?: TelemetryQuery | undefined;
20
+ };
21
+ }): Promise<MonitorStatusTimeline | null> {
22
+ // criteria filters are met, now process the actions.
23
+
24
+ const lastMonitorStatusTimeline: MonitorStatusTimeline | null =
25
+ await MonitorStatusTimelineService.findOneBy({
26
+ query: {
27
+ monitorId: input.monitor.id!,
28
+ projectId: input.monitor.projectId!,
29
+ },
30
+ select: {
31
+ _id: true,
32
+ monitorStatusId: true,
33
+ },
34
+ sort: {
35
+ startsAt: SortOrder.Descending,
36
+ },
37
+ props: {
38
+ isRoot: true,
39
+ },
40
+ });
41
+
42
+ let shouldUpdateStatus: boolean = false;
43
+
44
+ if (!lastMonitorStatusTimeline) {
45
+ // if monitor does not have any status timeline, then create one.
46
+ shouldUpdateStatus = true;
47
+ }
48
+
49
+ if (
50
+ input.criteriaInstance.data?.changeMonitorStatus &&
51
+ input.criteriaInstance.data?.monitorStatusId &&
52
+ input.criteriaInstance.data?.monitorStatusId.toString() !==
53
+ lastMonitorStatusTimeline?.id?.toString()
54
+ ) {
55
+ // if monitor status is changed, then create a new status timeline.
56
+ shouldUpdateStatus = true;
57
+ }
58
+
59
+ // check if the current status is same as the last status.
60
+
61
+ if (
62
+ input.criteriaInstance.data?.changeMonitorStatus &&
63
+ input.criteriaInstance.data?.monitorStatusId &&
64
+ input.criteriaInstance.data?.monitorStatusId.toString() !==
65
+ input.monitor.currentMonitorStatusId?.toString()
66
+ ) {
67
+ // if monitor status is changed, then create a new status timeline.
68
+ shouldUpdateStatus = true;
69
+ }
70
+
71
+ if (shouldUpdateStatus) {
72
+ logger.debug(
73
+ `${input.monitor.id?.toString()} - Change monitor status to ${input.criteriaInstance.data?.monitorStatusId?.toString()}`,
74
+ );
75
+ // change monitor status
76
+
77
+ const monitorStatusId: ObjectID | undefined =
78
+ input.criteriaInstance.data?.monitorStatusId;
79
+
80
+ if (!monitorStatusId) {
81
+ throw new BadDataException("Monitor status is not defined.");
82
+ }
83
+
84
+ //change monitor status.
85
+
86
+ // get last status of this monitor.
87
+
88
+ // get last monitor status timeline.
89
+
90
+ if (
91
+ lastMonitorStatusTimeline &&
92
+ lastMonitorStatusTimeline.monitorStatusId &&
93
+ lastMonitorStatusTimeline.monitorStatusId.toString() ===
94
+ monitorStatusId.toString()
95
+ ) {
96
+ // status is same as last status. do not create new status timeline.
97
+ return null;
98
+ }
99
+
100
+ const monitorStatusTimeline: MonitorStatusTimeline =
101
+ new MonitorStatusTimeline();
102
+ monitorStatusTimeline.monitorId = input.monitor.id!;
103
+ monitorStatusTimeline.monitorStatusId = monitorStatusId;
104
+ monitorStatusTimeline.projectId = input.monitor.projectId!;
105
+ monitorStatusTimeline.statusChangeLog = JSON.parse(
106
+ JSON.stringify(input.dataToProcess),
107
+ );
108
+ monitorStatusTimeline.rootCause = input.rootCause;
109
+
110
+ return await MonitorStatusTimelineService.create({
111
+ data: monitorStatusTimeline,
112
+ props: {
113
+ isRoot: true,
114
+ },
115
+ });
116
+ }
117
+
118
+ return null;
119
+ }
120
+ }