@oneuptime/common 10.5.22 → 10.5.24
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.
- package/Server/Infrastructure/Semaphore.ts +10 -0
- package/Server/Utils/Monitor/MonitorResource.ts +570 -545
- package/build/dist/Server/Infrastructure/Semaphore.js +6 -0
- package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +434 -416
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/package.json +1 -1
|
@@ -32,16 +32,6 @@ import { LIMIT_PER_PROJECT } from "../../../Types/Database/LimitMax";
|
|
|
32
32
|
export default class MonitorResourceUtil {
|
|
33
33
|
static async monitorResource(dataToProcess) {
|
|
34
34
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
|
35
|
-
let mutex = null;
|
|
36
|
-
try {
|
|
37
|
-
mutex = await Semaphore.lock({
|
|
38
|
-
key: dataToProcess.monitorId.toString(),
|
|
39
|
-
namespace: "MonitorResourceUtil.monitorResource",
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
catch (err) {
|
|
43
|
-
logger.error(err);
|
|
44
|
-
}
|
|
45
35
|
let response = {
|
|
46
36
|
monitorId: dataToProcess.monitorId,
|
|
47
37
|
criteriaMetId: undefined,
|
|
@@ -124,458 +114,486 @@ export default class MonitorResourceUtil {
|
|
|
124
114
|
logger.debug(`${dataToProcess.monitorId.toString()} Monitor is disabled because one of the scheduled maintenance event this monitor is attached to has not ended. Please end the scheduled maintenance event to start monitoring again.`);
|
|
125
115
|
throw new BadDataException("Monitor is disabled because one of the scheduled maintenance event this monitor is attached to has not ended. Please end the scheduled maintenance event to start monitoring again.");
|
|
126
116
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
117
|
+
/*
|
|
118
|
+
* Acquire a per-monitor lock so concurrent results for the same monitor are
|
|
119
|
+
* processed serially. This MUST come after the validation above: acquiring
|
|
120
|
+
* before the not-found/disabled checks meant those throw paths held — and
|
|
121
|
+
* leaked — the lock. redis-semaphore keeps a refresh timer alive until
|
|
122
|
+
* release() is called, so a leaked lock pinned the Redis key until pod
|
|
123
|
+
* restart and forced every other worker to spin on acquire. The try/finally
|
|
124
|
+
* below guarantees the lock is released on every exit path (return or
|
|
125
|
+
* throw); acquireTimeout/retryInterval cap the acquire spin so a contended
|
|
126
|
+
* lock fails fast instead of polling Redis for 10s.
|
|
127
|
+
*/
|
|
128
|
+
let mutex = null;
|
|
129
|
+
try {
|
|
130
|
+
mutex = await Semaphore.lock({
|
|
131
|
+
key: dataToProcess.monitorId.toString(),
|
|
132
|
+
namespace: "MonitorResourceUtil.monitorResource",
|
|
133
|
+
acquireTimeout: 2000,
|
|
134
|
+
retryInterval: 100,
|
|
135
|
+
acquireAttemptsLimit: 20,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
logger.error(err);
|
|
140
|
+
}
|
|
141
|
+
const releaseMutex = async () => {
|
|
142
|
+
if (mutex) {
|
|
143
|
+
try {
|
|
144
|
+
await Semaphore.release(mutex);
|
|
153
145
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
probeId: dataToProcess.probeId,
|
|
159
|
-
},
|
|
160
|
-
data: {
|
|
161
|
-
lastMonitoringLog: Object.assign(Object.assign({}, (monitorProbe.lastMonitoringLog || {})), { [dataToProcess.monitorStepId.toString()]: Object.assign(Object.assign({}, JSON.parse(JSON.stringify(dataToProcess))), { monitoredAt: OneUptimeDate.getCurrentDate() }) }),
|
|
162
|
-
},
|
|
163
|
-
props: {
|
|
164
|
-
isRoot: true,
|
|
165
|
-
},
|
|
166
|
-
});
|
|
146
|
+
catch (err) {
|
|
147
|
+
logger.error(err);
|
|
148
|
+
}
|
|
149
|
+
mutex = null;
|
|
167
150
|
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
dataToProcess.
|
|
175
|
-
|
|
176
|
-
.
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
151
|
+
};
|
|
152
|
+
try {
|
|
153
|
+
let probeName = undefined;
|
|
154
|
+
const monitorName = monitor.name || undefined;
|
|
155
|
+
// save the last log to MonitorProbe.
|
|
156
|
+
// get last log. We do this because there are many monitoring steps and we need to store those.
|
|
157
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - monitor type ${monitor.monitorType}`);
|
|
158
|
+
if (monitor.monitorType &&
|
|
159
|
+
MonitorTypeHelper.isProbableMonitor(monitor.monitorType)) {
|
|
160
|
+
dataToProcess = dataToProcess;
|
|
161
|
+
if (dataToProcess.probeId) {
|
|
162
|
+
const monitorProbe = await MonitorProbeService.findOneBy({
|
|
163
|
+
query: {
|
|
164
|
+
monitorId: monitor.id,
|
|
165
|
+
probeId: dataToProcess.probeId,
|
|
166
|
+
},
|
|
167
|
+
select: {
|
|
168
|
+
lastMonitoringLog: true,
|
|
169
|
+
probe: {
|
|
170
|
+
name: true,
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
props: {
|
|
174
|
+
isRoot: true,
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
if (!monitorProbe) {
|
|
178
|
+
throw new BadDataException("Probe is not assigned to this monitor");
|
|
179
|
+
}
|
|
180
|
+
probeName = ((_a = monitorProbe.probe) === null || _a === void 0 ? void 0 : _a.name) || undefined;
|
|
181
|
+
await MonitorProbeService.updateOneBy({
|
|
182
|
+
query: {
|
|
183
|
+
monitorId: monitor.id,
|
|
184
|
+
probeId: dataToProcess.probeId,
|
|
185
|
+
},
|
|
186
|
+
data: {
|
|
187
|
+
lastMonitoringLog: Object.assign(Object.assign({}, (monitorProbe.lastMonitoringLog || {})), { [dataToProcess.monitorStepId.toString()]: Object.assign(Object.assign({}, JSON.parse(JSON.stringify(dataToProcess))), { monitoredAt: OneUptimeDate.getCurrentDate() }) }),
|
|
188
|
+
},
|
|
189
|
+
props: {
|
|
190
|
+
isRoot: true,
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
}
|
|
183
194
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
195
|
+
const serverMonitorResponse = monitor.monitorType === MonitorType.Server &&
|
|
196
|
+
dataToProcess.requestReceivedAt
|
|
197
|
+
? dataToProcess
|
|
198
|
+
: undefined;
|
|
199
|
+
const incomingMonitorRequest = monitor.monitorType === MonitorType.IncomingRequest &&
|
|
200
|
+
dataToProcess.incomingRequestReceivedAt &&
|
|
201
|
+
!dataToProcess
|
|
202
|
+
.onlyCheckForIncomingRequestReceivedAt
|
|
203
|
+
? dataToProcess
|
|
204
|
+
: undefined;
|
|
205
|
+
let hasPersistedMonitorData = false;
|
|
206
|
+
const persistLatestMonitorPayload = async () => {
|
|
207
|
+
if (hasPersistedMonitorData) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
if (serverMonitorResponse) {
|
|
211
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - Server request received at ${serverMonitorResponse.requestReceivedAt}`);
|
|
212
|
+
logger.debug(dataToProcess);
|
|
213
|
+
/*
|
|
214
|
+
* Skip persistence when this evaluation originated from the
|
|
215
|
+
* CheckOnlineStatus cron (onlyCheckRequestReceivedAt=true). The cron
|
|
216
|
+
* re-evaluates using the already-stale value read from the DB and has
|
|
217
|
+
* no new heartbeat data to persist — writing it back would race with
|
|
218
|
+
* (and overwrite) the ingest path's fresh heartbeat update, causing
|
|
219
|
+
* the monitor to flap between Online and Offline every minute.
|
|
220
|
+
*/
|
|
221
|
+
if (!serverMonitorResponse.onlyCheckRequestReceivedAt) {
|
|
222
|
+
await MonitorService.updateOneById({
|
|
223
|
+
id: monitor.id,
|
|
224
|
+
data: {
|
|
225
|
+
serverMonitorRequestReceivedAt: serverMonitorResponse.requestReceivedAt,
|
|
226
|
+
serverMonitorResponse,
|
|
227
|
+
},
|
|
228
|
+
props: {
|
|
229
|
+
isRoot: true,
|
|
230
|
+
ignoreHooks: true,
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - Monitor Server Response Updated`);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - Skipping Monitor Server Response persist (cron re-evaluation).`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (incomingMonitorRequest) {
|
|
240
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - Incoming request received at ${incomingMonitorRequest.incomingRequestReceivedAt}`);
|
|
196
241
|
await MonitorService.updateOneById({
|
|
197
242
|
id: monitor.id,
|
|
198
243
|
data: {
|
|
199
|
-
|
|
200
|
-
|
|
244
|
+
incomingRequestMonitorHeartbeatCheckedAt: OneUptimeDate.getCurrentDate(),
|
|
245
|
+
incomingMonitorRequest: JSON.parse(JSON.stringify(incomingMonitorRequest)),
|
|
201
246
|
},
|
|
202
247
|
props: {
|
|
203
248
|
isRoot: true,
|
|
204
249
|
ignoreHooks: true,
|
|
205
250
|
},
|
|
206
251
|
});
|
|
207
|
-
logger.debug(`${dataToProcess.monitorId.toString()} - Monitor
|
|
208
|
-
}
|
|
209
|
-
else {
|
|
210
|
-
logger.debug(`${dataToProcess.monitorId.toString()} - Skipping Monitor Server Response persist (cron re-evaluation).`);
|
|
252
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - Monitor Incoming Request Updated`);
|
|
211
253
|
}
|
|
254
|
+
hasPersistedMonitorData = true;
|
|
255
|
+
};
|
|
256
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - Saving monitor metrics`);
|
|
257
|
+
try {
|
|
258
|
+
await MonitorMetricUtil.saveMonitorMetrics({
|
|
259
|
+
monitorId: monitor.id,
|
|
260
|
+
projectId: monitor.projectId,
|
|
261
|
+
dataToProcess: dataToProcess,
|
|
262
|
+
probeName: probeName || undefined,
|
|
263
|
+
monitorName: monitorName || undefined,
|
|
264
|
+
});
|
|
212
265
|
}
|
|
213
|
-
|
|
214
|
-
logger.
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
266
|
+
catch (err) {
|
|
267
|
+
logger.error("Unable to save metrics");
|
|
268
|
+
logger.error(err);
|
|
269
|
+
}
|
|
270
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - Monitor metrics saved`);
|
|
271
|
+
const monitorSteps = monitor.monitorSteps;
|
|
272
|
+
if (!((_b = monitorSteps.data) === null || _b === void 0 ? void 0 : _b.monitorStepsInstanceArray) ||
|
|
273
|
+
((_c = monitorSteps.data) === null || _c === void 0 ? void 0 : _c.monitorStepsInstanceArray.length) === 0) {
|
|
274
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - No monitoring steps.`);
|
|
275
|
+
await persistLatestMonitorPayload();
|
|
276
|
+
MonitorLogUtil.saveMonitorLog({
|
|
277
|
+
monitorId: monitor.id,
|
|
278
|
+
projectId: monitor.projectId,
|
|
279
|
+
dataToProcess: dataToProcess,
|
|
225
280
|
});
|
|
226
|
-
|
|
281
|
+
return response;
|
|
227
282
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
});
|
|
255
|
-
return response;
|
|
256
|
-
}
|
|
257
|
-
logger.debug(`${dataToProcess.monitorId.toString()} - Auto resolving criteria instances.`);
|
|
258
|
-
const criteriaInstances = monitorSteps.data.monitorStepsInstanceArray
|
|
259
|
-
.map((step) => {
|
|
260
|
-
var _a;
|
|
261
|
-
return (_a = step.data) === null || _a === void 0 ? void 0 : _a.monitorCriteria;
|
|
262
|
-
})
|
|
263
|
-
.filter((criteria) => {
|
|
264
|
-
return Boolean(criteria);
|
|
265
|
-
})
|
|
266
|
-
.map((criteria) => {
|
|
267
|
-
var _a;
|
|
268
|
-
return [...(((_a = criteria === null || criteria === void 0 ? void 0 : criteria.data) === null || _a === void 0 ? void 0 : _a.monitorCriteriaInstanceArray) || [])];
|
|
269
|
-
})
|
|
270
|
-
.flat();
|
|
271
|
-
const autoResolveCriteriaInstanceIdIncidentIdsDictionary = {};
|
|
272
|
-
const criteriaInstanceMap = {};
|
|
273
|
-
for (const criteriaInstance of criteriaInstances) {
|
|
274
|
-
criteriaInstanceMap[((_d = criteriaInstance.data) === null || _d === void 0 ? void 0 : _d.id) || ""] = criteriaInstance;
|
|
275
|
-
if (((_e = criteriaInstance.data) === null || _e === void 0 ? void 0 : _e.incidents) &&
|
|
276
|
-
((_f = criteriaInstance.data) === null || _f === void 0 ? void 0 : _f.incidents.length) > 0) {
|
|
277
|
-
for (const incidentTemplate of criteriaInstance.data.incidents) {
|
|
278
|
-
if (incidentTemplate.autoResolveIncident) {
|
|
279
|
-
if (!autoResolveCriteriaInstanceIdIncidentIdsDictionary[criteriaInstance.data.id.toString()]) {
|
|
280
|
-
autoResolveCriteriaInstanceIdIncidentIdsDictionary[criteriaInstance.data.id.toString()] = [];
|
|
283
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - Auto resolving criteria instances.`);
|
|
284
|
+
const criteriaInstances = monitorSteps.data.monitorStepsInstanceArray
|
|
285
|
+
.map((step) => {
|
|
286
|
+
var _a;
|
|
287
|
+
return (_a = step.data) === null || _a === void 0 ? void 0 : _a.monitorCriteria;
|
|
288
|
+
})
|
|
289
|
+
.filter((criteria) => {
|
|
290
|
+
return Boolean(criteria);
|
|
291
|
+
})
|
|
292
|
+
.map((criteria) => {
|
|
293
|
+
var _a;
|
|
294
|
+
return [...(((_a = criteria === null || criteria === void 0 ? void 0 : criteria.data) === null || _a === void 0 ? void 0 : _a.monitorCriteriaInstanceArray) || [])];
|
|
295
|
+
})
|
|
296
|
+
.flat();
|
|
297
|
+
const autoResolveCriteriaInstanceIdIncidentIdsDictionary = {};
|
|
298
|
+
const criteriaInstanceMap = {};
|
|
299
|
+
for (const criteriaInstance of criteriaInstances) {
|
|
300
|
+
criteriaInstanceMap[((_d = criteriaInstance.data) === null || _d === void 0 ? void 0 : _d.id) || ""] = criteriaInstance;
|
|
301
|
+
if (((_e = criteriaInstance.data) === null || _e === void 0 ? void 0 : _e.incidents) &&
|
|
302
|
+
((_f = criteriaInstance.data) === null || _f === void 0 ? void 0 : _f.incidents.length) > 0) {
|
|
303
|
+
for (const incidentTemplate of criteriaInstance.data.incidents) {
|
|
304
|
+
if (incidentTemplate.autoResolveIncident) {
|
|
305
|
+
if (!autoResolveCriteriaInstanceIdIncidentIdsDictionary[criteriaInstance.data.id.toString()]) {
|
|
306
|
+
autoResolveCriteriaInstanceIdIncidentIdsDictionary[criteriaInstance.data.id.toString()] = [];
|
|
307
|
+
}
|
|
308
|
+
(_g = autoResolveCriteriaInstanceIdIncidentIdsDictionary[criteriaInstance.data.id.toString()]) === null || _g === void 0 ? void 0 : _g.push(incidentTemplate.id);
|
|
281
309
|
}
|
|
282
|
-
(_g = autoResolveCriteriaInstanceIdIncidentIdsDictionary[criteriaInstance.data.id.toString()]) === null || _g === void 0 ? void 0 : _g.push(incidentTemplate.id);
|
|
283
310
|
}
|
|
284
311
|
}
|
|
285
312
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
criteriaInstance
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
313
|
+
// alerts.
|
|
314
|
+
const autoResolveCriteriaInstanceIdAlertIdsDictionary = {};
|
|
315
|
+
const criteriaInstanceAlertMap = {};
|
|
316
|
+
for (const criteriaInstance of criteriaInstances) {
|
|
317
|
+
criteriaInstanceAlertMap[((_h = criteriaInstance.data) === null || _h === void 0 ? void 0 : _h.id) || ""] =
|
|
318
|
+
criteriaInstance;
|
|
319
|
+
if (((_j = criteriaInstance.data) === null || _j === void 0 ? void 0 : _j.alerts) &&
|
|
320
|
+
((_k = criteriaInstance.data) === null || _k === void 0 ? void 0 : _k.alerts.length) > 0) {
|
|
321
|
+
for (const alertTemplate of criteriaInstance.data.alerts) {
|
|
322
|
+
if (alertTemplate.autoResolveAlert) {
|
|
323
|
+
if (!autoResolveCriteriaInstanceIdAlertIdsDictionary[criteriaInstance.data.id.toString()]) {
|
|
324
|
+
autoResolveCriteriaInstanceIdAlertIdsDictionary[criteriaInstance.data.id.toString()] = [];
|
|
325
|
+
}
|
|
326
|
+
(_l = autoResolveCriteriaInstanceIdAlertIdsDictionary[criteriaInstance.data.id.toString()]) === null || _l === void 0 ? void 0 : _l.push(alertTemplate.id);
|
|
299
327
|
}
|
|
300
|
-
(_l = autoResolveCriteriaInstanceIdAlertIdsDictionary[criteriaInstance.data.id.toString()]) === null || _l === void 0 ? void 0 : _l.push(alertTemplate.id);
|
|
301
328
|
}
|
|
302
329
|
}
|
|
303
330
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
logger.debug("No steps found, ignoring everything.");
|
|
316
|
-
await persistLatestMonitorPayload();
|
|
317
|
-
MonitorLogUtil.saveMonitorLog({
|
|
318
|
-
monitorId: monitor.id,
|
|
319
|
-
projectId: monitor.projectId,
|
|
320
|
-
dataToProcess: dataToProcess,
|
|
321
|
-
});
|
|
322
|
-
return response;
|
|
323
|
-
}
|
|
324
|
-
// now process the monitor step
|
|
325
|
-
response.ingestedMonitorStepId = monitorStep.id;
|
|
326
|
-
logger.debug(`Ingested Monitor Step ID: ${monitorStep.id}`);
|
|
327
|
-
//find next monitor step after this one.
|
|
328
|
-
const nextMonitorStepIndex = monitorSteps.data.monitorStepsInstanceArray.findIndex((step) => {
|
|
329
|
-
return step.id.toString() === monitorStep.id.toString();
|
|
330
|
-
});
|
|
331
|
-
response.nextMonitorStepId =
|
|
332
|
-
(_m = monitorSteps.data.monitorStepsInstanceArray[nextMonitorStepIndex + 1]) === null || _m === void 0 ? void 0 : _m.id;
|
|
333
|
-
logger.debug(`Next Monitor Step ID: ${response.nextMonitorStepId}`);
|
|
334
|
-
// now process probe response monitors
|
|
335
|
-
logger.debug(`${dataToProcess.monitorId.toString()} - Processing monitor step...`);
|
|
336
|
-
response = await MonitorCriteriaEvaluator.processMonitorStep({
|
|
337
|
-
dataToProcess: dataToProcess,
|
|
338
|
-
monitorStep: monitorStep,
|
|
339
|
-
monitor: monitor,
|
|
340
|
-
probeApiIngestResponse: response,
|
|
341
|
-
evaluationSummary: evaluationSummary,
|
|
342
|
-
});
|
|
343
|
-
// Check probe agreement for probe-based monitors
|
|
344
|
-
if (monitor.monitorType &&
|
|
345
|
-
MonitorTypeHelper.isProbableMonitor(monitor.monitorType)) {
|
|
346
|
-
const probeAgreementResult = await MonitorResourceUtil.checkProbeAgreement({
|
|
347
|
-
monitor: monitor,
|
|
348
|
-
monitorStep: monitorStep,
|
|
349
|
-
currentCriteriaMetId: response.criteriaMetId || null,
|
|
350
|
-
currentRootCause: response.rootCause || null,
|
|
351
|
-
});
|
|
352
|
-
// Add probe agreement event to evaluation summary
|
|
353
|
-
evaluationSummary.events.push({
|
|
354
|
-
type: "probe-agreement",
|
|
355
|
-
title: "Probe Agreement Check",
|
|
356
|
-
message: probeAgreementResult.hasAgreement
|
|
357
|
-
? `Probe agreement reached: ${probeAgreementResult.agreementCount}/${probeAgreementResult.requiredCount} probes agree (${probeAgreementResult.totalActiveProbes} active probes total).`
|
|
358
|
-
: `Probe agreement not reached: ${probeAgreementResult.agreementCount}/${probeAgreementResult.requiredCount} probes agree (${probeAgreementResult.totalActiveProbes} active probes total). Skipping status change.`,
|
|
359
|
-
at: OneUptimeDate.getCurrentDate(),
|
|
360
|
-
});
|
|
361
|
-
if (!probeAgreementResult.hasAgreement) {
|
|
362
|
-
logger.debug(`${dataToProcess.monitorId.toString()} - Probe agreement not met. ${probeAgreementResult.agreementCount}/${probeAgreementResult.requiredCount} probes agree. Skipping status change.`);
|
|
363
|
-
// Release lock and return early - no status change
|
|
364
|
-
if (mutex) {
|
|
365
|
-
try {
|
|
366
|
-
await Semaphore.release(mutex);
|
|
367
|
-
}
|
|
368
|
-
catch (err) {
|
|
369
|
-
logger.error(err);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
331
|
+
const monitorStep = monitorSteps.data.monitorStepsInstanceArray[0];
|
|
332
|
+
logger.debug(`Monitor Step: ${monitorStep ? monitorStep.id : "undefined"}`);
|
|
333
|
+
if (dataToProcess.monitorStepId) {
|
|
334
|
+
monitorSteps.data.monitorStepsInstanceArray.find((monitorStep) => {
|
|
335
|
+
return (monitorStep.id.toString() ===
|
|
336
|
+
dataToProcess.monitorStepId.toString());
|
|
337
|
+
});
|
|
338
|
+
logger.debug(`Found Monitor Step ID: ${dataToProcess.monitorStepId}`);
|
|
339
|
+
}
|
|
340
|
+
if (!monitorStep) {
|
|
341
|
+
logger.debug("No steps found, ignoring everything.");
|
|
372
342
|
await persistLatestMonitorPayload();
|
|
373
343
|
MonitorLogUtil.saveMonitorLog({
|
|
374
344
|
monitorId: monitor.id,
|
|
375
345
|
projectId: monitor.projectId,
|
|
376
346
|
dataToProcess: dataToProcess,
|
|
377
347
|
});
|
|
378
|
-
response.evaluationSummary = evaluationSummary;
|
|
379
348
|
return response;
|
|
380
349
|
}
|
|
381
|
-
//
|
|
382
|
-
response.
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
if (response.criteriaMetId && response.rootCause) {
|
|
395
|
-
logger.debug(`${dataToProcess.monitorId.toString()} - Criteria met: ${response.criteriaMetId}`);
|
|
396
|
-
logger.debug(`${dataToProcess.monitorId.toString()} - Root cause: ${response.rootCause}`);
|
|
397
|
-
let telemetryQuery = undefined;
|
|
398
|
-
if (dataToProcess && dataToProcess.logQuery) {
|
|
399
|
-
telemetryQuery = {
|
|
400
|
-
telemetryQuery: dataToProcess.logQuery,
|
|
401
|
-
telemetryType: TelemetryType.Log,
|
|
402
|
-
metricViewData: null,
|
|
403
|
-
};
|
|
404
|
-
logger.debug(`${dataToProcess.monitorId.toString()} - Log query found.`);
|
|
405
|
-
}
|
|
406
|
-
if (dataToProcess && dataToProcess.spanQuery) {
|
|
407
|
-
telemetryQuery = {
|
|
408
|
-
telemetryQuery: dataToProcess.spanQuery,
|
|
409
|
-
telemetryType: TelemetryType.Trace,
|
|
410
|
-
metricViewData: null,
|
|
411
|
-
};
|
|
412
|
-
logger.debug(`${dataToProcess.monitorId.toString()} - Span query found.`);
|
|
413
|
-
}
|
|
414
|
-
if (dataToProcess &&
|
|
415
|
-
dataToProcess.metricViewConfig &&
|
|
416
|
-
dataToProcess.startAndEndDate) {
|
|
417
|
-
telemetryQuery = {
|
|
418
|
-
telemetryQuery: null,
|
|
419
|
-
telemetryType: TelemetryType.Metric,
|
|
420
|
-
metricViewData: {
|
|
421
|
-
startAndEndDate: dataToProcess.startAndEndDate || null,
|
|
422
|
-
queryConfigs: dataToProcess
|
|
423
|
-
.metricViewConfig.queryConfigs,
|
|
424
|
-
formulaConfigs: dataToProcess
|
|
425
|
-
.metricViewConfig.formulaConfigs,
|
|
426
|
-
},
|
|
427
|
-
};
|
|
428
|
-
logger.debug(`${dataToProcess.monitorId.toString()} - Span query found.`);
|
|
429
|
-
}
|
|
430
|
-
if (dataToProcess &&
|
|
431
|
-
dataToProcess.exceptionQuery) {
|
|
432
|
-
const exceptionResponse = dataToProcess;
|
|
433
|
-
telemetryQuery = {
|
|
434
|
-
telemetryQuery: exceptionResponse.exceptionQuery,
|
|
435
|
-
telemetryType: TelemetryType.Exception,
|
|
436
|
-
metricViewData: null,
|
|
437
|
-
};
|
|
438
|
-
logger.debug(`${dataToProcess.monitorId.toString()} - Exception query found.`);
|
|
439
|
-
}
|
|
440
|
-
const matchedCriteriaInstance = criteriaInstanceMap[response.criteriaMetId];
|
|
441
|
-
const monitorStatusTimelineChange = await MonitorStatusTimelineUtil.updateMonitorStatusTimeline({
|
|
442
|
-
monitor: monitor,
|
|
443
|
-
rootCause: response.rootCause,
|
|
350
|
+
// now process the monitor step
|
|
351
|
+
response.ingestedMonitorStepId = monitorStep.id;
|
|
352
|
+
logger.debug(`Ingested Monitor Step ID: ${monitorStep.id}`);
|
|
353
|
+
//find next monitor step after this one.
|
|
354
|
+
const nextMonitorStepIndex = monitorSteps.data.monitorStepsInstanceArray.findIndex((step) => {
|
|
355
|
+
return step.id.toString() === monitorStep.id.toString();
|
|
356
|
+
});
|
|
357
|
+
response.nextMonitorStepId =
|
|
358
|
+
(_m = monitorSteps.data.monitorStepsInstanceArray[nextMonitorStepIndex + 1]) === null || _m === void 0 ? void 0 : _m.id;
|
|
359
|
+
logger.debug(`Next Monitor Step ID: ${response.nextMonitorStepId}`);
|
|
360
|
+
// now process probe response monitors
|
|
361
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - Processing monitor step...`);
|
|
362
|
+
response = await MonitorCriteriaEvaluator.processMonitorStep({
|
|
444
363
|
dataToProcess: dataToProcess,
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
364
|
+
monitorStep: monitorStep,
|
|
365
|
+
monitor: monitor,
|
|
366
|
+
probeApiIngestResponse: response,
|
|
367
|
+
evaluationSummary: evaluationSummary,
|
|
449
368
|
});
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
369
|
+
// Check probe agreement for probe-based monitors
|
|
370
|
+
if (monitor.monitorType &&
|
|
371
|
+
MonitorTypeHelper.isProbableMonitor(monitor.monitorType)) {
|
|
372
|
+
const probeAgreementResult = await MonitorResourceUtil.checkProbeAgreement({
|
|
373
|
+
monitor: monitor,
|
|
374
|
+
monitorStep: monitorStep,
|
|
375
|
+
currentCriteriaMetId: response.criteriaMetId || null,
|
|
376
|
+
currentRootCause: response.rootCause || null,
|
|
377
|
+
});
|
|
378
|
+
// Add probe agreement event to evaluation summary
|
|
453
379
|
evaluationSummary.events.push({
|
|
454
|
-
type: "
|
|
455
|
-
title: "
|
|
456
|
-
message:
|
|
457
|
-
? `
|
|
458
|
-
: `
|
|
459
|
-
relatedCriteriaId: (_r = matchedCriteriaInstance.data) === null || _r === void 0 ? void 0 : _r.id,
|
|
380
|
+
type: "probe-agreement",
|
|
381
|
+
title: "Probe Agreement Check",
|
|
382
|
+
message: probeAgreementResult.hasAgreement
|
|
383
|
+
? `Probe agreement reached: ${probeAgreementResult.agreementCount}/${probeAgreementResult.requiredCount} probes agree (${probeAgreementResult.totalActiveProbes} active probes total).`
|
|
384
|
+
: `Probe agreement not reached: ${probeAgreementResult.agreementCount}/${probeAgreementResult.requiredCount} probes agree (${probeAgreementResult.totalActiveProbes} active probes total). Skipping status change.`,
|
|
460
385
|
at: OneUptimeDate.getCurrentDate(),
|
|
461
386
|
});
|
|
387
|
+
if (!probeAgreementResult.hasAgreement) {
|
|
388
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - Probe agreement not met. ${probeAgreementResult.agreementCount}/${probeAgreementResult.requiredCount} probes agree. Skipping status change.`);
|
|
389
|
+
// Release lock and return early - no status change
|
|
390
|
+
await releaseMutex();
|
|
391
|
+
await persistLatestMonitorPayload();
|
|
392
|
+
MonitorLogUtil.saveMonitorLog({
|
|
393
|
+
monitorId: monitor.id,
|
|
394
|
+
projectId: monitor.projectId,
|
|
395
|
+
dataToProcess: dataToProcess,
|
|
396
|
+
});
|
|
397
|
+
response.evaluationSummary = evaluationSummary;
|
|
398
|
+
return response;
|
|
399
|
+
}
|
|
400
|
+
// Use the agreed criteria result
|
|
401
|
+
response.criteriaMetId = probeAgreementResult.agreedCriteriaId
|
|
402
|
+
? probeAgreementResult.agreedCriteriaId
|
|
403
|
+
: undefined;
|
|
404
|
+
response.rootCause = probeAgreementResult.agreedRootCause;
|
|
405
|
+
// Add probe names in agreement to the root cause
|
|
406
|
+
if (response.rootCause &&
|
|
407
|
+
probeAgreementResult.agreedProbeNames.length > 0) {
|
|
408
|
+
response.rootCause += `
|
|
409
|
+
**Probes in Agreement**: ${probeAgreementResult.agreedProbeNames.join(", ")}
|
|
410
|
+
`;
|
|
411
|
+
}
|
|
462
412
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
413
|
+
if (response.criteriaMetId && response.rootCause) {
|
|
414
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - Criteria met: ${response.criteriaMetId}`);
|
|
415
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - Root cause: ${response.rootCause}`);
|
|
416
|
+
let telemetryQuery = undefined;
|
|
417
|
+
if (dataToProcess && dataToProcess.logQuery) {
|
|
418
|
+
telemetryQuery = {
|
|
419
|
+
telemetryQuery: dataToProcess.logQuery,
|
|
420
|
+
telemetryType: TelemetryType.Log,
|
|
421
|
+
metricViewData: null,
|
|
422
|
+
};
|
|
423
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - Log query found.`);
|
|
424
|
+
}
|
|
425
|
+
if (dataToProcess &&
|
|
426
|
+
dataToProcess.spanQuery) {
|
|
427
|
+
telemetryQuery = {
|
|
428
|
+
telemetryQuery: dataToProcess.spanQuery,
|
|
429
|
+
telemetryType: TelemetryType.Trace,
|
|
430
|
+
metricViewData: null,
|
|
431
|
+
};
|
|
432
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - Span query found.`);
|
|
433
|
+
}
|
|
434
|
+
if (dataToProcess &&
|
|
435
|
+
dataToProcess.metricViewConfig &&
|
|
436
|
+
dataToProcess.startAndEndDate) {
|
|
437
|
+
telemetryQuery = {
|
|
438
|
+
telemetryQuery: null,
|
|
439
|
+
telemetryType: TelemetryType.Metric,
|
|
440
|
+
metricViewData: {
|
|
441
|
+
startAndEndDate: dataToProcess.startAndEndDate ||
|
|
442
|
+
null,
|
|
443
|
+
queryConfigs: dataToProcess
|
|
444
|
+
.metricViewConfig.queryConfigs,
|
|
445
|
+
formulaConfigs: dataToProcess
|
|
446
|
+
.metricViewConfig.formulaConfigs,
|
|
447
|
+
},
|
|
448
|
+
};
|
|
449
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - Span query found.`);
|
|
450
|
+
}
|
|
451
|
+
if (dataToProcess &&
|
|
452
|
+
dataToProcess.exceptionQuery) {
|
|
453
|
+
const exceptionResponse = dataToProcess;
|
|
454
|
+
telemetryQuery = {
|
|
455
|
+
telemetryQuery: exceptionResponse.exceptionQuery,
|
|
456
|
+
telemetryType: TelemetryType.Exception,
|
|
457
|
+
metricViewData: null,
|
|
458
|
+
};
|
|
459
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - Exception query found.`);
|
|
460
|
+
}
|
|
461
|
+
const matchedCriteriaInstance = criteriaInstanceMap[response.criteriaMetId];
|
|
462
|
+
const monitorStatusTimelineChange = await MonitorStatusTimelineUtil.updateMonitorStatusTimeline({
|
|
463
|
+
monitor: monitor,
|
|
464
|
+
rootCause: response.rootCause,
|
|
465
|
+
dataToProcess: dataToProcess,
|
|
466
|
+
criteriaInstance: matchedCriteriaInstance,
|
|
467
|
+
props: {
|
|
468
|
+
telemetryQuery: telemetryQuery,
|
|
469
|
+
},
|
|
470
|
+
});
|
|
471
|
+
if (monitorStatusTimelineChange) {
|
|
472
|
+
const changedStatusName = await getMonitorStatusName(((_o = matchedCriteriaInstance.data) === null || _o === void 0 ? void 0 : _o.monitorStatusId) ||
|
|
473
|
+
monitorStatusTimelineChange.monitorStatusId);
|
|
474
|
+
evaluationSummary.events.push({
|
|
475
|
+
type: "monitor-status-changed",
|
|
476
|
+
title: "Monitor status updated",
|
|
477
|
+
message: changedStatusName
|
|
478
|
+
? `Monitor status changed to "${changedStatusName}" because criteria "${((_p = matchedCriteriaInstance.data) === null || _p === void 0 ? void 0 : _p.name) || "Unnamed criteria"}" was met.`
|
|
479
|
+
: `Monitor status changed because criteria "${((_q = matchedCriteriaInstance.data) === null || _q === void 0 ? void 0 : _q.name) || "Unnamed criteria"}" was met.`,
|
|
480
|
+
relatedCriteriaId: (_r = matchedCriteriaInstance.data) === null || _r === void 0 ? void 0 : _r.id,
|
|
481
|
+
at: OneUptimeDate.getCurrentDate(),
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
await MonitorIncident.criteriaMetCreateIncidentsAndUpdateMonitorStatus({
|
|
485
|
+
monitor: monitor,
|
|
486
|
+
rootCause: response.rootCause,
|
|
487
|
+
dataToProcess: dataToProcess,
|
|
488
|
+
autoResolveCriteriaInstanceIdIncidentIdsDictionary,
|
|
489
|
+
criteriaInstance: matchedCriteriaInstance,
|
|
490
|
+
evaluationSummary: evaluationSummary,
|
|
491
|
+
props: {
|
|
492
|
+
telemetryQuery: telemetryQuery,
|
|
493
|
+
},
|
|
494
|
+
matchesPerSeries: response.perSeriesMatches,
|
|
495
|
+
});
|
|
496
|
+
await MonitorAlert.criteriaMetCreateAlertsAndUpdateMonitorStatus({
|
|
497
|
+
monitor: monitor,
|
|
498
|
+
rootCause: response.rootCause,
|
|
499
|
+
dataToProcess: dataToProcess,
|
|
500
|
+
autoResolveCriteriaInstanceIdAlertIdsDictionary,
|
|
501
|
+
criteriaInstance: criteriaInstanceAlertMap[response.criteriaMetId],
|
|
502
|
+
evaluationSummary: evaluationSummary,
|
|
503
|
+
props: {
|
|
504
|
+
telemetryQuery: telemetryQuery,
|
|
505
|
+
},
|
|
506
|
+
matchesPerSeries: response.perSeriesMatches,
|
|
507
|
+
});
|
|
534
508
|
}
|
|
535
|
-
else
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
509
|
+
else if (!response.criteriaMetId &&
|
|
510
|
+
monitorSteps.data.defaultMonitorStatusId &&
|
|
511
|
+
((_s = monitor.currentMonitorStatusId) === null || _s === void 0 ? void 0 : _s.toString()) !==
|
|
512
|
+
monitorSteps.data.defaultMonitorStatusId.toString()) {
|
|
513
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - No criteria met. Change to default status.`);
|
|
514
|
+
await MonitorIncident.checkOpenIncidentsAndCloseIfResolved({
|
|
515
|
+
monitorId: monitor.id,
|
|
516
|
+
autoResolveCriteriaInstanceIdIncidentIdsDictionary,
|
|
517
|
+
rootCause: "No monitoring criteria met. Change to default status.",
|
|
518
|
+
criteriaInstance: null, // no criteria met!
|
|
519
|
+
dataToProcess: dataToProcess,
|
|
520
|
+
evaluationSummary: evaluationSummary,
|
|
521
|
+
});
|
|
522
|
+
await MonitorAlert.checkOpenAlertsAndCloseIfResolved({
|
|
523
|
+
monitorId: monitor.id,
|
|
524
|
+
autoResolveCriteriaInstanceIdAlertIdsDictionary,
|
|
525
|
+
rootCause: "No monitoring criteria met. Change to default status.",
|
|
526
|
+
criteriaInstance: null, // no criteria met!
|
|
527
|
+
dataToProcess: dataToProcess,
|
|
528
|
+
evaluationSummary: evaluationSummary,
|
|
529
|
+
});
|
|
530
|
+
// get last monitor status timeline.
|
|
531
|
+
const lastMonitorStatusTimeline = await MonitorStatusTimelineService.findOneBy({
|
|
532
|
+
query: {
|
|
533
|
+
monitorId: monitor.id,
|
|
534
|
+
projectId: monitor.projectId,
|
|
535
|
+
},
|
|
536
|
+
select: {
|
|
537
|
+
_id: true,
|
|
538
|
+
monitorStatusId: true,
|
|
539
|
+
},
|
|
540
|
+
sort: {
|
|
541
|
+
startsAt: SortOrder.Descending,
|
|
542
|
+
},
|
|
548
543
|
props: {
|
|
549
544
|
isRoot: true,
|
|
550
545
|
},
|
|
551
546
|
});
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
547
|
+
if (lastMonitorStatusTimeline &&
|
|
548
|
+
lastMonitorStatusTimeline.monitorStatusId &&
|
|
549
|
+
lastMonitorStatusTimeline.monitorStatusId.toString() ===
|
|
550
|
+
monitorSteps.data.defaultMonitorStatusId.toString()) {
|
|
551
|
+
/*
|
|
552
|
+
* status is same as last status. do not create new status timeline.
|
|
553
|
+
* do nothing! status is same as last status.
|
|
554
|
+
*/
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
// if no criteria is met then update monitor to default state.
|
|
558
|
+
const monitorStatusTimeline = new MonitorStatusTimeline();
|
|
559
|
+
monitorStatusTimeline.monitorId = monitor.id;
|
|
560
|
+
monitorStatusTimeline.monitorStatusId =
|
|
561
|
+
monitorSteps.data.defaultMonitorStatusId;
|
|
562
|
+
monitorStatusTimeline.projectId = monitor.projectId;
|
|
563
|
+
monitorStatusTimeline.isOwnerNotified = true; // no need to notify owner as this is default status.
|
|
564
|
+
monitorStatusTimeline.statusChangeLog = JSON.parse(JSON.stringify(dataToProcess));
|
|
565
|
+
monitorStatusTimeline.rootCause =
|
|
566
|
+
"No monitoring criteria met. Change to default status. ";
|
|
567
|
+
await MonitorStatusTimelineService.create({
|
|
568
|
+
data: monitorStatusTimeline,
|
|
569
|
+
props: {
|
|
570
|
+
isRoot: true,
|
|
571
|
+
},
|
|
572
|
+
});
|
|
573
|
+
logger.debug(`${dataToProcess.monitorId.toString()} - Monitor status updated to default.`);
|
|
574
|
+
const defaultStatusName = await getMonitorStatusName(monitorSteps.data.defaultMonitorStatusId);
|
|
575
|
+
evaluationSummary.events.push({
|
|
576
|
+
type: "monitor-status-changed",
|
|
577
|
+
title: "Monitor status reverted",
|
|
578
|
+
message: defaultStatusName
|
|
579
|
+
? `Monitor status reverted to "${defaultStatusName}" because no monitoring criteria were met.`
|
|
580
|
+
: "Monitor status reverted to its default state because no monitoring criteria were met.",
|
|
581
|
+
at: OneUptimeDate.getCurrentDate(),
|
|
582
|
+
});
|
|
583
|
+
}
|
|
562
584
|
}
|
|
585
|
+
await releaseMutex();
|
|
586
|
+
await persistLatestMonitorPayload();
|
|
587
|
+
MonitorLogUtil.saveMonitorLog({
|
|
588
|
+
monitorId: monitor.id,
|
|
589
|
+
projectId: monitor.projectId,
|
|
590
|
+
dataToProcess: dataToProcess,
|
|
591
|
+
});
|
|
592
|
+
return response;
|
|
563
593
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
await Semaphore.release(mutex);
|
|
567
|
-
}
|
|
568
|
-
catch (err) {
|
|
569
|
-
logger.error(err);
|
|
570
|
-
}
|
|
594
|
+
finally {
|
|
595
|
+
await releaseMutex();
|
|
571
596
|
}
|
|
572
|
-
await persistLatestMonitorPayload();
|
|
573
|
-
MonitorLogUtil.saveMonitorLog({
|
|
574
|
-
monitorId: monitor.id,
|
|
575
|
-
projectId: monitor.projectId,
|
|
576
|
-
dataToProcess: dataToProcess,
|
|
577
|
-
});
|
|
578
|
-
return response;
|
|
579
597
|
}
|
|
580
598
|
static async checkProbeAgreement(input) {
|
|
581
599
|
var _a, _b, _c, _d, _e, _f, _g;
|