From 27415aeca624ec6b90d713614fdd69b8cf26d282 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Mon, 18 Aug 2025 15:34:15 -0700 Subject: [PATCH 1/3] fix undefined bug, updated server validation --- .../src/service/infrastructure/statusService.js | 17 ++++++++++++++--- server/src/validation/joi.js | 4 ++++ 2 files changed, 18 insertions(+), 3 deletions(-) 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()), From ced2417c986dd0a56927903c194cd3295749fb8f Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Mon, 18 Aug 2025 15:34:30 -0700 Subject: [PATCH 2/3] add incident config --- client/src/Hooks/monitorHooks.js | 2 ++ client/src/Pages/Uptime/Create/index.jsx | 44 ++++++++++++++++++++++++ client/src/Validation/validation.js | 10 ++++++ 3 files changed, 56 insertions(+) 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..c763071da 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,43 @@ const UptimeCreate = ({ isClone = false }) => { /> + + + + Incidents + + + { + "A sliding window is used to determine when a monitor goes down. The status of a monitor will only change when the percentage of checks in the sliding window meet the specified value." + } + + + + + + + Date: Mon, 18 Aug 2025 15:46:41 -0700 Subject: [PATCH 3/3] extract strings, sort json --- client/src/Pages/Uptime/Create/index.jsx | 12 +-- client/src/locales/en.json | 104 ++++++++++++----------- 2 files changed, 59 insertions(+), 57 deletions(-) diff --git a/client/src/Pages/Uptime/Create/index.jsx b/client/src/Pages/Uptime/Create/index.jsx index c763071da..3f905fa11 100644 --- a/client/src/Pages/Uptime/Create/index.jsx +++ b/client/src/Pages/Uptime/Create/index.jsx @@ -615,18 +615,16 @@ const UptimeCreate = ({ isClone = false }) => { component="h2" variant="h2" > - Incidents + {t("createMonitorPage.incidentConfigTitle")} - { - "A sliding window is used to determine when a monitor goes down. The status of a monitor will only change when the percentage of checks in the sliding window meet the specified value." - } + {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" }