diff --git a/client/src/Hooks/monitorHooks.js b/client/src/Hooks/monitorHooks.js index 970b5d97f..eb1e7acdc 100644 --- a/client/src/Hooks/monitorHooks.js +++ b/client/src/Hooks/monitorHooks.js @@ -369,6 +369,8 @@ const useUpdateMonitor = () => { setIsLoading(true); const updatedFields = { name: monitor.name, + statusWindowSize: monitor.statusWindowSize, + statusWindowThreshold: monitor.statusWindowThreshold, description: monitor.description, interval: monitor.interval, notifications: monitor.notifications, diff --git a/client/src/Pages/Uptime/Create/index.jsx b/client/src/Pages/Uptime/Create/index.jsx index 668d840af..3f905fa11 100644 --- a/client/src/Pages/Uptime/Create/index.jsx +++ b/client/src/Pages/Uptime/Create/index.jsx @@ -55,6 +55,8 @@ const UptimeCreate = ({ isClone = false }) => { // States const [monitor, setMonitor] = useState({ type: "http", + statusWindowSize: 5, + statusWindowThreshold: 60, matchMethod: "equal", expectedValue: "", jsonPath: "", @@ -177,7 +179,10 @@ const UptimeCreate = ({ isClone = false }) => { ? `http${https ? "s" : ""}://` + monitor.url : monitor.url, name: monitor.name || monitor.url.substring(0, 50), + statusWindowSize: monitor.statusWindowSize, + statusWindowThreshold: monitor.statusWindowThreshold, type: monitor.type, + port: monitor.type === "port" || monitor.type === "game" ? monitor.port : undefined, interval: monitor.interval, @@ -192,6 +197,8 @@ const UptimeCreate = ({ isClone = false }) => { _id: monitor._id, url: monitor.url, name: monitor.name || monitor.url.substring(0, 50), + statusWindowSize: monitor.statusWindowSize, + statusWindowThreshold: monitor.statusWindowThreshold, type: monitor.type, matchMethod: monitor.matchMethod, expectedValue: monitor.expectedValue, @@ -602,6 +609,39 @@ const UptimeCreate = ({ isClone = false }) => { /> + + + + {t("createMonitorPage.incidentConfigTitle")} + + + {t("createMonitorPage.incidentConfigDescription")} + + + + + + + to get the full container ID.", + "game": "Enter the IP address or hostname and the port number to ping (e.g., 192.168.1.100 or example.com) and choose game type.", "http": "Enter the URL or IP to monitor (e.g., https://example.com/ or 192.168.1.100) and add a clear display name that appears on the dashboard.", "ping": "Enter the IP address or hostname to ping (e.g., 192.168.1.100 or example.com) and add a clear display name that appears on the dashboard.", - "port": "Enter the URL or IP of the server, the port number and a clear display name that appears on the dashboard.", - "game": "Enter the IP address or hostname and the port number to ping (e.g., 192.168.1.100 or example.com) and choose game type." + "port": "Enter the URL or IP of the server, the port number and a clear display name that appears on the dashboard." }, "uptimeMonitor": { "fallback": { @@ -1066,5 +1071,6 @@ "websiteMonitoring": "Website monitoring", "websiteMonitoringDescription": "Use HTTP(s) to monitor your website or API endpoint.", "whenNewIncident": "When there is a new incident,", - "window": "window" + "window": "window", + "YourPhoto": "Profile photo" } diff --git a/server/src/service/infrastructure/statusService.js b/server/src/service/infrastructure/statusService.js index 0c3434df0..eac2d34bd 100755 --- a/server/src/service/infrastructure/statusService.js +++ b/server/src/service/infrastructure/statusService.js @@ -117,13 +117,18 @@ class StatusService { // Update running stats this.updateRunningStats({ monitor, networkResponse }); + // If the status window size has changed, empty + while (monitor.statusWindow.length > monitor.statusWindowSize) { + monitor.statusWindow.shift(); + } + // Update status sliding window monitor.statusWindow.push(status); if (monitor.statusWindow.length > monitor.statusWindowSize) { monitor.statusWindow.shift(); } - if (!monitor.status) { + if (monitor.status === undefined || monitor.status === null) { monitor.status = status; } @@ -145,10 +150,16 @@ class StatusService { // Check if threshold has been met const failures = monitor.statusWindow.filter((s) => s === false).length; - const failureRate = failures / monitor.statusWindow.length; + const failureRate = (failures / monitor.statusWindow.length) * 100; + + console.log({ + failureRate, + status: monitor.status, + statusWindow: monitor.statusWindow, + }); // If threshold has been met and the monitor is not already down, mark down: - if (failureRate > monitor.statusWindowThreshold && monitor.status !== false) { + if (failureRate >= monitor.statusWindowThreshold && monitor.status !== false) { newStatus = false; statusChanged = true; } diff --git a/server/src/validation/joi.js b/server/src/validation/joi.js index 31f8e97c0..725004afa 100755 --- a/server/src/validation/joi.js +++ b/server/src/validation/joi.js @@ -155,6 +155,8 @@ const createMonitorBodyValidation = joi.object({ name: joi.string().required(), description: joi.string().required(), type: joi.string().required(), + statusWindowSize: joi.number().min(1).max(20).default(5), + statusWindowThreshold: joi.number().min(1).max(100).default(60), url: joi.string().required(), ignoreTlsErrors: joi.boolean().default(false), port: joi.number(), @@ -183,6 +185,8 @@ const createMonitorsBodyValidation = joi.array().items( const editMonitorBodyValidation = joi.object({ name: joi.string(), + statusWindowSize: joi.number().min(1).max(20).default(5), + statusWindowThreshold: joi.number().min(1).max(100).default(60), description: joi.string(), interval: joi.number(), notifications: joi.array().items(joi.string()),