diff --git a/server/src/config/services.js b/server/src/config/services.js index 515fe5cfe..08c2525f3 100644 --- a/server/src/config/services.js +++ b/server/src/config/services.js @@ -47,8 +47,6 @@ import { ParseBoolean } from "../utils/utils.js"; // Models import Check from "../db/models/Check.js"; -import HardwareCheck from "../db/models/HardwareCheck.js"; -import PageSpeedCheck from "../db/models/PageSpeedCheck.js"; import Monitor from "../db/models/Monitor.js"; import User from "../db/models/User.js"; import InviteToken from "../db/models/InviteToken.js"; @@ -56,7 +54,6 @@ import StatusPage from "../db/models/StatusPage.js"; import Team from "../db/models/Team.js"; import MaintenanceWindow from "../db/models/MaintenanceWindow.js"; import MonitorStats from "../db/models/MonitorStats.js"; -import NetworkCheck from "../db/models/NetworkCheck.js"; import Notification from "../db/models/Notification.js"; import RecoveryToken from "../db/models/RecoveryToken.js"; import AppSettings from "../db/models/AppSettings.js"; @@ -65,12 +62,9 @@ import InviteModule from "../db/mongo/modules/inviteModule.js"; import CheckModule from "../db/mongo/modules/checkModule.js"; import StatusPageModule from "../db/mongo/modules/statusPageModule.js"; import UserModule from "../db/mongo/modules/userModule.js"; -import HardwareCheckModule from "../db/mongo/modules/hardwareCheckModule.js"; import MaintenanceWindowModule from "../db/mongo/modules/maintenanceWindowModule.js"; import MonitorModule from "../db/mongo/modules/monitorModule.js"; -import NetworkCheckModule from "../db/mongo/modules/networkCheckModule.js"; import NotificationModule from "../db/mongo/modules/notificationModule.js"; -import PageSpeedCheckModule from "../db/mongo/modules/pageSpeedCheckModule.js"; import RecoveryModule from "../db/mongo/modules/recoveryModule.js"; import SettingsModule from "../db/mongo/modules/settingsModule.js"; @@ -84,18 +78,15 @@ export const initializeServices = async ({ logger, envSettings, settingsService const stringService = new StringService(translationService); // Create DB - const checkModule = new CheckModule({ logger, Check, HardwareCheck, PageSpeedCheck, Monitor, User }); + const checkModule = new CheckModule({ logger, Check, Monitor, User }); const inviteModule = new InviteModule({ InviteToken, crypto, stringService }); const statusPageModule = new StatusPageModule({ StatusPage, NormalizeData, stringService }); const userModule = new UserModule({ User, Team, GenerateAvatarImage, ParseBoolean, stringService }); - const hardwareCheckModule = new HardwareCheckModule({ HardwareCheck, Monitor, logger }); const maintenanceWindowModule = new MaintenanceWindowModule({ MaintenanceWindow }); const monitorModule = new MonitorModule({ Monitor, MonitorStats, Check, - PageSpeedCheck, - HardwareCheck, stringService, fs, path, @@ -104,9 +95,7 @@ export const initializeServices = async ({ logger, envSettings, settingsService NormalizeData, NormalizeDataUptimeDetails, }); - const networkCheckModule = new NetworkCheckModule({ NetworkCheck }); const notificationModule = new NotificationModule({ Notification, Monitor }); - const pageSpeedCheckModule = new PageSpeedCheckModule({ PageSpeedCheck }); const recoveryModule = new RecoveryModule({ User, RecoveryToken, crypto, stringService }); const settingsModule = new SettingsModule({ AppSettings }); @@ -117,12 +106,9 @@ export const initializeServices = async ({ logger, envSettings, settingsService inviteModule, statusPageModule, userModule, - hardwareCheckModule, maintenanceWindowModule, monitorModule, - networkCheckModule, notificationModule, - pageSpeedCheckModule, recoveryModule, settingsModule, }); diff --git a/server/src/db/models/Check.js b/server/src/db/models/Check.js index 0037ffadc..42a718bd0 100755 --- a/server/src/db/models/Check.js +++ b/server/src/db/models/Check.js @@ -1,108 +1,176 @@ import mongoose from "mongoose"; -const BaseCheckSchema = mongoose.Schema({ - /** - * Reference to the associated Monitor document. - * - * @type {mongoose.Schema.Types.ObjectId} - */ - monitorId: { - type: mongoose.Schema.Types.ObjectId, - ref: "Monitor", - immutable: true, - index: true, - }, - - teamId: { - type: mongoose.Schema.Types.ObjectId, - ref: "Team", - immutable: true, - index: true, - }, - /** - * Status of the check (true for up, false for down). - * - * @type {Boolean} - */ - status: { - type: Boolean, - index: true, - }, - /** - * Response time of the check in milliseconds. - * - * @type {Number} - */ - responseTime: { - type: Number, - }, - /** - * Timings from Got. - * - * @type {Object} - */ - timings: { - type: Object, // Accepts any object - default: {}, - }, - /** - * HTTP status code received during the check. - * - * @type {Number} - */ - statusCode: { - type: Number, - index: true, - }, - /** - * Message or description of the check result. - * - * @type {String} - */ - message: { - type: String, - }, - /** - * Expiry date of the check, auto-calculated to expire after 30 days. - * - * @type {Date} - */ - - expiry: { - type: Date, - default: Date.now, - expires: 60 * 60 * 24 * 30, // 30 days - }, - /** - * Acknowledgment of the check. - * - * @type {Boolean} - */ - ack: { - type: Boolean, - default: false, - }, - /** - * Resolution date of the check (when the check was resolved). - * - * @type {Date} - */ - ackAt: { - type: Date, - }, +const cpuSchema = mongoose.Schema({ + physical_core: { type: Number, default: 0 }, + logical_core: { type: Number, default: 0 }, + frequency: { type: Number, default: 0 }, + temperature: { type: [Number], default: [] }, + free_percent: { type: Number, default: 0 }, + usage_percent: { type: Number, default: 0 }, }); -/** - * Check Schema for MongoDB collection. - * - * Represents a check associated with a monitor, storing information - * about the status and response of a particular check event. - */ -const CheckSchema = mongoose.Schema({ ...BaseCheckSchema.obj }, { timestamps: true }); +const memorySchema = mongoose.Schema({ + total_bytes: { type: Number, default: 0 }, + available_bytes: { type: Number, default: 0 }, + used_bytes: { type: Number, default: 0 }, + usage_percent: { type: Number, default: 0 }, +}); + +const diskSchema = mongoose.Schema({ + read_speed_bytes: { type: Number, default: 0 }, + write_speed_bytes: { type: Number, default: 0 }, + total_bytes: { type: Number, default: 0 }, + free_bytes: { type: Number, default: 0 }, + usage_percent: { type: Number, default: 0 }, +}); + +const hostSchema = mongoose.Schema({ + os: { type: String, default: "" }, + platform: { type: String, default: "" }, + kernel_version: { type: String, default: "" }, +}); + +const errorSchema = mongoose.Schema({ + metric: { type: [String], default: [] }, + err: { type: String, default: "" }, +}); + +const captureSchema = mongoose.Schema({ + version: { type: String, default: "" }, + mode: { type: String, default: "" }, +}); + +const networkInterfaceSchema = mongoose.Schema({ + name: { type: String }, + bytes_sent: { type: Number, default: 0 }, + bytes_recv: { type: Number, default: 0 }, + packets_sent: { type: Number, default: 0 }, + packets_recv: { type: Number, default: 0 }, + err_in: { type: Number, default: 0 }, + err_out: { type: Number, default: 0 }, + drop_in: { type: Number, default: 0 }, + drop_out: { type: Number, default: 0 }, + fifo_in: { type: Number, default: 0 }, + fifo_out: { type: Number, default: 0 }, +}); + +const CheckSchema = new mongoose.Schema( + { + // Common fields + monitorId: { + type: mongoose.Schema.Types.ObjectId, + ref: "Monitor", + immutable: true, + index: true, + }, + + teamId: { + type: mongoose.Schema.Types.ObjectId, + ref: "Team", + immutable: true, + index: true, + }, + type: { + type: String, + enum: ["http", "hardware", "pagespeed", "distributed"], + required: true, + index: true, + }, + + status: { + type: Boolean, + index: true, + }, + + responseTime: { + type: Number, + }, + + timings: { + type: Object, + default: {}, + }, + + statusCode: { + type: Number, + index: true, + }, + + message: { + type: String, + }, + + expiry: { + type: Date, + default: Date.now, + expires: 60 * 60 * 24 * 30, // 30 days + }, + + ack: { + type: Boolean, + default: false, + }, + + ackAt: { + type: Date, + }, + + // Hardware fields + cpu: { + type: cpuSchema, + default: () => ({}), + }, + memory: { + type: memorySchema, + default: () => ({}), + }, + disk: { + type: [diskSchema], + default: () => [], + }, + host: { + type: hostSchema, + default: () => ({}), + }, + + errors: { + type: [errorSchema], + default: () => [], + }, + + capture: { + type: captureSchema, + default: () => ({}), + }, + + net: { + type: [networkInterfaceSchema], + default: () => [], + }, + + // PageSpeed fields + accessibility: { + type: Number, + }, + bestPractices: { + type: Number, + }, + seo: { + type: Number, + }, + performance: { + type: Number, + }, + audits: { + type: Object, + }, + }, + { timestamps: true } +); + CheckSchema.index({ updatedAt: 1 }); CheckSchema.index({ monitorId: 1, updatedAt: 1 }); CheckSchema.index({ monitorId: 1, updatedAt: -1 }); CheckSchema.index({ teamId: 1, updatedAt: -1 }); export default mongoose.model("Check", CheckSchema); -export { BaseCheckSchema }; diff --git a/server/src/db/models/HardwareCheck.js b/server/src/db/models/HardwareCheck.js deleted file mode 100755 index 5b7d56213..000000000 --- a/server/src/db/models/HardwareCheck.js +++ /dev/null @@ -1,100 +0,0 @@ -import mongoose from "mongoose"; -import { BaseCheckSchema } from "./Check.js"; -const cpuSchema = mongoose.Schema({ - physical_core: { type: Number, default: 0 }, - logical_core: { type: Number, default: 0 }, - frequency: { type: Number, default: 0 }, - temperature: { type: [Number], default: [] }, - free_percent: { type: Number, default: 0 }, - usage_percent: { type: Number, default: 0 }, -}); - -const memorySchema = mongoose.Schema({ - total_bytes: { type: Number, default: 0 }, - available_bytes: { type: Number, default: 0 }, - used_bytes: { type: Number, default: 0 }, - usage_percent: { type: Number, default: 0 }, -}); - -const diskSchema = mongoose.Schema({ - read_speed_bytes: { type: Number, default: 0 }, - write_speed_bytes: { type: Number, default: 0 }, - total_bytes: { type: Number, default: 0 }, - free_bytes: { type: Number, default: 0 }, - usage_percent: { type: Number, default: 0 }, -}); - -const hostSchema = mongoose.Schema({ - os: { type: String, default: "" }, - platform: { type: String, default: "" }, - kernel_version: { type: String, default: "" }, -}); - -const errorSchema = mongoose.Schema({ - metric: { type: [String], default: [] }, - err: { type: String, default: "" }, -}); - -const captureSchema = mongoose.Schema({ - version: { type: String, default: "" }, - mode: { type: String, default: "" }, -}); - -const networkInterfaceSchema = mongoose.Schema({ - name: { type: String }, - bytes_sent: { type: Number, default: 0 }, - bytes_recv: { type: Number, default: 0 }, - packets_sent: { type: Number, default: 0 }, - packets_recv: { type: Number, default: 0 }, - err_in: { type: Number, default: 0 }, - err_out: { type: Number, default: 0 }, - drop_in: { type: Number, default: 0 }, - drop_out: { type: Number, default: 0 }, - fifo_in: { type: Number, default: 0 }, - fifo_out: { type: Number, default: 0 }, -}); - -const HardwareCheckSchema = mongoose.Schema( - { - ...BaseCheckSchema.obj, - cpu: { - type: cpuSchema, - default: () => ({}), - }, - memory: { - type: memorySchema, - default: () => ({}), - }, - disk: { - type: [diskSchema], - default: () => [], - }, - host: { - type: hostSchema, - default: () => ({}), - }, - - errors: { - type: [errorSchema], - default: () => [], - }, - - capture: { - type: captureSchema, - default: () => ({}), - }, - - net: { - type: [networkInterfaceSchema], - default: () => [], - required: false, - }, - }, - { timestamps: true } -); - -HardwareCheckSchema.index({ createdAt: 1 }); -HardwareCheckSchema.index({ monitorId: 1, createdAt: 1 }); -HardwareCheckSchema.index({ monitorId: 1, createdAt: -1 }); - -export default mongoose.model("HardwareCheck", HardwareCheckSchema); diff --git a/server/src/db/models/Monitor.js b/server/src/db/models/Monitor.js index 1ee467999..8d4ff9468 100755 --- a/server/src/db/models/Monitor.js +++ b/server/src/db/models/Monitor.js @@ -1,6 +1,4 @@ import mongoose from "mongoose"; -import HardwareCheck from "./HardwareCheck.js"; -import PageSpeedCheck from "./PageSpeedCheck.js"; import Check from "./Check.js"; import MonitorStats from "./MonitorStats.js"; import StatusPage from "./StatusPage.js"; @@ -133,13 +131,7 @@ MonitorSchema.pre("findOneAndDelete", async function (next) { throw new Error("Monitor not found"); } - if (doc?.type === "pagespeed") { - await PageSpeedCheck.deleteMany({ monitorId: doc._id }); - } else if (doc?.type === "hardware") { - await HardwareCheck.deleteMany({ monitorId: doc._id }); - } else { - await Check.deleteMany({ monitorId: doc._id }); - } + await Check.deleteMany({ monitorId: doc._id }); // Deal with status pages await StatusPage.updateMany({ monitors: doc?._id }, { $pull: { monitors: doc?._id } }); @@ -156,13 +148,7 @@ MonitorSchema.pre("deleteMany", async function (next) { const monitors = await this.model.find(filter).select(["_id", "type"]).lean(); for (const monitor of monitors) { - if (monitor.type === "pagespeed") { - await PageSpeedCheck.deleteMany({ monitorId: monitor._id }); - } else if (monitor.type === "hardware") { - await HardwareCheck.deleteMany({ monitorId: monitor._id }); - } else { - await Check.deleteMany({ monitorId: monitor._id }); - } + await Check.deleteMany({ monitorId: monitor._id }); await StatusPage.updateMany({ monitors: monitor._id }, { $pull: { monitors: monitor._id } }); await MonitorStats.deleteMany({ monitorId: monitor._id.toString() }); } diff --git a/server/src/db/models/MonitorStats.js b/server/src/db/models/MonitorStats.js index c28811b33..c081c8a4f 100755 --- a/server/src/db/models/MonitorStats.js +++ b/server/src/db/models/MonitorStats.js @@ -40,10 +40,6 @@ const MonitorStatsSchema = new mongoose.Schema( type: Number, default: 0, }, - uptBurnt: { - type: mongoose.Schema.Types.Decimal128, - required: false, - }, }, { timestamps: true } ); diff --git a/server/src/db/models/NetworkCheck.js b/server/src/db/models/NetworkCheck.js deleted file mode 100644 index eca69eef9..000000000 --- a/server/src/db/models/NetworkCheck.js +++ /dev/null @@ -1,46 +0,0 @@ -import mongoose from "mongoose"; -import { BaseCheckSchema } from "./Check.js"; - -const networkInterfaceSchema = mongoose.Schema({ - name: { type: String, required: true }, - bytes_sent: { type: Number, default: 0 }, - bytes_recv: { type: Number, default: 0 }, - packets_sent: { type: Number, default: 0 }, - packets_recv: { type: Number, default: 0 }, - err_in: { type: Number, default: 0 }, - err_out: { type: Number, default: 0 }, - drop_in: { type: Number, default: 0 }, - drop_out: { type: Number, default: 0 }, - fifo_in: { type: Number, default: 0 }, - fifo_out: { type: Number, default: 0 }, -}); - -const captureSchema = mongoose.Schema({ - version: { type: String, default: "" }, - mode: { type: String, default: "" }, -}); - -const NetworkCheckSchema = mongoose.Schema( - { - ...BaseCheckSchema.obj, - data: { - type: [networkInterfaceSchema], - default: () => [], - }, - capture: { - type: captureSchema, - default: () => ({}), - }, - errors: { - type: mongoose.Schema.Types.Mixed, - default: null, - }, - }, - { timestamps: true } -); - -NetworkCheckSchema.index({ createdAt: 1 }); -NetworkCheckSchema.index({ monitorId: 1, createdAt: 1 }); -NetworkCheckSchema.index({ monitorId: 1, createdAt: -1 }); - -export default mongoose.model("NetworkCheck", NetworkCheckSchema); diff --git a/server/src/db/models/PageSpeedCheck.js b/server/src/db/models/PageSpeedCheck.js deleted file mode 100755 index 67c7c375e..000000000 --- a/server/src/db/models/PageSpeedCheck.js +++ /dev/null @@ -1,83 +0,0 @@ -import mongoose from "mongoose"; -import { BaseCheckSchema } from "./Check.js"; -const AuditSchema = mongoose.Schema({ - id: { type: String, required: true }, - title: { type: String, required: true }, - description: { type: String, required: true }, - score: { type: Number, required: true }, - scoreDisplayMode: { type: String, required: true }, - displayValue: { type: String, required: true }, - numericValue: { type: Number, required: true }, - numericUnit: { type: String, required: true }, -}); - -const AuditsSchema = mongoose.Schema({ - cls: { - type: AuditSchema, - required: true, - }, - si: { - type: AuditSchema, - required: true, - }, - fcp: { - type: AuditSchema, - required: true, - }, - lcp: { - type: AuditSchema, - required: true, - }, - tbt: { - type: AuditSchema, - required: true, - }, -}); - -/** - * Mongoose schema for storing metrics from Google Lighthouse. - * @typedef {Object} PageSpeedCheck - * @property {mongoose.Schema.Types.ObjectId} monitorId - Reference to the Monitor model. - * @property {number} accessibility - Accessibility score. - * @property {number} bestPractices - Best practices score. - * @property {number} seo - SEO score. - * @property {number} performance - Performance score. - */ - -const PageSpeedCheck = mongoose.Schema( - { - ...BaseCheckSchema.obj, - accessibility: { - type: Number, - required: true, - }, - bestPractices: { - type: Number, - required: true, - }, - seo: { - type: Number, - required: true, - }, - performance: { - type: Number, - required: true, - }, - audits: { - type: AuditsSchema, - required: true, - }, - }, - { timestamps: true } -); - -/** - * Mongoose model for storing metrics from Google Lighthouse. - * @typedef {mongoose.Model} LighthouseMetricsModel - */ - -PageSpeedCheck.index({ createdAt: 1 }); -PageSpeedCheck.index({ monitorId: 1, createdAt: 1 }); -PageSpeedCheck.index({ monitorId: 1, createdAt: -1 }); - -export default mongoose.model("PageSpeedCheck", PageSpeedCheck); diff --git a/server/src/db/mongo/modules/checkModule.js b/server/src/db/mongo/modules/checkModule.js index a606a593b..dfca02bed 100755 --- a/server/src/db/mongo/modules/checkModule.js +++ b/server/src/db/mongo/modules/checkModule.js @@ -31,7 +31,7 @@ class CheckModule { } }; - getChecksByMonitor = async ({ monitorId, type, sortOrder, dateRange, filter, ack, page, rowsPerPage, status }) => { + getChecksByMonitor = async ({ monitorId, sortOrder, dateRange, filter, ack, page, rowsPerPage, status }) => { try { status = status === "true" ? true : status === "false" ? false : undefined; page = parseInt(page); @@ -79,19 +79,7 @@ class CheckModule { skip = page * rowsPerPage; } - const checkModels = { - http: this.Check, - ping: this.Check, - docker: this.Check, - port: this.Check, - pagespeed: this.PageSpeedCheck, - hardware: this.HardwareCheck, - game: this.Check, - }; - - const Model = checkModels[type]; - - const checks = await Model.aggregate([ + const checks = await this.Check.aggregate([ { $match: matchStage }, { $sort: { createdAt: sortOrder } }, { @@ -166,18 +154,6 @@ class CheckModule { const aggregatePipeline = [ { $match: matchStage }, - { - $unionWith: { - coll: "hardwarechecks", - pipeline: [{ $match: matchStage }], - }, - }, - { - $unionWith: { - coll: "pagespeedchecks", - pipeline: [{ $match: matchStage }], - }, - }, { $sort: { createdAt: sortOrder } }, { diff --git a/server/src/db/mongo/modules/hardwareCheckModule.js b/server/src/db/mongo/modules/hardwareCheckModule.js deleted file mode 100755 index 448e72fed..000000000 --- a/server/src/db/mongo/modules/hardwareCheckModule.js +++ /dev/null @@ -1,22 +0,0 @@ -const SERVICE_NAME = "hardwareCheckModule"; - -class HardwareCheckModule { - constructor({ HardwareCheck, Monitor, logger }) { - this.HardwareCheck = HardwareCheck; - this.Monitor = Monitor; - this.logger = logger; - } - - createHardwareChecks = async (hardwareChecks) => { - try { - await this.HardwareCheck.insertMany(hardwareChecks, { ordered: false }); - return true; - } catch (error) { - error.service = SERVICE_NAME; - error.method = "createHardwareChecks"; - throw error; - } - }; -} - -export default HardwareCheckModule; diff --git a/server/src/db/mongo/modules/monitorModule.js b/server/src/db/mongo/modules/monitorModule.js index 0e301cdcf..8beb9316c 100755 --- a/server/src/db/mongo/modules/monitorModule.js +++ b/server/src/db/mongo/modules/monitorModule.js @@ -11,25 +11,10 @@ import { const SERVICE_NAME = "monitorModule"; class MonitorModule { - constructor({ - Monitor, - MonitorStats, - Check, - PageSpeedCheck, - HardwareCheck, - stringService, - fs, - path, - fileURLToPath, - ObjectId, - NormalizeData, - NormalizeDataUptimeDetails, - }) { + constructor({ Monitor, MonitorStats, Check, stringService, fs, path, fileURLToPath, ObjectId, NormalizeData, NormalizeDataUptimeDetails }) { this.Monitor = Monitor; this.MonitorStats = MonitorStats; this.Check = Check; - this.PageSpeedCheck = PageSpeedCheck; - this.HardwareCheck = HardwareCheck; this.stringService = stringService; this.fs = fs; this.path = path; @@ -38,15 +23,6 @@ class MonitorModule { this.NormalizeData = NormalizeData; this.NormalizeDataUptimeDetails = NormalizeDataUptimeDetails; - this.CHECK_MODEL_LOOKUP = { - http: Check, - ping: Check, - docker: Check, - port: Check, - pagespeed: PageSpeedCheck, - hardware: HardwareCheck, - }; - const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -146,19 +122,18 @@ class MonitorModule { }; //Helper - getMonitorChecks = async (monitorId, model, dateRange, sortOrder) => { + getMonitorChecks = async (monitorId, dateRange, sortOrder) => { const indexSpec = { monitorId: 1, - createdAt: sortOrder, // This will be 1 or -1 + updatedAt: sortOrder, // This will be 1 or -1 }; const [checksAll, checksForDateRange] = await Promise.all([ - model.find({ monitorId }).sort({ createdAt: sortOrder }).hint(indexSpec).lean(), - model - .find({ - monitorId, - createdAt: { $gte: dateRange.start, $lte: dateRange.end }, - }) + this.Check.find({ monitorId }).sort({ createdAt: sortOrder }).hint(indexSpec).lean(), + this.Check.find({ + monitorId, + createdAt: { $gte: dateRange.start, $lte: dateRange.end }, + }) .hint(indexSpec) .lean(), ]); @@ -295,9 +270,8 @@ class MonitorModule { const sort = sortOrder === "asc" ? 1 : -1; // Get Checks for monitor in date range requested - const model = this.CHECK_MODEL_LOOKUP[monitor.type]; const dates = this.getDateRange(dateRange); - const { checksAll, checksForDateRange } = await this.getMonitorChecks(monitorId, model, dates, sort); + const { checksAll, checksForDateRange } = await this.getMonitorChecks(monitorId, dates, sort); // Build monitor stats const monitorStats = { @@ -339,7 +313,7 @@ class MonitorModule { }; const dateString = formatLookup[dateRange]; - const hardwareStats = await this.HardwareCheck.aggregate(buildHardwareDetailsPipeline(monitor, dates, dateString)); + const hardwareStats = await this.Check.aggregate(buildHardwareDetailsPipeline(monitor, dates, dateString)); const stats = hardwareStats[0]; diff --git a/server/src/db/mongo/modules/monitorModuleQueries.js b/server/src/db/mongo/modules/monitorModuleQueries.js index f6d20d855..0a8f807e8 100755 --- a/server/src/db/mongo/modules/monitorModuleQueries.js +++ b/server/src/db/mongo/modules/monitorModuleQueries.js @@ -5,12 +5,12 @@ const buildUptimeDetailsPipeline = (monitorId, dates, dateString) => { { $match: { monitorId: new ObjectId(monitorId), - createdAt: { $gte: dates.start, $lte: dates.end }, + updatedAt: { $gte: dates.start, $lte: dates.end }, }, }, { $sort: { - createdAt: 1, + updatedAt: 1, }, }, { @@ -173,6 +173,7 @@ const buildHardwareDetailsPipeline = (monitor, dates, dateString) => { { $match: { monitorId: monitor._id, + type: "hardware", createdAt: { $gte: dates.start, $lte: dates.end }, }, }, @@ -225,7 +226,7 @@ const buildHardwareDetailsPipeline = (monitor, dates, dateString) => { }, { $lookup: { - from: "hardwarechecks", + from: "checks", let: { diskCount: "$diskCount", netCount: "$netCount", @@ -987,11 +988,6 @@ const buildMonitorsWithChecksByTeamIdPipeline = ({ matchStage, filter, page, row // Add checks if (limit) { let checksCollection = "checks"; - if (type === "pagespeed") { - checksCollection = "pagespeedchecks"; - } else if (type === "hardware") { - checksCollection = "hardwarechecks"; - } monitorsPipeline.push({ $lookup: { from: checksCollection, @@ -1057,11 +1053,7 @@ const buildFilteredMonitorsByTeamIdPipeline = ({ matchStage, filter, page, rowsP // Add checks if (limit) { let checksCollection = "checks"; - if (type === "pagespeed") { - checksCollection = "pagespeedchecks"; - } else if (type === "hardware") { - checksCollection = "hardwarechecks"; - } + pipeline.push({ $lookup: { from: checksCollection, @@ -1175,46 +1167,6 @@ const buildGetMonitorsByTeamIdPipeline = (req) => { }, ] : []), - ...(limit - ? [ - { - $lookup: { - from: "pagespeedchecks", - let: { monitorId: "$_id" }, - pipeline: [ - { - $match: { - $expr: { $eq: ["$monitorId", "$$monitorId"] }, - }, - }, - { $sort: { createdAt: -1 } }, - ...(limit ? [{ $limit: limit }] : []), - ], - as: "pagespeedchecks", - }, - }, - ] - : []), - ...(limit - ? [ - { - $lookup: { - from: "hardwarechecks", - let: { monitorId: "$_id" }, - pipeline: [ - { - $match: { - $expr: { $eq: ["$monitorId", "$$monitorId"] }, - }, - }, - { $sort: { createdAt: -1 } }, - ...(limit ? [{ $limit: limit }] : []), - ], - as: "hardwarechecks", - }, - }, - ] - : []), { $addFields: { @@ -1225,14 +1177,6 @@ const buildGetMonitorsByTeamIdPipeline = (req) => { case: { $in: ["$type", ["http", "ping", "docker", "port", "game"]] }, then: "$standardchecks", }, - { - case: { $eq: ["$type", "pagespeed"] }, - then: "$pagespeedchecks", - }, - { - case: { $eq: ["$type", "hardware"] }, - then: "$hardwarechecks", - }, ], default: [], }, @@ -1242,8 +1186,6 @@ const buildGetMonitorsByTeamIdPipeline = (req) => { { $project: { standardchecks: 0, - pagespeedchecks: 0, - hardwarechecks: 0, }, }, ], diff --git a/server/src/db/mongo/modules/networkCheckModule.js b/server/src/db/mongo/modules/networkCheckModule.js deleted file mode 100644 index 917e68440..000000000 --- a/server/src/db/mongo/modules/networkCheckModule.js +++ /dev/null @@ -1,30 +0,0 @@ -const SERVICE_NAME = "networkCheckModule"; - -class NetworkCheckModule { - constructor({ NetworkCheck }) { - this.NetworkCheck = NetworkCheck; - } - createNetworkCheck = async (networkCheckData) => { - try { - const networkCheck = await new this.NetworkCheck(networkCheckData); - await networkCheck.save(); - return networkCheck; - } catch (error) { - error.service = SERVICE_NAME; - error.method = "createNetworkCheck"; - throw error; - } - }; - getNetworkChecksByMonitorId = async (monitorId, limit = 100) => { - try { - const networkChecks = await this.NetworkCheck.find({ monitorId }).sort({ createdAt: -1 }).limit(limit); - return networkChecks; - } catch (error) { - error.service = SERVICE_NAME; - error.method = "getNetworkChecksByMonitorId"; - throw error; - } - }; -} - -export default NetworkCheckModule; diff --git a/server/src/db/mongo/modules/pageSpeedCheckModule.js b/server/src/db/mongo/modules/pageSpeedCheckModule.js deleted file mode 100755 index b2a3eb71d..000000000 --- a/server/src/db/mongo/modules/pageSpeedCheckModule.js +++ /dev/null @@ -1,31 +0,0 @@ -// import PageSpeedCheck from "../../models/PageSpeedCheck.js"; -const SERVICE_NAME = "pageSpeedCheckModule"; - -class PageSpeedCheckModule { - constructor({ PageSpeedCheck }) { - this.PageSpeedCheck = PageSpeedCheck; - } - - createPageSpeedChecks = async (pageSpeedChecks) => { - try { - await this.PageSpeedCheck.insertMany(pageSpeedChecks, { ordered: false }); - return true; - } catch (error) { - error.service = SERVICE_NAME; - error.method = "createPageSpeedCheck"; - throw error; - } - }; - - deletePageSpeedChecksByMonitorId = async (monitorId) => { - try { - const result = await this.PageSpeedCheck.deleteMany({ monitorId }); - return result.deletedCount; - } catch (error) { - error.service = SERVICE_NAME; - error.method = "deletePageSpeedChecksByMonitorId"; - throw error; - } - }; -} -export default PageSpeedCheckModule; diff --git a/server/src/service/business/checkService.js b/server/src/service/business/checkService.js index 7966fdbb4..9beb43326 100644 --- a/server/src/service/business/checkService.js +++ b/server/src/service/business/checkService.js @@ -33,10 +33,9 @@ class CheckService { throw this.errorService.createAuthorizationError(); } - let { type, sortOrder, dateRange, filter, ack, page, rowsPerPage, status } = query; + let { sortOrder, dateRange, filter, ack, page, rowsPerPage, status } = query; const result = await this.db.checkModule.getChecksByMonitor({ monitorId, - type, sortOrder, dateRange, filter, diff --git a/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.js b/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.js index 7659b1c71..ac8da9169 100644 --- a/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.js +++ b/server/src/service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.js @@ -2,6 +2,16 @@ const SERVICE_NAME = "JobQueueHelper"; class SuperSimpleQueueHelper { static SERVICE_NAME = SERVICE_NAME; + + /** + * @param {{ + * db: import("../database").Database, + * logger: import("../logger").Logger, + * networkService: import("../networkService").NetworkService, + * statusService: import("../statusService").StatusService, + * notificationService: import("../notificationService").NotificationService + * }} + */ constructor({ db, logger, networkService, statusService, notificationService }) { this.db = db; this.logger = logger; diff --git a/server/src/service/infrastructure/bufferService.js b/server/src/service/infrastructure/bufferService.js index dc86597b2..f55e25037 100755 --- a/server/src/service/infrastructure/bufferService.js +++ b/server/src/service/infrastructure/bufferService.js @@ -1,13 +1,4 @@ const SERVICE_NAME = "BufferService"; -const TYPE_MAP = { - http: "checks", - ping: "checks", - port: "checks", - docker: "checks", - pagespeed: "pagespeedChecks", - hardware: "hardwareChecks", - game: "checks", -}; class BufferService { static SERVICE_NAME = SERVICE_NAME; @@ -16,17 +7,7 @@ class BufferService { this.db = db; this.logger = logger; this.SERVICE_NAME = SERVICE_NAME; - this.buffers = { - checks: [], - pagespeedChecks: [], - hardwareChecks: [], - }; - this.OPERATION_MAP = { - checks: this.db.checkModule.createChecks, - pagespeedChecks: this.db.pageSpeedCheckModule.createPageSpeedChecks, - hardwareChecks: this.db.hardwareCheckModule.createHardwareChecks, - }; - + this.buffer = []; this.scheduleNextFlush(); this.logger.info({ message: `Buffer service initialized, flushing every ${this.BUFFER_TIMEOUT / 1000}s`, @@ -39,9 +20,9 @@ class BufferService { return BufferService.SERVICE_NAME; } - addToBuffer({ check, type }) { + addToBuffer({ check }) { try { - this.buffers[TYPE_MAP[type]].push(check); + this.buffer.push(check); } catch (error) { this.logger.error({ message: error.message, @@ -55,7 +36,7 @@ class BufferService { scheduleNextFlush() { this.bufferTimer = setTimeout(async () => { try { - await this.flushBuffers(); + await this.flushBuffer(); } catch (error) { this.logger.error({ message: `Error in flush cycle: ${error.message}`, @@ -69,35 +50,24 @@ class BufferService { } }, this.BUFFER_TIMEOUT); } - async flushBuffers() { - let items = 0; - for (const [bufferName, buffer] of Object.entries(this.buffers)) { - items += buffer.length; - const operation = this.OPERATION_MAP[bufferName]; - if (!operation) { - this.logger.error({ - message: `No operation found for ${bufferName}`, - service: this.SERVICE_NAME, - method: "flushBuffers", - }); - continue; - } - try { - await operation(buffer); - } catch (error) { - this.logger.error({ - message: error.message, - service: this.SERVICE_NAME, - method: "flushBuffers", - stack: error.stack, - }); - } - this.buffers[bufferName] = []; + async flushBuffer() { + let items = this.buffer.length; + + try { + await this.db.checkModule.createChecks(this.buffer); + } catch (error) { + this.logger.error({ + message: error.message, + service: this.SERVICE_NAME, + method: "flushBuffer", + stack: error.stack, + }); } + this.buffer = []; this.logger.debug({ message: `Flushed ${items} items`, service: this.SERVICE_NAME, - method: "flushBuffers", + method: "flushBuffer", }); items = 0; } diff --git a/server/src/service/infrastructure/statusService.js b/server/src/service/infrastructure/statusService.js index 4a98996fb..af2c82fa9 100755 --- a/server/src/service/infrastructure/statusService.js +++ b/server/src/service/infrastructure/statusService.js @@ -1,17 +1,14 @@ import MonitorStats from "../../db/models/MonitorStats.js"; -import { safelyParseFloat } from "../../utils/dataUtils.js"; const SERVICE_NAME = "StatusService"; class StatusService { static SERVICE_NAME = SERVICE_NAME; /** - * Creates an instance of StatusService. - * - * @param {Object} db - The database instance. - * @param {Object} logger - The logger instance. - */ - constructor({ db, logger, buffer }) { + * @param {{ + * buffer: import("./bufferService.js").BufferService + * }} + */ constructor({ db, logger, buffer }) { this.db = db; this.logger = logger; this.buffer = buffer; @@ -24,7 +21,7 @@ class StatusService { async updateRunningStats({ monitor, networkResponse }) { try { const monitorId = monitor._id; - const { responseTime, status, upt_burnt } = networkResponse; + const { responseTime, status } = networkResponse; // Get stats let stats = await MonitorStats.findOne({ monitorId }); if (!stats) { @@ -36,8 +33,6 @@ class StatusService { totalDownChecks: 0, uptimePercentage: 0, lastCheck: null, - timeSInceLastCheck: 0, - uptBurnt: 0, }); } @@ -82,12 +77,6 @@ class StatusService { // latest check stats.lastCheckTimestamp = new Date().getTime(); - // UPT burned - if (typeof upt_burnt !== "undefined" && upt_burnt !== null) { - const currentUptBurnt = safelyParseFloat(stats.uptBurnt); - const newUptBurnt = safelyParseFloat(upt_burnt); - stats.uptBurnt = currentUptBurnt + newUptBurnt; - } await stats.save(); return true; } catch (error) { @@ -119,7 +108,8 @@ class StatusService { * @returns {boolean} returnObject.prevStatus - The previous status of the monitor */ updateStatus = async (networkResponse) => { - this.insertCheck(networkResponse); + const check = this.buildCheck(networkResponse); + await this.insertCheck(check); try { const { monitorId, status, code } = networkResponse; const monitor = await this.db.monitorModule.getMonitorById(monitorId); @@ -198,6 +188,7 @@ class StatusService { const check = { monitorId, teamId, + type, status, statusCode: code, responseTime, @@ -264,25 +255,24 @@ class StatusService { * @param {Object} networkResponse.payload - The payload of the response. * @returns {Promise} A promise that resolves when the check is inserted. */ - insertCheck = async (networkResponse) => { + insertCheck = async (check) => { try { - const check = this.buildCheck(networkResponse); if (typeof check === "undefined") { this.logger.warn({ message: "Failed to build check", service: this.SERVICE_NAME, method: "insertCheck", - details: networkResponse, }); - return; + return false; } - this.buffer.addToBuffer({ check, type: networkResponse.type }); + this.buffer.addToBuffer({ check }); + return true; } catch (error) { this.logger.error({ message: error.message, service: error.service || this.SERVICE_NAME, method: error.method || "insertCheck", - details: error.details || `Error inserting check for monitor: ${networkResponse?.monitorId}`, + details: error.details || `Error inserting check for monitor: ${check?.monitorId}`, stack: error.stack, }); }