mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-05-02 22:49:19 -05:00
Add route, controller, db operations, and validation for aggregate monitor stats
This commit is contained in:
@@ -6,12 +6,13 @@ const {
|
||||
editMonitorBodyValidation,
|
||||
getMonitorsByTeamIdQueryValidation,
|
||||
pauseMonitorParamValidation,
|
||||
getMonitorAggregateStatsParamValidation,
|
||||
getMonitorAggregateStatsQueryValidation,
|
||||
} = require("../validation/joi");
|
||||
|
||||
const sslChecker = require("ssl-checker");
|
||||
const SERVICE_NAME = "monitorController";
|
||||
const { errorMessages, successMessages } = require("../utils/messages");
|
||||
const { runInNewContext } = require("vm");
|
||||
|
||||
/**
|
||||
* Returns all monitors
|
||||
@@ -35,6 +36,44 @@ const getAllMonitors = async (req, res, next) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns agregate stats for a monitor
|
||||
* @async
|
||||
* @param {Express.Request} req
|
||||
* @param {Express.Response} res
|
||||
* @returns {Promise<Express.Response>}
|
||||
* @throws {Error}
|
||||
*/
|
||||
|
||||
const getMonitorAggregateStats = async (req, res, next) => {
|
||||
try {
|
||||
await getMonitorAggregateStatsParamValidation.validateAsync(req.params);
|
||||
await getMonitorAggregateStatsQueryValidation.validateAsync(req.query);
|
||||
} catch (error) {
|
||||
error.status = 422;
|
||||
error.message =
|
||||
error.details?.[0]?.message || error.message || "Validation Error";
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { monitorId } = req.params;
|
||||
const dateRange = req.query.dateRange;
|
||||
const aggregateStats = await req.db.getMonitorAggregateStats(
|
||||
monitorId,
|
||||
dateRange
|
||||
);
|
||||
return res.json({
|
||||
success: true,
|
||||
msg: successMessages.MONTIOR_STATS_BY_ID,
|
||||
data: aggregateStats,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns monitor stats for monitor with matching ID
|
||||
* @async
|
||||
@@ -376,6 +415,7 @@ const pauseMonitor = async (req, res, next) => {
|
||||
|
||||
module.exports = {
|
||||
getAllMonitors,
|
||||
getMonitorAggregateStats,
|
||||
getMonitorStatsById,
|
||||
getMonitorCertificate,
|
||||
getMonitorById,
|
||||
|
||||
@@ -64,6 +64,7 @@ const {
|
||||
|
||||
const {
|
||||
getAllMonitors,
|
||||
getMonitorAggregateStats,
|
||||
getMonitorStatsById,
|
||||
getMonitorById,
|
||||
getMonitorsByTeamId,
|
||||
@@ -144,6 +145,7 @@ module.exports = {
|
||||
resetPassword,
|
||||
checkSuperadmin,
|
||||
getAllMonitors,
|
||||
getMonitorAggregateStats,
|
||||
getMonitorStatsById,
|
||||
getMonitorById,
|
||||
getMonitorsByTeamId,
|
||||
|
||||
@@ -143,6 +143,88 @@ const getStatusBarValues = (monitor, checks) => {
|
||||
}
|
||||
return statusBarValues.reverse();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get aggregate monitor stats for charts
|
||||
* @async
|
||||
* @param {Express.Request} req
|
||||
* @param {Express.Response} res
|
||||
* @returns {Promise<Monitor>}
|
||||
* @throws {Error}
|
||||
*/
|
||||
const getMonitorAggregateStats = async (monitorId, dateRange) => {
|
||||
const startDates = {
|
||||
day: new Date(new Date().setDate(new Date().getDate() - 1)),
|
||||
|
||||
week: new Date(new Date().setDate(new Date().getDate() - 7)),
|
||||
month: new Date(new Date().setMonth(new Date().getMonth() - 1)),
|
||||
};
|
||||
|
||||
try {
|
||||
const startDate = startDates[dateRange];
|
||||
if (!startDate) {
|
||||
throw new Error("Invalid date range specified");
|
||||
}
|
||||
const endDate = new Date();
|
||||
|
||||
const checks = await Check.find({
|
||||
monitorId: monitorId,
|
||||
createdAt: {
|
||||
$gte: startDate,
|
||||
$lte: endDate,
|
||||
},
|
||||
});
|
||||
|
||||
let groupedChecks;
|
||||
// Group checks by hour if range is day
|
||||
if (dateRange === "day") {
|
||||
groupedChecks = checks.reduce((acc, check) => {
|
||||
const hour = new Date(check.createdAt).getHours();
|
||||
if (!acc[hour]) {
|
||||
acc[hour] = { hour, checks: [] };
|
||||
}
|
||||
acc[hour].checks.push(check);
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
// Group checks by day if range is week or month
|
||||
else {
|
||||
groupedChecks = checks.reduce((acc, check) => {
|
||||
const day = new Date(check.createdAt).toISOString().split("T")[0]; // Extract the date part
|
||||
if (!acc[day]) {
|
||||
acc[day] = { day, checks: [] };
|
||||
}
|
||||
acc[day].checks.push(check);
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
// Map grouped checks to stats
|
||||
stats = Object.values(groupedChecks).map((group) => {
|
||||
const totalChecks = group.checks.length;
|
||||
const totalIncidents = group.checks.filter(
|
||||
(check) => check.status === false
|
||||
).length;
|
||||
const avgResponseTime =
|
||||
group.checks.reduce((sum, check) => sum + check.responseTime, 0) /
|
||||
totalChecks;
|
||||
|
||||
return {
|
||||
hour: group.hour,
|
||||
day: group.day,
|
||||
totalChecks,
|
||||
totalIncidents,
|
||||
avgResponseTime: `${avgResponseTime.toFixed(2)}ms`,
|
||||
};
|
||||
});
|
||||
|
||||
return stats;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get stats by monitor ID
|
||||
* @async
|
||||
@@ -452,6 +534,7 @@ const editMonitor = async (candidateId, candidateMonitor) => {
|
||||
|
||||
module.exports = {
|
||||
getAllMonitors,
|
||||
getMonitorAggregateStats,
|
||||
getMonitorStatsById,
|
||||
getMonitorById,
|
||||
getMonitorsByTeamId,
|
||||
|
||||
@@ -3,6 +3,7 @@ const monitorController = require("../controllers/monitorController");
|
||||
const { isAllowed } = require("../middleware/isAllowed");
|
||||
|
||||
router.get("/", monitorController.getAllMonitors);
|
||||
router.get("/aggregate/:monitorId", monitorController.getMonitorAggregateStats);
|
||||
router.get("/stats/:monitorId", monitorController.getMonitorStatsById);
|
||||
router.get("/certificate/:monitorId", monitorController.getMonitorCertificate);
|
||||
router.get("/:monitorId", monitorController.getMonitorById);
|
||||
|
||||
@@ -201,6 +201,13 @@ const pauseMonitorParamValidation = joi.object({
|
||||
monitorId: joi.string().required(),
|
||||
});
|
||||
|
||||
const getMonitorAggregateStatsParamValidation = joi.object({
|
||||
monitorId: joi.string().required(),
|
||||
});
|
||||
const getMonitorAggregateStatsQueryValidation = joi.object({
|
||||
dateRange: joi.string().valid("day", "week", "month"),
|
||||
});
|
||||
|
||||
//****************************************
|
||||
// Alerts
|
||||
//****************************************
|
||||
@@ -357,6 +364,8 @@ module.exports = {
|
||||
getMonitorByIdQueryValidation,
|
||||
getMonitorsByTeamIdValidation,
|
||||
getMonitorsByTeamIdQueryValidation,
|
||||
getMonitorAggregateStatsParamValidation,
|
||||
getMonitorAggregateStatsQueryValidation,
|
||||
editMonitorBodyValidation,
|
||||
pauseMonitorParamValidation,
|
||||
editUserParamValidation,
|
||||
|
||||
Reference in New Issue
Block a user