Merge pull request #3200 from bluewave-labs/fix/checks

fix/checks
This commit is contained in:
Alexander Holliday authored and GitHub committed 2026-01-27 12:52:20 -08:00
commit 81e73e5adf
10 files changed
+103 -50

No files matched your search

+3 -3
View File
@@ -137,7 +137,7 @@ const useFetchChecksByMonitor = ({
return [checks, checksCount, isLoading, networkError];
};
const useFetchChecksSummaryByTeamId = ({ updateTrigger } = {}) => {
const useFetchChecksSummaryByTeamId = ({ dateRange, updateTrigger } = {}) => {
const [summary, setSummary] = useState(undefined);
const [isLoading, setIsLoading] = useState(false);
const [networkError, setNetworkError] = useState(false);
@@ -147,7 +147,7 @@ const useFetchChecksSummaryByTeamId = ({ updateTrigger } = {}) => {
try {
setIsLoading(true);
const res = await networkService.getChecksAndSummaryByTeamId();
const res = await networkService.getChecksAndSummaryByTeamId({ dateRange });
setSummary(res.data.data);
} catch (error) {
setNetworkError(true);
@@ -158,7 +158,7 @@ const useFetchChecksSummaryByTeamId = ({ updateTrigger } = {}) => {
};
fetchSummary();
}, [updateTrigger]);
}, [dateRange, updateTrigger]);
return [summary, isLoading, networkError];
};
@@ -19,7 +19,7 @@ import { useState } from "react";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
import { useFetchChecksTeam, useFetchChecksByMonitor } from "@/Hooks/checkHooks.js";
import { Button, Typography, useTheme } from "@mui/material";
import { Typography, useTheme } from "@mui/material";
import { lighten } from "@mui/material/styles";
const GetTooltip = (row) => {
+2 -2
View File
@@ -5,7 +5,6 @@ import GenericFallback from "@/Components/v1/GenericFallback/index.jsx";
import IncidentTable from "./Components/IncidentTable/index.jsx";
import OptionsHeader from "./Components/OptionsHeader/index.jsx";
import StatusBoxes from "./Components/StatusBoxes/index.jsx";
import { Box, Button } from "@mui/material";
//Utils
import { useTheme } from "@emotion/react";
@@ -26,7 +25,7 @@ const Checks = () => {
// Local state
const [selectedMonitor, setSelectedMonitor] = useState("0");
const [filter, setFilter] = useState(undefined);
const [dateRange, setDateRange] = useState(undefined);
const [dateRange, setDateRange] = useState("hour");
const [monitorLookup, setMonitorLookup] = useState(undefined);
const [updateTrigger, setUpdateTrigger] = useState(false);
@@ -36,6 +35,7 @@ const Checks = () => {
const theme = useTheme();
const [monitors, , isLoading, networkError] = useFetchMonitorsByTeamId({});
const [summary, isLoadingSummary, networkErrorSummary] = useFetchChecksSummaryByTeamId({
dateRange,
updateTrigger,
});
const { monitorId } = useParams();
+73
View File
@@ -154,6 +154,79 @@ export interface ChecksResponse {
checksCount: number;
}
export type MonitorType =
| "http"
| "ping"
| "pagespeed"
| "hardware"
| "docker"
| "port"
| "game"
| "unknown";
export interface ChecksQueryResult {
checksCount: number;
checks: Check[];
}
export interface PageSpeedChecksResult {
monitorType: "pagespeed";
checks: Check[];
}
export interface HardwareChecksResult {
monitorType: "hardware";
aggregateData: {
totalChecks: number;
};
upChecks: {
totalChecks: number;
};
checks: Array<{
_id: string;
avgCpuUsage: number;
avgMemoryUsage: number;
avgTemperature: number[];
disks: Array<{
name: string;
readSpeed: number;
writeSpeed: number;
totalBytes: number;
freeBytes: number;
usagePercent: number;
}>;
net: Array<{
name: string;
bytesSentPerSecond: number;
deltaBytesRecv: number;
deltaPacketsSent: number;
deltaPacketsRecv: number;
deltaErrIn: number;
deltaErrOut: number;
deltaDropIn: number;
deltaDropOut: number;
deltaFifoIn: number;
deltaFifoOut: number;
}>;
}>;
}
export interface UptimeChecksResult {
monitorType: Exclude<MonitorType, "hardware" | "pagespeed">;
groupedChecks: GroupedCheck[];
groupedUpChecks: GroupedCheck[];
groupedDownChecks: GroupedCheck[];
uptimePercentage: number;
avgResponseTime: number;
}
export interface ChecksSummary {
totalChecks: number;
resolvedChecks: number;
downChecks: number;
cannotResolveChecks: number;
}
export type CheckSnapshot = Omit<
Check,
"metadata" | "ack" | "ackAt" | "expiry" | "__v" | "updatedAt"
+2 -2
View File
@@ -594,8 +594,8 @@ class NetworkService {
* @async
* @returns {Promise<AxiosResponse>} The response from the axios GET request.
*/
getChecksAndSummaryByTeamId = async () => {
return this.axiosInstance.get(`/checks/team/summary`);
getChecksAndSummaryByTeamId = async ({ dateRange }) => {
return this.axiosInstance.get(`/checks/team/summary?dateRange=${dateRange}`);
};
/**
+2 -2
View File
@@ -54,8 +54,8 @@ async function ensureMonitor({ monitorId, teamId, userId, type }) {
async function run() {
const mongoUri = process.env.MONGO_URI ?? "mongodb://localhost:27017/uptime_db";
const monitorId = parseObjectId(process.env.MONITOR_ID ?? DEFAULT_MONITOR_ID, DEFAULT_MONITOR_ID);
const teamId = parseObjectId("69648b0578209af45f9ffe30");
const userId = parseObjectId("69648b0678209af45f9ffe32");
const teamId = parseObjectId("6971546de1b2bc3de6498e6e");
const userId = parseObjectId("6971546de1b2bc3de6498e70");
const monitorType = process.env.MONITOR_TYPE ?? DEFAULT_MONITOR_TYPE;
const total = Number(process.env.CHECK_TOTAL ?? DEFAULT_TOTAL);
const batchSize = Number(process.env.CHECK_BATCH_SIZE ?? DEFAULT_BATCH_SIZE);
+2 -1
View File
@@ -66,7 +66,8 @@ class CheckController {
getChecksSummaryByTeamId = async (req: Request, res: Response, next: NextFunction) => {
try {
const summary = await this.checkService.getChecksSummaryByTeamId({ teamId: req?.user?.teamId });
const dateRange = req.query?.dateRange || "hour";
const summary = await this.checkService.getChecksSummaryByTeamId({ teamId: req?.user?.teamId, dateRange });
return res.status(200).json({
success: true,
msg: "Checks summary retrieved successfully",
@@ -33,7 +33,7 @@ export interface IChecksRepository {
dateString: string,
options?: { type?: MonitorType }
): Promise<UptimeChecksResult | HardwareChecksResult | PageSpeedChecksResult>;
findSummaryByTeamId(teamId: string): Promise<ChecksSummary>;
findSummaryByTeamId(teamId: string, dateRange: string): Promise<ChecksSummary>;
// update
//delete
deleteByMonitorId(monitorId: string): Promise<number>;
@@ -365,51 +365,30 @@ class MongoChecksRepository implements IChecksRepository {
return this.findUptimeDateRangeChecks(options?.type ?? "http", monitorObjectId, startDate, endDate, dateString);
};
findSummaryByTeamId = async (teamId: string) => {
findSummaryByTeamId = async (teamId: string, dateRange: string) => {
const matchStage = {
"metadata.teamId": new mongoose.Types.ObjectId(teamId),
status: false,
...(dateRangeLookup[dateRange] && {
createdAt: {
$gte: dateRangeLookup[dateRange],
},
}),
};
const checks = await CheckModel.aggregate([
{ $match: matchStage },
{
$facet: {
summary: [
{
$group: {
_id: null,
totalChecks: { $sum: { $cond: [{ $eq: ["$status", false] }, 1, 0] } },
resolvedChecks: {
$sum: {
$cond: [{ $and: [{ $eq: ["$ack", true] }, { $eq: ["$status", false] }] }, 1, 0],
},
},
downChecks: {
$sum: {
$cond: [{ $and: [{ $eq: ["$ack", false] }, { $eq: ["$status", false] }] }, 1, 0],
},
},
cannotResolveChecks: {
$sum: {
$cond: [{ $eq: ["$statusCode", 5000] }, 1, 0],
},
},
},
},
{
$project: {
_id: 0,
},
},
],
},
},
{
$project: {
summary: { $arrayElemAt: ["$summary", 0] },
$group: {
_id: null,
totalChecks: { $sum: 1 },
resolvedChecks: { $sum: { $cond: [{ $eq: ["$ack", true] }, 1, 0] } },
downChecks: { $sum: { $cond: [{ $eq: ["$ack", false] }, 1, 0] } },
cannotResolveChecks: { $sum: { $cond: [{ $eq: ["$statusCode", 5000] }, 1, 0] } },
},
},
{ $project: { _id: 0 } },
]);
return checks[0].summary;
return checks[0] ?? { totalChecks: 0, resolvedChecks: 0, downChecks: 0, cannotResolveChecks: 0 };
};
deleteByMonitorId = async (monitorId: string): Promise<number> => {
+2 -2
View File
@@ -145,11 +145,11 @@ class CheckService {
return checkData;
};
getChecksSummaryByTeamId = async ({ teamId }: { teamId: string }) => {
getChecksSummaryByTeamId = async ({ teamId, dateRange }: { teamId: string; dateRange: string }) => {
if (!teamId) {
throw new AppError({ message: "No team ID in request", service: SERVICE_NAME, method: "getChecksSummaryByTeamId", status: 400 });
}
const summary = await this.checksRepository.findSummaryByTeamId(teamId);
const summary = await this.checksRepository.findSummaryByTeamId(teamId, dateRange);
return summary;
};