oneuptime/Ingestor/API/Monitor.ts

300 lines
10 KiB
TypeScript
Raw Normal View History

2023-05-03 20:13:00 +00:00
import Express, {
ExpressRequest,
ExpressResponse,
ExpressRouter,
NextFunction,
2023-08-07 12:11:09 +00:00
OneUptimeRequest,
2023-05-03 20:13:00 +00:00
} from 'CommonServer/Utils/Express';
import Response from 'CommonServer/Utils/Response';
2023-05-05 11:55:51 +00:00
import ProbeAuthorization from '../Middleware/ProbeAuthorization';
import MonitorProbe from 'Model/Models/MonitorProbe';
import MonitorProbeService from 'CommonServer/Services/MonitorProbeService';
import QueryHelper from 'CommonServer/Types/Database/QueryHelper';
2023-05-03 20:13:00 +00:00
import OneUptimeDate from 'Common/Types/Date';
2023-05-05 11:55:51 +00:00
import { ProbeExpressRequest } from '../Types/Request';
import BadDataException from 'Common/Types/Exception/BadDataException';
2023-05-05 12:02:23 +00:00
import CronTab from 'CommonServer/Utils/CronTab';
2023-05-05 11:55:51 +00:00
import Monitor from 'Model/Models/Monitor';
import PositiveNumber from 'Common/Types/PositiveNumber';
2023-05-05 12:02:23 +00:00
import { JSONObject } from 'Common/Types/JSON';
2023-05-11 12:25:40 +00:00
import SubscriptionStatus from 'Common/Types/Billing/SubscriptionStatus';
2023-08-06 19:57:58 +00:00
import ObjectID from 'Common/Types/ObjectID';
import ClusterKeyAuthorization from 'CommonServer/Middleware/ClusterKeyAuthorization';
import LIMIT_MAX from 'Common/Types/Database/LimitMax';
2023-10-02 11:13:37 +00:00
import SortOrder from 'Common/Types/BaseDatabase/SortOrder';
2023-08-07 12:11:09 +00:00
import Query from 'CommonServer/Types/Database/Query';
2023-09-22 15:36:04 +00:00
import logger from 'CommonServer/Utils/Logger';
import BaseModel from 'Common/Models/BaseModel';
2023-05-03 20:13:00 +00:00
const router: ExpressRouter = Express.getRouter();
2023-08-07 12:11:09 +00:00
const getMonitorFetchQuery: Function = (
probeId: ObjectID
): Query<MonitorProbe> => {
const monitorFetchQuery: Query<MonitorProbe> = {
probeId: probeId,
isEnabled: true,
nextPingAt: QueryHelper.lessThanEqualToOrNull(
OneUptimeDate.getCurrentDate()
),
monitor: {
disableActiveMonitoring: false, // do not fetch if disabled is true.
2023-09-08 09:38:43 +00:00
disableActiveMonitoringBecauseOfManualIncident: false,
disableActiveMonitoringBecauseOfScheduledMaintenanceEvent: false,
2023-08-07 12:11:09 +00:00
},
project: {
// get only active projects
paymentProviderSubscriptionStatus: QueryHelper.equalToOrNull([
SubscriptionStatus.Active,
SubscriptionStatus.Trialing,
]),
paymentProviderMeteredSubscriptionStatus: QueryHelper.equalToOrNull(
[SubscriptionStatus.Active, SubscriptionStatus.Trialing]
),
},
};
return monitorFetchQuery;
};
2023-08-06 19:57:58 +00:00
router.get(
'/monitor/pending-list/:probeId',
ClusterKeyAuthorization.isAuthorizedServiceMiddleware,
async (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction
): Promise<void> => {
try {
if (!req.params['probeId']) {
return Response.sendErrorResponse(
req,
res,
new BadDataException('Probe not found')
);
}
//get list of monitors to be monitored
const monitorProbes: Array<MonitorProbe> =
await MonitorProbeService.findBy({
2023-08-07 12:11:09 +00:00
query: getMonitorFetchQuery(
new ObjectID(req.params['probeId'])
),
2023-08-07 11:17:13 +00:00
sort: {
nextPingAt: SortOrder.Ascending,
},
2023-08-06 19:59:46 +00:00
select: {
2023-08-07 11:17:13 +00:00
nextPingAt: true,
2023-08-06 19:59:46 +00:00
probeId: true,
monitorId: true,
monitor: {
monitorSteps: true,
monitorType: true,
monitoringInterval: true,
},
},
2023-08-06 19:57:58 +00:00
skip: 0,
limit: LIMIT_MAX,
props: {
isRoot: true,
},
});
const monitors: Array<Monitor> = monitorProbes
.map((monitorProbe: MonitorProbe) => {
return monitorProbe.monitor!;
})
.filter((monitor: Monitor) => {
return Boolean(monitor._id);
});
// return the list of monitors to be monitored
return Response.sendEntityArrayResponse(
req,
res,
monitors,
new PositiveNumber(monitors.length),
Monitor
);
} catch (err) {
return next(err);
}
}
);
// This API returns the count of the monitor waiting to be monitored.
router.get(
'/monitor/pending-count/:probeId',
ClusterKeyAuthorization.isAuthorizedServiceMiddleware,
async (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction
): Promise<void> => {
try {
if (!req.params['probeId']) {
return Response.sendErrorResponse(
req,
res,
new BadDataException('Probe not found')
);
}
//get list of monitors to be monitored
const monitorProbesCount: PositiveNumber =
await MonitorProbeService.countBy({
2023-08-07 12:11:09 +00:00
query: getMonitorFetchQuery(
new ObjectID(req.params['probeId'])
),
props: {
isRoot: true,
},
});
//get list of monitors to be monitored
const firstMonitorToBeFetched: MonitorProbe | null =
await MonitorProbeService.findOneBy({
query: getMonitorFetchQuery(
new ObjectID(req.params['probeId'])
),
select: {
nextPingAt: true,
monitorId: true,
},
sort: {
nextPingAt: SortOrder.Ascending,
2023-08-06 19:57:58 +00:00
},
props: {
isRoot: true,
},
});
return Response.sendJsonObjectResponse(req, res, {
2023-08-07 12:11:09 +00:00
firstMonitorToBeFetched: firstMonitorToBeFetched
? BaseModel.toJSONObject(
2023-08-07 12:11:09 +00:00
firstMonitorToBeFetched,
MonitorProbe
)
: null,
2023-08-06 19:57:58 +00:00
count: monitorProbesCount.toNumber(),
2023-08-07 12:11:09 +00:00
nextPingAt: firstMonitorToBeFetched?.nextPingAt,
friendlyNextPingAt: firstMonitorToBeFetched?.nextPingAt
? OneUptimeDate.getDateAsFormattedStringInMultipleTimezones(
firstMonitorToBeFetched?.nextPingAt
)
: '',
2023-08-06 19:57:58 +00:00
});
} catch (err) {
return next(err);
}
}
);
2023-05-03 20:13:00 +00:00
router.post(
'/monitor/list',
2023-05-05 11:55:51 +00:00
ProbeAuthorization.isAuthorizedServiceMiddleware,
2023-05-03 20:13:00 +00:00
async (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction
): Promise<void> => {
try {
2023-05-05 12:02:23 +00:00
const data: JSONObject = req.body;
const limit: number = (data['limit'] as number) || 100;
2023-05-05 11:55:51 +00:00
2023-05-05 12:02:23 +00:00
if (
!(req as ProbeExpressRequest).probe ||
!(req as ProbeExpressRequest).probe?.id
) {
2023-05-03 20:13:00 +00:00
return Response.sendErrorResponse(
req,
res,
2023-05-05 11:55:51 +00:00
new BadDataException('Probe not found')
2023-05-03 20:13:00 +00:00
);
}
2023-05-05 11:55:51 +00:00
//get list of monitors to be monitored
2023-05-05 12:02:23 +00:00
const monitorProbes: Array<MonitorProbe> =
await MonitorProbeService.findBy({
2023-08-07 12:11:09 +00:00
query: getMonitorFetchQuery(
(req as OneUptimeRequest).probe?.id
),
2023-08-06 20:54:12 +00:00
sort: {
nextPingAt: SortOrder.Ascending,
},
2023-05-05 12:02:23 +00:00
skip: 0,
limit: limit,
select: {
2023-08-07 09:18:12 +00:00
nextPingAt: true,
2023-05-05 12:02:23 +00:00
probeId: true,
monitorId: true,
monitor: {
monitorSteps: true,
monitorType: true,
monitoringInterval: true,
},
},
props: {
isRoot: true,
},
});
2023-05-03 20:13:00 +00:00
2023-05-05 11:55:51 +00:00
// update the lastMonitoredAt field of the monitors
2023-05-03 20:13:00 +00:00
2023-05-05 12:02:23 +00:00
for (const monitorProbe of monitorProbes) {
2023-05-11 15:29:38 +00:00
if (!monitorProbe.monitor) {
continue;
}
2023-09-22 15:36:04 +00:00
let nextPing: Date = OneUptimeDate.addRemoveMinutes(
OneUptimeDate.getCurrentDate(),
1
);
try {
nextPing = CronTab.getNextExecutionTime(
monitorProbe?.monitor?.monitoringInterval as string
);
} catch (err) {
logger.error(err);
}
2023-05-05 11:55:51 +00:00
await MonitorProbeService.updateOneById({
id: monitorProbe.id!,
data: {
lastPingAt: OneUptimeDate.getCurrentDate(),
2023-09-22 15:36:04 +00:00
nextPingAt: nextPing,
2023-05-05 11:55:51 +00:00
},
props: {
2023-05-05 12:02:23 +00:00
isRoot: true,
},
2023-05-05 11:55:51 +00:00
});
}
2023-05-03 20:13:00 +00:00
2023-05-11 15:29:38 +00:00
const monitors: Array<Monitor> = monitorProbes
.map((monitorProbe: MonitorProbe) => {
2023-05-05 12:02:23 +00:00
return monitorProbe.monitor!;
2023-05-11 15:29:38 +00:00
})
.filter((monitor: Monitor) => {
2023-05-12 11:29:51 +00:00
return Boolean(monitor._id);
2023-05-11 15:29:38 +00:00
});
2023-05-05 11:55:51 +00:00
// return the list of monitors to be monitored
2023-05-05 12:02:23 +00:00
return Response.sendEntityArrayResponse(
req,
res,
monitors,
new PositiveNumber(monitors.length),
Monitor
);
2023-05-03 20:13:00 +00:00
} catch (err) {
return next(err);
}
}
);
export default router;