From 771cce98b5ee6a8de63307a31fb45f38fec6a470 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Mon, 17 Jun 2024 13:52:20 -0700 Subject: [PATCH] Checks now inserted into db during monitor status check --- Server/controllers/monitorController.js | 6 +- Server/db/MongoDB.js | 16 +---- Server/service/jobQueue.js | 2 +- Server/service/networkService.js | 86 ++++++++++++++++++------- 4 files changed, 69 insertions(+), 41 deletions(-) diff --git a/Server/controllers/monitorController.js b/Server/controllers/monitorController.js index c883d32bb..a8ef8aecc 100644 --- a/Server/controllers/monitorController.js +++ b/Server/controllers/monitorController.js @@ -162,9 +162,9 @@ const deleteMonitor = async (req, res, next) => { try { const monitor = await req.db.deleteMonitor(req, res, next); // Delete associated checks and alerts - console.log(monitor); - req.jobQueue.deleteJob(monitor); - + await req.jobQueue.deleteJob(monitor); + await req.db.deleteChecks(monitor._id); + await req.db.deleteAlertByMonitorId(monitor._id); /** * TODO * We should remove all checks and alerts associated with this monitor diff --git a/Server/db/MongoDB.js b/Server/db/MongoDB.js index fb2d3e6d7..ad37ee084 100644 --- a/Server/db/MongoDB.js +++ b/Server/db/MongoDB.js @@ -249,14 +249,12 @@ const deleteMonitor = async (req, res) => { const monitorId = req.params.monitorId; try { const monitor = await Monitor.findByIdAndDelete(monitorId); - deleteChecks(monitorId); - deleteAlertByMonitorId(monitorId); if (!monitor) { throw new Error(errorMessages.DB_FIND_MONTIOR_BY_ID(monitorId)); } - return monitor; } catch (error) { + console.log("CATHCING DELETE MONITOR ERROR"); throw error; } }; @@ -340,11 +338,7 @@ const getChecks = async (monitorId) => { const deleteChecks = async (monitorId) => { try { const result = await Check.deleteMany({ monitorId }); - if (result.deletedCount > 0) { - return result.deletedCount; - } else { - throw new Error(errorMessages.DB_DELETE_CHECKS(monitorId)); - } + return result.deletedCount; } catch (error) { throw error; } @@ -461,11 +455,7 @@ const editAlert = async (alertId, alertData) => { const deleteAlert = async (alertId) => { try { const result = await Alert.findByIdAndDelete(alertId); - if (result) { - return result; - } else { - throw new Error(errorMessages.DB_DELETE_ALERT(alertId)); - } + return result; } catch (error) { throw error; } diff --git a/Server/service/jobQueue.js b/Server/service/jobQueue.js index 511f01e9a..ae735ae86 100644 --- a/Server/service/jobQueue.js +++ b/Server/service/jobQueue.js @@ -59,7 +59,7 @@ class JobQueue { QUEUE_NAME, async (job) => { try { - await this.networkService.getStatus(job); + const res = await this.networkService.getStatus(job); } catch (error) { logger.error(`Error processing job ${job.id}: ${error.message}`, { service: SERVICE_NAME, diff --git a/Server/service/networkService.js b/Server/service/networkService.js index 1e1da69c2..1fa2daac4 100644 --- a/Server/service/networkService.js +++ b/Server/service/networkService.js @@ -1,6 +1,7 @@ const axios = require("axios"); const ping = require("ping"); const logger = require("../utils/logger"); +const Check = require("../models/Check"); class NetworkService { constructor(db) { @@ -10,6 +11,12 @@ class NetworkService { this.SERVICE_NAME = "NetworkService"; } + /** + * Measures the response time of an asynchronous operation. + * @param {Function} operation - An asynchronous operation to measure. + * @returns {Promise<{responseTime: number, response: any}>} An object containing the response time in milliseconds and the response from the operation. + * @throws {Error} The error object from the operation, contains response time. + */ async measureResponseTime(operation) { const startTime = Date.now(); try { @@ -17,10 +24,17 @@ class NetworkService { const endTime = Date.now(); return { responseTime: endTime - startTime, response }; } catch (error) { + const endTime = Date.now(); + error.responseTime = endTime - startTime; throw error; } } + /** + * Handles the ping operation for a given job, measures its response time, and logs the result. + * @param {Object} job - The job object containing data for the ping operation. + * @returns {Promise<{boolean}} The result of logging and storing the check + */ async handlePing(job) { const operation = async () => { const response = await ping.promise.probe(job.data.url); @@ -32,14 +46,17 @@ class NetworkService { operation ); const isAlive = response.alive; - await this.logAndStoreCheck(job, isAlive, responseTime); - return isAlive; + return await this.logAndStoreCheck(job, isAlive, responseTime); } catch (error) { - await this.logAndStoreCheck(job, false, 0, error); - return false; + return await this.logAndStoreCheck(job, false, error.responseTime, error); } } + /** + * Handles the http operation for a given job, measures its response time, and logs the result. + * @param {Object} job - The job object containing data for the ping operation. + * @returns {Promise<{boolean}} The result of logging and storing the check + */ async handleHttp(job) { const operation = async () => { const response = await axios.get(job.data.url); @@ -50,14 +67,18 @@ class NetworkService { operation ); const isAlive = response.status >= 200 && response.status < 300; - await this.logAndStoreCheck(job, isAlive, responseTime); - return isAlive; + return await this.logAndStoreCheck(job, isAlive, responseTime); } catch (error) { - await this.logAndStoreCheck(job, false, 0, error); - return false; + return await this.logAndStoreCheck(job, false, error.responseTime, error); } } - + /** + * Retrieves the status of a given job based on its type. + * For unsupported job types, it logs an error and returns false. + * + * @param {Object} job - The job object containing data necessary for processing. + * @returns {Promise} The status of the job if it is supported and processed successfully, otherwise false. + */ async getStatus(job) { switch (job.data.type) { case this.TYPE_PING: @@ -65,30 +86,47 @@ class NetworkService { case this.TYPE_HTTP: return await this.handleHttp(job); default: - console.error(`Unsupported type: ${job.data.type}`, { + logger.error(`Unsupported type: ${job.data.type}`, { service: this.SERVICE_NAME, - timestamp: new Date().toISOString(), + jobId: job.id, }); return false; } } + /** + * Logs and stores the result of a check for a specific job. + * This function creates a new Check object with the job's details and the result of the check, + * then attempts to save this object to the database. If the save operation is successful, + * it returns the status of the inserted check. If an error occurs during the save operation, + * it logs the error and returns false. + * + * @param {Object} job - The job object containing data necessary for the check. + * @param {boolean} isAlive - The result of the check, indicating if the target is alive. + * @param {number} responseTime - The response time measured during the check. + * @param {Error} [error=null] - Optional error object if an error occurred during the check. + * @returns {Promise} The status of the inserted check if successful, otherwise false. + */ async logAndStoreCheck(job, isAlive, responseTime, error = null) { - const status = isAlive ? "alive" : "dead"; - if (error) { - console.log(`Job ${job.data.url} is dead`); - return; - } + const check = new Check({ + monitorId: job.data._id, + status: isAlive, + responseTime, + statusCode: 0, + message: error ? error.message : "", + }); - if (isAlive) { - console.log( - `Job ${job.data.url} is alive, response time: ${responseTime}ms` - ); - return; + try { + const insertedCheck = await check.save(); + return insertedCheck.status; + } catch (error) { + logger.error(`Error wrtiting check for ${job.id}`, { + service: this.SERVICE_NAME, + jobId: job.id, + error: error, + }); + return false; } - - console.log(`Job ${job.data.url} is dead`); - return; } }