@oneuptime/common 7.0.3148 → 7.0.3153

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 (222) 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/Services/AlertCustomFieldService.ts +9 -0
  18. package/Server/Services/AlertInternalNoteService.ts +10 -0
  19. package/Server/Services/AlertNoteTemplateService.ts +9 -0
  20. package/Server/Services/AlertOwnerTeamService.ts +10 -0
  21. package/Server/Services/AlertOwnerUserService.ts +10 -0
  22. package/Server/Services/AlertService.ts +568 -0
  23. package/Server/Services/AlertSeverityService.ts +154 -0
  24. package/Server/Services/AlertStateService.ts +227 -0
  25. package/Server/Services/AlertStateTimelineService.ts +334 -0
  26. package/Server/Services/CallLogService.ts +4 -1
  27. package/Server/Services/DatabaseService.ts +17 -20
  28. package/Server/Services/EmailLogService.ts +4 -1
  29. package/Server/Services/IncidentService.ts +4 -1
  30. package/Server/Services/IncidentStateTimelineService.ts +4 -1
  31. package/Server/Services/Index.ts +23 -0
  32. package/Server/Services/MonitorStatusTimelineService.ts +4 -1
  33. package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +4 -1
  34. package/Server/Services/OnCallDutyPolicyService.ts +15 -0
  35. package/Server/Services/ProjectService.ts +99 -1
  36. package/Server/Services/ScheduledMaintenanceService.ts +4 -1
  37. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +4 -1
  38. package/Server/Services/ShortLinkService.ts +4 -1
  39. package/Server/Services/SmsLogService.ts +4 -1
  40. package/Server/Services/TableViewService.ts +10 -0
  41. package/Server/Services/TelemetryUsageBillingService.ts +4 -1
  42. package/Server/Services/UserNotificationSettingService.ts +58 -0
  43. package/Server/Services/UserOnCallLogService.ts +4 -1
  44. package/Server/Services/WorkflowLogService.ts +4 -1
  45. package/Server/Types/Workflow/Components/API/Post.ts +25 -0
  46. package/Server/Utils/Monitor/MonitorAlert.ts +273 -0
  47. package/Server/Utils/Monitor/MonitorIncident.ts +298 -0
  48. package/Server/Utils/Monitor/MonitorResource.ts +67 -387
  49. package/Server/Utils/Monitor/MonitorStatusTimeline.ts +120 -0
  50. package/Server/Utils/Realtime.ts +1 -35
  51. package/Types/Email/EmailTemplateType.ts +7 -0
  52. package/Types/Icon/IconProp.ts +1 -0
  53. package/Types/Monitor/CriteriaAlert.ts +11 -0
  54. package/Types/Monitor/MonitorCriteria.ts +2 -0
  55. package/Types/Monitor/MonitorCriteriaInstance.ts +134 -1
  56. package/Types/Monitor/MonitorStep.ts +1 -0
  57. package/Types/Monitor/MonitorSteps.ts +1 -0
  58. package/Types/NotificationSetting/NotificationSettingEventType.ts +7 -0
  59. package/Types/Permission.ts +369 -1
  60. package/Types/Telemetry/TelemetryQuery.ts +10 -0
  61. package/Types/UserNotification/UserNotificationEventType.ts +1 -0
  62. package/UI/Components/Card/Card.tsx +40 -31
  63. package/UI/Components/Card/CardButtons/MoreButton.ts +15 -0
  64. package/UI/Components/HeaderAlert/HeaderAlert.tsx +75 -16
  65. package/UI/Components/HeaderAlert/HeaderAlertGroup.tsx +50 -0
  66. package/UI/Components/HeaderAlert/HeaderModelAlert.tsx +5 -1
  67. package/UI/Components/Icon/Icon.tsx +8 -0
  68. package/UI/Components/ModelDetail/CardModelDetail.tsx +4 -2
  69. package/UI/Components/ModelTable/BaseModelTable.tsx +70 -2
  70. package/UI/Components/ModelTable/TableView.tsx +317 -0
  71. package/UI/Components/MoreMenu/Divider.tsx +7 -0
  72. package/UI/Components/MoreMenu/MoreMenu.tsx +54 -0
  73. package/UI/Components/MoreMenu/MoreMenuItem.tsx +37 -0
  74. package/UI/Components/MoreMenu/MoreMenuSection.tsx +22 -0
  75. package/UI/Components/Toggle/Toggle.tsx +14 -0
  76. package/build/dist/Models/DatabaseModels/Alert.js +1028 -0
  77. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -0
  78. package/build/dist/Models/DatabaseModels/AlertCustomField.js +360 -0
  79. package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -0
  80. package/build/dist/Models/DatabaseModels/AlertInternalNote.js +391 -0
  81. package/build/dist/Models/DatabaseModels/AlertInternalNote.js.map +1 -0
  82. package/build/dist/Models/DatabaseModels/AlertNoteTemplate.js +372 -0
  83. package/build/dist/Models/DatabaseModels/AlertNoteTemplate.js.map +1 -0
  84. package/build/dist/Models/DatabaseModels/AlertOwnerTeam.js +434 -0
  85. package/build/dist/Models/DatabaseModels/AlertOwnerTeam.js.map +1 -0
  86. package/build/dist/Models/DatabaseModels/AlertOwnerUser.js +433 -0
  87. package/build/dist/Models/DatabaseModels/AlertOwnerUser.js.map +1 -0
  88. package/build/dist/Models/DatabaseModels/AlertSeverity.js +450 -0
  89. package/build/dist/Models/DatabaseModels/AlertSeverity.js.map +1 -0
  90. package/build/dist/Models/DatabaseModels/AlertState.js +530 -0
  91. package/build/dist/Models/DatabaseModels/AlertState.js.map +1 -0
  92. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +548 -0
  93. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -0
  94. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  95. package/build/dist/Models/DatabaseModels/Index.js +29 -9
  96. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  97. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js +55 -0
  98. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js.map +1 -1
  99. package/build/dist/Models/DatabaseModels/TableView.js +475 -0
  100. package/build/dist/Models/DatabaseModels/TableView.js.map +1 -0
  101. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1727894983857-MigrationName.js +24 -0
  102. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1727894983857-MigrationName.js.map +1 -0
  103. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1727906598804-MigrationName.js +198 -0
  104. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1727906598804-MigrationName.js.map +1 -0
  105. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  106. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  107. package/build/dist/Server/Services/AlertCustomFieldService.js +9 -0
  108. package/build/dist/Server/Services/AlertCustomFieldService.js.map +1 -0
  109. package/build/dist/Server/Services/AlertInternalNoteService.js +9 -0
  110. package/build/dist/Server/Services/AlertInternalNoteService.js.map +1 -0
  111. package/build/dist/Server/Services/AlertNoteTemplateService.js +9 -0
  112. package/build/dist/Server/Services/AlertNoteTemplateService.js.map +1 -0
  113. package/build/dist/Server/Services/AlertOwnerTeamService.js +9 -0
  114. package/build/dist/Server/Services/AlertOwnerTeamService.js.map +1 -0
  115. package/build/dist/Server/Services/AlertOwnerUserService.js +9 -0
  116. package/build/dist/Server/Services/AlertOwnerUserService.js.map +1 -0
  117. package/build/dist/Server/Services/AlertService.js +418 -0
  118. package/build/dist/Server/Services/AlertService.js.map +1 -0
  119. package/build/dist/Server/Services/AlertSeverityService.js +108 -0
  120. package/build/dist/Server/Services/AlertSeverityService.js.map +1 -0
  121. package/build/dist/Server/Services/AlertStateService.js +158 -0
  122. package/build/dist/Server/Services/AlertStateService.js.map +1 -0
  123. package/build/dist/Server/Services/AlertStateTimelineService.js +267 -0
  124. package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -0
  125. package/build/dist/Server/Services/CallLogService.js +4 -1
  126. package/build/dist/Server/Services/CallLogService.js.map +1 -1
  127. package/build/dist/Server/Services/DatabaseService.js +9 -9
  128. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  129. package/build/dist/Server/Services/EmailLogService.js +4 -1
  130. package/build/dist/Server/Services/EmailLogService.js.map +1 -1
  131. package/build/dist/Server/Services/IncidentService.js +4 -1
  132. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  133. package/build/dist/Server/Services/IncidentStateTimelineService.js +4 -1
  134. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  135. package/build/dist/Server/Services/Index.js +21 -0
  136. package/build/dist/Server/Services/Index.js.map +1 -1
  137. package/build/dist/Server/Services/MonitorStatusTimelineService.js +4 -1
  138. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  139. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +4 -1
  140. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
  141. package/build/dist/Server/Services/OnCallDutyPolicyService.js +8 -0
  142. package/build/dist/Server/Services/OnCallDutyPolicyService.js.map +1 -1
  143. package/build/dist/Server/Services/ProjectService.js +80 -1
  144. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  145. package/build/dist/Server/Services/ScheduledMaintenanceService.js +4 -1
  146. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  147. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +4 -1
  148. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  149. package/build/dist/Server/Services/ShortLinkService.js +4 -1
  150. package/build/dist/Server/Services/ShortLinkService.js.map +1 -1
  151. package/build/dist/Server/Services/SmsLogService.js +4 -1
  152. package/build/dist/Server/Services/SmsLogService.js.map +1 -1
  153. package/build/dist/Server/Services/TableViewService.js +9 -0
  154. package/build/dist/Server/Services/TableViewService.js.map +1 -0
  155. package/build/dist/Server/Services/TelemetryUsageBillingService.js +4 -1
  156. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  157. package/build/dist/Server/Services/UserNotificationSettingService.js +49 -0
  158. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  159. package/build/dist/Server/Services/UserOnCallLogService.js +4 -1
  160. package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
  161. package/build/dist/Server/Services/WorkflowLogService.js +4 -1
  162. package/build/dist/Server/Services/WorkflowLogService.js.map +1 -1
  163. package/build/dist/Server/Types/Workflow/Components/API/Post.js +14 -0
  164. package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
  165. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +177 -0
  166. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -0
  167. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +187 -0
  168. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -0
  169. package/build/dist/Server/Utils/Monitor/MonitorResource.js +46 -254
  170. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  171. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js +79 -0
  172. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js.map +1 -0
  173. package/build/dist/Server/Utils/Realtime.js +3 -28
  174. package/build/dist/Server/Utils/Realtime.js.map +1 -1
  175. package/build/dist/Types/Email/EmailTemplateType.js +4 -0
  176. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  177. package/build/dist/Types/Icon/IconProp.js +1 -0
  178. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  179. package/build/dist/Types/Monitor/CriteriaAlert.js +2 -0
  180. package/build/dist/Types/Monitor/CriteriaAlert.js.map +1 -0
  181. package/build/dist/Types/Monitor/MonitorCriteria.js +1 -0
  182. package/build/dist/Types/Monitor/MonitorCriteria.js.map +1 -1
  183. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +120 -1
  184. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  185. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  186. package/build/dist/Types/Monitor/MonitorSteps.js.map +1 -1
  187. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +5 -0
  188. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
  189. package/build/dist/Types/Permission.js +323 -1
  190. package/build/dist/Types/Permission.js.map +1 -1
  191. package/build/dist/Types/Telemetry/TelemetryQuery.js +2 -0
  192. package/build/dist/Types/Telemetry/TelemetryQuery.js.map +1 -0
  193. package/build/dist/Types/UserNotification/UserNotificationEventType.js +1 -0
  194. package/build/dist/Types/UserNotification/UserNotificationEventType.js.map +1 -1
  195. package/build/dist/UI/Components/Card/Card.js +3 -2
  196. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  197. package/build/dist/UI/Components/Card/CardButtons/MoreButton.js +12 -0
  198. package/build/dist/UI/Components/Card/CardButtons/MoreButton.js.map +1 -0
  199. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js +53 -9
  200. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js.map +1 -1
  201. package/build/dist/UI/Components/HeaderAlert/HeaderAlertGroup.js +25 -0
  202. package/build/dist/UI/Components/HeaderAlert/HeaderAlertGroup.js.map +1 -0
  203. package/build/dist/UI/Components/HeaderAlert/HeaderModelAlert.js +1 -1
  204. package/build/dist/UI/Components/HeaderAlert/HeaderModelAlert.js.map +1 -1
  205. package/build/dist/UI/Components/Icon/Icon.js +3 -0
  206. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  207. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  208. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +46 -0
  209. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  210. package/build/dist/UI/Components/ModelTable/TableView.js +183 -0
  211. package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -0
  212. package/build/dist/UI/Components/MoreMenu/Divider.js +6 -0
  213. package/build/dist/UI/Components/MoreMenu/Divider.js.map +1 -0
  214. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +19 -0
  215. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -0
  216. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +13 -0
  217. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -0
  218. package/build/dist/UI/Components/MoreMenu/MoreMenuSection.js +10 -0
  219. package/build/dist/UI/Components/MoreMenu/MoreMenuSection.js.map +1 -0
  220. package/build/dist/UI/Components/Toggle/Toggle.js +7 -1
  221. package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
  222. package/package.json +2 -2
