Add route, controller, db operations, and validation for aggregate monitor stats

This commit is contained in:
Alex Holliday committed 2024-09-03 14:39:16 -07:00
1 parent 88316de306
commit bc0df325d1
6 files changed
+137 -2

No files matched your search

+83
View File
@@ -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,