From 8d9803fef0099a2b26b42d54d7bbfd6bebd583a0 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Wed, 23 Oct 2024 13:46:27 +0800 Subject: [PATCH] Added methods for handleHardwareUpdates, refactored sending notifications to allow for arbitrary templates --- Server/service/networkService.js | 96 ++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 18 deletions(-) diff --git a/Server/service/networkService.js b/Server/service/networkService.js index e90180835..3e9582fd6 100644 --- a/Server/service/networkService.js +++ b/Server/service/networkService.js @@ -34,24 +34,24 @@ class NetworkService { } /** - * Handles the notification process for a monitor. + * Handles notifications for a given monitor configuration. * - * @param {Object} monitor - The monitor object containing monitor details. - * @param {boolean} isAlive - The status of the monitor (true if up, false if down). - * @returns {Promise} - */ async handleNotification(monitor, isAlive) { + * @param {Object} config - The configuration object for the notification. + * @param {Object} config.monitor - The monitor object containing the monitor ID. + * @param {string} config.template - The email template to be used. + * @param {Object} config.context - The context for the email template. + * @param {string} config.subject - The subject of the email. + */ + async handleNotification(config) { try { - let template = isAlive === true ? "serverIsUpTemplate" : "serverIsDownTemplate"; - let status = isAlive === true ? "up" : "down"; - - const notifications = await this.db.getNotificationsByMonitorId(monitor._id); + const notifications = await this.db.getNotificationsByMonitorId(config.monitor._id); for (const notification of notifications) { if (notification.type === "email") { await this.emailService.buildAndSendEmail( - template, - { monitorName: monitor.name, monitorUrl: monitor.url }, + config.template, + config.context, notification.address, - `Monitor ${monitor.name} is ${status}` + config.subject ); } } @@ -69,9 +69,10 @@ class NetworkService { * * @param {Object} job - The job object containing job details. * @param {boolean} isAlive - The status of the monitor (true if up, false if down). + * @param {Object} [hardwareData] - The hardware data for the monitor. * @returns {Promise} */ - async handleStatusUpdate(job, isAlive) { + async handleStatusUpdate(job, isAlive, hardwareData) { let monitor; const { _id } = job.data; @@ -98,9 +99,19 @@ class NetworkService { await monitor.save(); if (oldStatus !== undefined && oldStatus !== isAlive) { - this.handleNotification(monitor, isAlive); + const config = { + monitor: monitor, + template: isAlive === true ? "serverIsUpTemplate" : "serverIsDownTemplate", + context: { monitorName: monitor.name, monitorUrl: monitor.url }, + subject: + (subject = `Monitor ${monitor.name} is ${isAlive === true ? "up" : "down"}`), + }; + this.handleNotification(config); } } + if (monitor.type === this.TYPE_HARDWARE) { + this.handleHardwareUpdate(monitor, hardwareData); + } } catch (error) { this.logger.error(error.message, { method: "handleStatusUpdate", @@ -110,6 +121,55 @@ class NetworkService { } } + async handleHardwareUpdate(monitor, hardwareData) { + //Get Thresholds + const thresholds = monitor?.thresholds; + if (thresholds === undefined) { + return; + } + //Get Values + const cpuUsage = hardwareData?.cpu?.usage_percent; + const memoryUsage = hardwareData?.memory?.usage_percent; + const diskUsage = hardwareData?.disk[0]?.usage_percent; + + // Return early if no values + if (cpuUsage === undefined && memoryUsage === undefined && diskUsage === undefined) { + return; + } + + // Return early if all values are below thresholds + if ( + cpuUsage < thresholds.usage_cpu && + memoryUsage < thresholds.usage_memory && + diskUsage < thresholds.usage_disk + ) { + return; + } + + let context = { + message: "Threshold(s) exceeded:", + }; + if (cpuUsage > thresholds.usage_cpu) { + context.cpu = `CPU USAGE: ${cpuUsage * 100}% > ${thresholds.usage_cpu * 100}%`; + } + + if (memoryUsage > thresholds.usage_memory) { + context.memory = `MEMORY USAGE: ${memoryUsage * 100}% > ${thresholds.usage_memory * 100}%`; + } + + if (diskUsage > thresholds.usage_disk) { + context.disk = `DISK USAGE: ${diskUsage * 100}% > ${thresholds.usage_disk * 100}%`; + } + + const config = { + monitor: monitor, + template: "thresholdViolatedTemplate", + context: context, + subject: `Threshold Violated for ${monitor.name}`, + }; + this.handleNotification(config); + } + /** * Measures the response time of an asynchronous operation. * @param {Function} operation - An asynchronous operation to measure. @@ -308,13 +368,13 @@ class NetworkService { frequency: 266, temperature: null, free_percent: null, - usage_percent: null, + usage_percent: 1, }, memory: { total_bytes: 4, available_bytes: 4, used_bytes: 2, - usage_percent: 0.5, + usage_percent: 1, }, disk: [ { @@ -322,7 +382,7 @@ class NetworkService { write_speed_bytes: 3, total_bytes: 10, free_bytes: 2, - usage_percent: 0.8, + usage_percent: 1, }, ], host: { @@ -369,7 +429,7 @@ class NetworkService { }; this.logAndStoreCheck(nullData, this.db.createHardwareCheck); } finally { - this.handleStatusUpdate(job, isAlive); + this.handleStatusUpdate(job, isAlive, hardwareData); } }