@@ -0,0 +1,273 @@
1
+ import Alert from "../../../Models/DatabaseModels/Alert";
2
+ import AlertSeverity from "../../../Models/DatabaseModels/AlertSeverity";
3
+ import AlertStateTimeline from "../../../Models/DatabaseModels/AlertStateTimeline";
4
+ import Monitor from "../../../Models/DatabaseModels/Monitor";
5
+ import OnCallDutyPolicy from "../../../Models/DatabaseModels/OnCallDutyPolicy";
6
+ import SortOrder from "../../../Types/BaseDatabase/SortOrder";
7
+ import { LIMIT_PER_PROJECT } from "../../../Types/Database/LimitMax";
8
+ import Dictionary from "../../../Types/Dictionary";
9
+ import BadDataException from "../../../Types/Exception/BadDataException";
10
+ import IncomingMonitorRequest from "../../../Types/Monitor/IncomingMonitor/IncomingMonitorRequest";
11
+ import MonitorCriteriaInstance from "../../../Types/Monitor/MonitorCriteriaInstance";
12
+ import ObjectID from "../../../Types/ObjectID";
13
+ import ProbeMonitorResponse from "../../../Types/Probe/ProbeMonitorResponse";
14
+ import { TelemetryQuery } from "../../../Types/Telemetry/TelemetryQuery";
15
+ import AlertService from "../../Services/AlertService";
16
+ import AlertSeverityService from "../../Services/AlertSeverityService";
17
+ import AlertStateTimelineService from "../../Services/AlertStateTimelineService";
18
+ import logger from "../Logger";
19
+ import DataToProcess from "./DataToProcess";
20
+
21
+ export default class MonitorAlert {
22
+ public static async checkOpenAlertsAndCloseIfResolved(input: {
23
+ monitorId: ObjectID;
24
+ autoResolveCriteriaInstanceIdAlertIdsDictionary: Dictionary<Array<string>>;
25
+ rootCause: string;
26
+ criteriaInstance: MonitorCriteriaInstance | null;
27
+ dataToProcess: DataToProcess;
28
+ }): Promise<Array<Alert>> {
29
+ // check active alerts and if there are open alerts, do not cretae anothr alert.
30
+ const openAlerts: Array<Alert> = await AlertService.findBy({
31
+ query: {
32
+ monitor: input.monitorId!,
33
+ currentAlertState: {
34
+ isResolvedState: false,
35
+ },
36
+ },
37
+ skip: 0,
38
+ limit: LIMIT_PER_PROJECT,
39
+ select: {
40
+ _id: true,
41
+ createdCriteriaId: true,
42
+ projectId: true,
43
+ },
44
+ props: {
45
+ isRoot: true,
46
+ },
47
+ });
48
+
49
+ // check if should close the alert.
50
+
51
+ for (const openAlert of openAlerts) {
52
+ const shouldClose: boolean = this.shouldCloseAlert({
53
+ openAlert,
54
+ autoResolveCriteriaInstanceIdAlertIdsDictionary:
55
+ input.autoResolveCriteriaInstanceIdAlertIdsDictionary,
56
+ criteriaInstance: input.criteriaInstance,
57
+ });
58
+
59
+ if (shouldClose) {
60
+ // then resolve alert.
61
+ await this.resolveOpenAlert({
62
+ openAlert: openAlert,
63
+ rootCause: input.rootCause,
64
+ dataToProcess: input.dataToProcess,
65
+ });
66
+ }
67
+ }
68
+
69
+ return openAlerts;
70
+ }
71
+
72
+ public static async criteriaMetCreateAlertsAndUpdateMonitorStatus(input: {
73
+ criteriaInstance: MonitorCriteriaInstance;
74
+ monitor: Monitor;
75
+ dataToProcess: DataToProcess;
76
+ rootCause: string;
77
+ autoResolveCriteriaInstanceIdAlertIdsDictionary: Dictionary<Array<string>>;
78
+ props: {
79
+ telemetryQuery?: TelemetryQuery | undefined;
80
+ };
81
+ }): Promise<void> {
82
+ // check open alerts
83
+ logger.debug(`${input.monitor.id?.toString()} - Check open alerts.`);
84
+ // check active alerts and if there are open alerts, do not cretae anothr alert.
85
+ const openAlerts: Array<Alert> =
86
+ await this.checkOpenAlertsAndCloseIfResolved({
87
+ monitorId: input.monitor.id!,
88
+ autoResolveCriteriaInstanceIdAlertIdsDictionary:
89
+ input.autoResolveCriteriaInstanceIdAlertIdsDictionary,
90
+ rootCause: input.rootCause,
91
+ criteriaInstance: input.criteriaInstance,
92
+ dataToProcess: input.dataToProcess,
93
+ });
94
+
95
+ if (input.criteriaInstance.data?.createAlerts) {
96
+ // create alerts
97
+
98
+ for (const criteriaAlert of input.criteriaInstance.data?.alerts || []) {
99
+ // should create alert.
100
+
101
+ const alreadyOpenAlert: Alert | undefined = openAlerts.find(
102
+ (alert: Alert) => {
103
+ return (
104
+ alert.createdCriteriaId ===
105
+ input.criteriaInstance.data?.id.toString()
106
+ );
107
+ },
108
+ );
109
+
110
+ const hasAlreadyOpenAlert: boolean = Boolean(alreadyOpenAlert);
111
+
112
+ logger.debug(
113
+ `${input.monitor.id?.toString()} - Open Alert ${alreadyOpenAlert?.id?.toString()}`,
114
+ );
115
+
116
+ logger.debug(
117
+ `${input.monitor.id?.toString()} - Has open alert ${hasAlreadyOpenAlert}`,
118
+ );
119
+
120
+ if (hasAlreadyOpenAlert) {
121
+ continue;
122
+ }
123
+
124
+ // create alert here.
125
+
126
+ logger.debug(`${input.monitor.id?.toString()} - Create alert.`);
127
+
128
+ const alert: Alert = new Alert();
129
+
130
+ alert.title = criteriaAlert.title;
131
+ alert.description = criteriaAlert.description;
132
+
133
+ if (!criteriaAlert.alertSeverityId) {
134
+ // pick the critical criteria.
135
+
136
+ const severity: AlertSeverity | null =
137
+ await AlertSeverityService.findOneBy({
138
+ query: {
139
+ projectId: input.monitor.projectId!,
140
+ },
141
+ sort: {
142
+ order: SortOrder.Ascending,
143
+ },
144
+ props: {
145
+ isRoot: true,
146
+ },
147
+ select: {
148
+ _id: true,
149
+ },
150
+ });
151
+
152
+ if (!severity) {
153
+ throw new BadDataException("Project does not have alert severity");
154
+ } else {
155
+ alert.alertSeverityId = severity.id!;
156
+ }
157
+ } else {
158
+ alert.alertSeverityId = criteriaAlert.alertSeverityId!;
159
+ }
160
+
161
+ alert.monitor = input.monitor;
162
+ alert.projectId = input.monitor.projectId!;
163
+ alert.rootCause = input.rootCause;
164
+ alert.createdStateLog = JSON.parse(
165
+ JSON.stringify(input.dataToProcess, null, 2),
166
+ );
167
+
168
+ alert.createdCriteriaId = input.criteriaInstance.data.id.toString();
169
+
170
+ alert.onCallDutyPolicies =
171
+ criteriaAlert.onCallPolicyIds?.map((id: ObjectID) => {
172
+ const onCallPolicy: OnCallDutyPolicy = new OnCallDutyPolicy();
173
+ onCallPolicy._id = id.toString();
174
+ return onCallPolicy;
175
+ }) || [];
176
+
177
+ alert.isCreatedAutomatically = true;
178
+
179
+ if (input.props.telemetryQuery) {
180
+ alert.telemetryQuery = input.props.telemetryQuery;
181
+ }
182
+
183
+ if (
184
+ input.dataToProcess &&
185
+ (input.dataToProcess as ProbeMonitorResponse).probeId
186
+ ) {
187
+ alert.createdByProbeId = (
188
+ input.dataToProcess as ProbeMonitorResponse
189
+ ).probeId;
190
+ }
191
+
192
+ if (criteriaAlert.remediationNotes) {
193
+ alert.remediationNotes = criteriaAlert.remediationNotes;
194
+ }
195
+
196
+ await AlertService.create({
197
+ data: alert,
198
+ props: {
199
+ isRoot: true,
200
+ },
201
+ });
202
+ }
203
+ }
204
+ }
205
+
206
+ private static async resolveOpenAlert(input: {
207
+ openAlert: Alert;
208
+ rootCause: string;
209
+ dataToProcess:
210
+ | ProbeMonitorResponse
211
+ | IncomingMonitorRequest
212
+ | DataToProcess;
213
+ }): Promise<void> {
214
+ const resolvedStateId: ObjectID =
215
+ await AlertStateTimelineService.getResolvedStateIdForProject(
216
+ input.openAlert.projectId!,
217
+ );
218
+
219
+ const alertStateTimeline: AlertStateTimeline = new AlertStateTimeline();
220
+ alertStateTimeline.alertId = input.openAlert.id!;
221
+ alertStateTimeline.alertStateId = resolvedStateId;
222
+ alertStateTimeline.projectId = input.openAlert.projectId!;
223
+
224
+ if (input.rootCause) {
225
+ alertStateTimeline.rootCause =
226
+ "Alert autoresolved because autoresolve is set to true in monitor criteria. " +
227
+ input.rootCause;
228
+ }
229
+
230
+ if (input.dataToProcess) {
231
+ alertStateTimeline.stateChangeLog = JSON.parse(
232
+ JSON.stringify(input.dataToProcess),
233
+ );
234
+ }
235
+
236
+ await AlertStateTimelineService.create({
237
+ data: alertStateTimeline,
238
+ props: {
239
+ isRoot: true,
240
+ },
241
+ });
242
+ }
243
+
244
+ private static shouldCloseAlert(input: {
245
+ openAlert: Alert;
246
+ autoResolveCriteriaInstanceIdAlertIdsDictionary: Dictionary<Array<string>>;
247
+ criteriaInstance: MonitorCriteriaInstance | null; // null if no criteia met.
248
+ }): boolean {
249
+ if (
250
+ input.openAlert.createdCriteriaId?.toString() ===
251
+ input.criteriaInstance?.data?.id.toString()
252
+ ) {
253
+ // same alert active. So, do not close.
254
+ return false;
255
+ }
256
+
257
+ // If antoher criteria is active then, check if the alert id is present in the map.
258
+
259
+ if (!input.openAlert.createdCriteriaId?.toString()) {
260
+ return false;
261
+ }
262
+
263
+ if (
264
+ input.autoResolveCriteriaInstanceIdAlertIdsDictionary[
265
+ input.openAlert.createdCriteriaId?.toString()
266
+ ]
267
+ ) {
268
+ return true;
269
+ }
270
+
271
+ return false;
272
+ }
273
+ }
@@ -0,0 +1,298 @@
1
+ import Incident from "../../../Models/DatabaseModels/Incident";
2
+ import IncidentSeverity from "../../../Models/DatabaseModels/IncidentSeverity";
3
+ import IncidentStateTimeline from "../../../Models/DatabaseModels/IncidentStateTimeline";
4
+ import Monitor from "../../../Models/DatabaseModels/Monitor";
5
+ import OnCallDutyPolicy from "../../../Models/DatabaseModels/OnCallDutyPolicy";
6
+ import SortOrder from "../../../Types/BaseDatabase/SortOrder";
7
+ import { LIMIT_PER_PROJECT } from "../../../Types/Database/LimitMax";
8
+ import Dictionary from "../../../Types/Dictionary";
9
+ import BadDataException from "../../../Types/Exception/BadDataException";
10
+ import IncomingMonitorRequest from "../../../Types/Monitor/IncomingMonitor/IncomingMonitorRequest";
11
+ import MonitorCriteriaInstance from "../../../Types/Monitor/MonitorCriteriaInstance";
12
+ import ObjectID from "../../../Types/ObjectID";
13
+ import ProbeMonitorResponse from "../../../Types/Probe/ProbeMonitorResponse";
14
+ import { TelemetryQuery } from "../../../Types/Telemetry/TelemetryQuery";
15
+ import IncidentService from "../../Services/IncidentService";
16
+ import IncidentSeverityService from "../../Services/IncidentSeverityService";
17
+ import IncidentStateTimelineService from "../../Services/IncidentStateTimelineService";
18
+ import logger from "../Logger";
19
+ import DataToProcess from "./DataToProcess";
20
+
21
+ export default class MonitorIncident {
22
+ public static async checkOpenIncidentsAndCloseIfResolved(input: {
23
+ monitorId: ObjectID;
24
+ autoResolveCriteriaInstanceIdIncidentIdsDictionary: Dictionary<
25
+ Array<string>
26
+ >;
27
+ rootCause: string;
28
+ criteriaInstance: MonitorCriteriaInstance | null;
29
+ dataToProcess: DataToProcess;
30
+ }): Promise<Array<Incident>> {
31
+ // check active incidents and if there are open incidents, do not cretae anothr incident.
32
+ const openIncidents: Array<Incident> = await IncidentService.findBy({
33
+ query: {
34
+ monitors: [input.monitorId] as any,
35
+ currentIncidentState: {
36
+ isResolvedState: false,
37
+ },
38
+ },
39
+ skip: 0,
40
+ limit: LIMIT_PER_PROJECT,
41
+ select: {
42
+ _id: true,
43
+ createdCriteriaId: true,
44
+ createdIncidentTemplateId: true,
45
+ projectId: true,
46
+ },
47
+ props: {
48
+ isRoot: true,
49
+ },
50
+ });
51
+
52
+ // check if should close the incident.
53
+
54
+ for (const openIncident of openIncidents) {
55
+ const shouldClose: boolean = this.shouldCloseIncident({
56
+ openIncident,
57
+ autoResolveCriteriaInstanceIdIncidentIdsDictionary:
58
+ input.autoResolveCriteriaInstanceIdIncidentIdsDictionary,
59
+ criteriaInstance: input.criteriaInstance,
60
+ });
61
+
62
+ if (shouldClose) {
63
+ // then resolve incident.
64
+ await this.resolveOpenIncident({
65
+ openIncident: openIncident,
66
+ rootCause: input.rootCause,
67
+ dataToProcess: input.dataToProcess,
68
+ });
69
+ }
70
+ }
71
+
72
+ return openIncidents;
73
+ }
74
+
75
+ public static async criteriaMetCreateIncidentsAndUpdateMonitorStatus(input: {
76
+ criteriaInstance: MonitorCriteriaInstance;
77
+ monitor: Monitor;
78
+ dataToProcess: DataToProcess;
79
+ rootCause: string;
80
+ autoResolveCriteriaInstanceIdIncidentIdsDictionary: Dictionary<
81
+ Array<string>
82
+ >;
83
+ props: {
84
+ telemetryQuery?: TelemetryQuery | undefined;
85
+ };
86
+ }): Promise<void> {
87
+ // check open incidents
88
+ logger.debug(`${input.monitor.id?.toString()} - Check open incidents.`);
89
+ // check active incidents and if there are open incidents, do not cretae anothr incident.
90
+ const openIncidents: Array<Incident> =
91
+ await this.checkOpenIncidentsAndCloseIfResolved({
92
+ monitorId: input.monitor.id!,
93
+ autoResolveCriteriaInstanceIdIncidentIdsDictionary:
94
+ input.autoResolveCriteriaInstanceIdIncidentIdsDictionary,
95
+ rootCause: input.rootCause,
96
+ criteriaInstance: input.criteriaInstance,
97
+ dataToProcess: input.dataToProcess,
98
+ });
99
+
100
+ if (input.criteriaInstance.data?.createIncidents) {
101
+ // create incidents
102
+
103
+ for (const criteriaIncident of input.criteriaInstance.data?.incidents ||
104
+ []) {
105
+ // should create incident.
106
+
107
+ const alreadyOpenIncident: Incident | undefined = openIncidents.find(
108
+ (incident: Incident) => {
109
+ return (
110
+ incident.createdCriteriaId ===
111
+ input.criteriaInstance.data?.id.toString() &&
112
+ incident.createdIncidentTemplateId ===
113
+ criteriaIncident.id.toString()
114
+ );
115
+ },
116
+ );
117
+
118
+ const hasAlreadyOpenIncident: boolean = Boolean(alreadyOpenIncident);
119
+
120
+ logger.debug(
121
+ `${input.monitor.id?.toString()} - Open Incident ${alreadyOpenIncident?.id?.toString()}`,
122
+ );
123
+
124
+ logger.debug(
125
+ `${input.monitor.id?.toString()} - Has open incident ${hasAlreadyOpenIncident}`,
126
+ );
127
+
128
+ if (hasAlreadyOpenIncident) {
129
+ continue;
130
+ }
131
+
132
+ // create incident here.
133
+
134
+ logger.debug(`${input.monitor.id?.toString()} - Create incident.`);
135
+
136
+ const incident: Incident = new Incident();
137
+
138
+ incident.title = criteriaIncident.title;
139
+ incident.description = criteriaIncident.description;
140
+
141
+ if (!criteriaIncident.incidentSeverityId) {
142
+ // pick the critical criteria.
143
+
144
+ const severity: IncidentSeverity | null =
145
+ await IncidentSeverityService.findOneBy({
146
+ query: {
147
+ projectId: input.monitor.projectId!,
148
+ },
149
+ sort: {
150
+ order: SortOrder.Ascending,
151
+ },
152
+ props: {
153
+ isRoot: true,
154
+ },
155
+ select: {
156
+ _id: true,
157
+ },
158
+ });
159
+
160
+ if (!severity) {
161
+ throw new BadDataException(
162
+ "Project does not have incident severity",
163
+ );
164
+ } else {
165
+ incident.incidentSeverityId = severity.id!;
166
+ }
167
+ } else {
168
+ incident.incidentSeverityId = criteriaIncident.incidentSeverityId!;
169
+ }
170
+
171
+ incident.monitors = [input.monitor];
172
+ incident.projectId = input.monitor.projectId!;
173
+ incident.rootCause = input.rootCause;
174
+ incident.createdStateLog = JSON.parse(
175
+ JSON.stringify(input.dataToProcess, null, 2),
176
+ );
177
+
178
+ incident.createdCriteriaId = input.criteriaInstance.data.id.toString();
179
+
180
+ incident.createdIncidentTemplateId = criteriaIncident.id.toString();
181
+
182
+ incident.onCallDutyPolicies =
183
+ criteriaIncident.onCallPolicyIds?.map((id: ObjectID) => {
184
+ const onCallPolicy: OnCallDutyPolicy = new OnCallDutyPolicy();
185
+ onCallPolicy._id = id.toString();
186
+ return onCallPolicy;
187
+ }) || [];
188
+
189
+ incident.isCreatedAutomatically = true;
190
+
191
+ if (input.props.telemetryQuery) {
192
+ incident.telemetryQuery = input.props.telemetryQuery;
193
+ }
194
+
195
+ if (
196
+ input.dataToProcess &&
197
+ (input.dataToProcess as ProbeMonitorResponse).probeId
198
+ ) {
199
+ incident.createdByProbeId = (
200
+ input.dataToProcess as ProbeMonitorResponse
201
+ ).probeId;
202
+ }
203
+
204
+ if (criteriaIncident.remediationNotes) {
205
+ incident.remediationNotes = criteriaIncident.remediationNotes;
206
+ }
207
+
208
+ await IncidentService.create({
209
+ data: incident,
210
+ props: {
211
+ isRoot: true,
212
+ },
213
+ });
214
+ }
215
+ }
216
+ }
217
+
218
+ private static async resolveOpenIncident(input: {
219
+ openIncident: Incident;
220
+ rootCause: string;
221
+ dataToProcess:
222
+ | ProbeMonitorResponse
223
+ | IncomingMonitorRequest
224
+ | DataToProcess;
225
+ }): Promise<void> {
226
+ const resolvedStateId: ObjectID =
227
+ await IncidentStateTimelineService.getResolvedStateIdForProject(
228
+ input.openIncident.projectId!,
229
+ );
230
+
231
+ const incidentStateTimeline: IncidentStateTimeline =
232
+ new IncidentStateTimeline();
233
+ incidentStateTimeline.incidentId = input.openIncident.id!;
234
+ incidentStateTimeline.incidentStateId = resolvedStateId;
235
+ incidentStateTimeline.projectId = input.openIncident.projectId!;
236
+
237
+ if (input.rootCause) {
238
+ incidentStateTimeline.rootCause =
239
+ "Incident autoresolved because autoresolve is set to true in monitor criteria. " +
240
+ input.rootCause;
241
+ }
242
+
243
+ if (input.dataToProcess) {
244
+ incidentStateTimeline.stateChangeLog = JSON.parse(
245
+ JSON.stringify(input.dataToProcess),
246
+ );
247
+ }
248
+
249
+ await IncidentStateTimelineService.create({
250
+ data: incidentStateTimeline,
251
+ props: {
252
+ isRoot: true,
253
+ },
254
+ });
255
+ }
256
+
257
+ private static shouldCloseIncident(input: {
258
+ openIncident: Incident;
259
+ autoResolveCriteriaInstanceIdIncidentIdsDictionary: Dictionary<
260
+ Array<string>
261
+ >;
262
+ criteriaInstance: MonitorCriteriaInstance | null; // null if no criteia met.
263
+ }): boolean {
264
+ if (
265
+ input.openIncident.createdCriteriaId?.toString() ===
266
+ input.criteriaInstance?.data?.id.toString()
267
+ ) {
268
+ // same incident active. So, do not close.
269
+ return false;
270
+ }
271
+
272
+ // If antoher criteria is active then, check if the incident id is present in the map.
273
+
274
+ if (!input.openIncident.createdCriteriaId?.toString()) {
275
+ return false;
276
+ }
277
+
278
+ if (!input.openIncident.createdIncidentTemplateId?.toString()) {
279
+ return false;
280
+ }
281
+
282
+ if (
283
+ input.autoResolveCriteriaInstanceIdIncidentIdsDictionary[
284
+ input.openIncident.createdCriteriaId?.toString()
285
+ ]
286
+ ) {
287
+ if (
288
+ input.autoResolveCriteriaInstanceIdIncidentIdsDictionary[
289
+ input.openIncident.createdCriteriaId?.toString()
290
+ ]?.includes(input.openIncident.createdIncidentTemplateId?.toString())
291
+ ) {
292
+ return true;
293
+ }
294
+ }
295
+
296
+ return false;
297
+ }
298
+ }