From cfebc770fd98b5bac9b92307e7f3c8a168b21eae Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Wed, 23 Jul 2025 14:28:16 -0700 Subject: [PATCH] add diagnostic service --- server/controllers/diagnosticController.js | 70 +----------------- server/index.js | 6 +- server/service/business/diagnosticService.js | 78 ++++++++++++++++++++ 3 files changed, 86 insertions(+), 68 deletions(-) create mode 100644 server/service/business/diagnosticService.js diff --git a/server/controllers/diagnosticController.js b/server/controllers/diagnosticController.js index 6ba880dcb..a4ade8f84 100755 --- a/server/controllers/diagnosticController.js +++ b/server/controllers/diagnosticController.js @@ -1,5 +1,3 @@ -import v8 from "v8"; -import os from "os"; import { asyncHandler } from "../utils/errorUtils.js"; const SERVICE_NAME = "diagnosticController"; @@ -10,75 +8,13 @@ const obs = new PerformanceObserver((items) => { }); obs.observe({ entryTypes: ["measure"] }); class DiagnosticController { - constructor(db) { - this.db = db; + constructor({ diagnosticService }) { + this.diagnosticService = diagnosticService; } - getCPUUsage = async () => { - const startUsage = process.cpuUsage(); - const timingPeriod = 1000; // measured in ms - await new Promise((resolve) => setTimeout(resolve, timingPeriod)); - const endUsage = process.cpuUsage(startUsage); - const cpuUsage = { - userUsageMs: endUsage.user / 1000, - systemUsageMs: endUsage.system / 1000, - usagePercentage: ((endUsage.user + endUsage.system) / 1000 / timingPeriod) * 100, - }; - return cpuUsage; - }; - getSystemStats = asyncHandler( async (req, res, next) => { - // Memory Usage - const totalMemory = os.totalmem(); - const freeMemory = os.freemem(); - - const osStats = { - freeMemoryBytes: freeMemory, // bytes - totalMemoryBytes: totalMemory, // bytes - }; - - const used = process.memoryUsage(); - const memoryUsage = {}; - for (let key in used) { - memoryUsage[`${key}Mb`] = Math.round((used[key] / 1024 / 1024) * 100) / 100; // MB - } - - // CPU Usage - const cpuMetrics = await this.getCPUUsage(); - - // V8 Heap Statistics - const heapStats = v8.getHeapStatistics(); - const v8Metrics = { - totalHeapSizeBytes: heapStats.total_heap_size, // bytes - usedHeapSizeBytes: heapStats.used_heap_size, // bytes - heapSizeLimitBytes: heapStats.heap_size_limit, // bytes - }; - - // Event Loop Delay - let eventLoopDelay = 0; - performance.mark("start"); - await new Promise((resolve) => setTimeout(resolve, 0)); - performance.mark("end"); - performance.measure("eventLoopDelay", "start", "end"); - const entries = performance.getEntriesByName("eventLoopDelay"); - if (entries.length > 0) { - eventLoopDelay = entries[0].duration; - } - - // Uptime - const uptimeMs = process.uptime() * 1000; // ms - - // Combine Metrics - const diagnostics = { - osStats, - memoryUsage, - cpuUsage: cpuMetrics, - v8HeapStats: v8Metrics, - eventLoopDelayMs: eventLoopDelay, - uptimeMs, - }; - + const diagnostics = await this.diagnosticService.getSystemStats(); return res.success({ msg: "OK", data: diagnostics, diff --git a/server/index.js b/server/index.js index 6b91874c4..c3c23995e 100755 --- a/server/index.js +++ b/server/index.js @@ -60,6 +60,7 @@ import SuperSimpleQueueHelper from "./service/infrastructure/SuperSimpleQueue/Su // Business services import UserService from "./service/business/userService.js"; import CheckService from "./service/business/checkService.js"; +import DiagnosticService from "./service/business/diagnosticService.js"; //Network service and dependencies import NetworkService from "./service/infrastructure/networkService.js"; @@ -196,6 +197,7 @@ const startApp = async () => { settingsService, stringService, }); + const diagnosticService = new DiagnosticService(); // const jobQueueHelper = new JobQueueHelper({ // redisService, @@ -328,7 +330,9 @@ const startApp = async () => { db: ServiceRegistry.get(MongoDB.SERVICE_NAME), }); - const diagnosticController = new DiagnosticController(ServiceRegistry.get(MongoDB.SERVICE_NAME)); + const diagnosticController = new DiagnosticController({ + diagnosticService, + }); //Create routes const authRoutes = new AuthRoutes(authController); diff --git a/server/service/business/diagnosticService.js b/server/service/business/diagnosticService.js new file mode 100644 index 000000000..68b6565cd --- /dev/null +++ b/server/service/business/diagnosticService.js @@ -0,0 +1,78 @@ +import v8 from "v8"; +import os from "os"; + +const SERVICE_NAME = "diagnosticService"; + +class DiagnosticService { + static SERVICE_NAME = SERVICE_NAME; + constructor() {} + + getCPUUsage = async () => { + const startUsage = process.cpuUsage(); + const timingPeriod = 1000; // measured in ms + await new Promise((resolve) => setTimeout(resolve, timingPeriod)); + const endUsage = process.cpuUsage(startUsage); + const cpuUsage = { + userUsageMs: endUsage.user / 1000, + systemUsageMs: endUsage.system / 1000, + usagePercentage: ((endUsage.user + endUsage.system) / 1000 / timingPeriod) * 100, + }; + return cpuUsage; + }; + + getSystemStats = async () => { + // Memory Usage + const totalMemory = os.totalmem(); + const freeMemory = os.freemem(); + + const osStats = { + freeMemoryBytes: freeMemory, // bytes + totalMemoryBytes: totalMemory, // bytes + }; + + const used = process.memoryUsage(); + const memoryUsage = {}; + for (let key in used) { + memoryUsage[`${key}Mb`] = Math.round((used[key] / 1024 / 1024) * 100) / 100; // MB + } + + // CPU Usage + const cpuMetrics = await this.getCPUUsage(); + + // V8 Heap Statistics + const heapStats = v8.getHeapStatistics(); + const v8Metrics = { + totalHeapSizeBytes: heapStats.total_heap_size, // bytes + usedHeapSizeBytes: heapStats.used_heap_size, // bytes + heapSizeLimitBytes: heapStats.heap_size_limit, // bytes + }; + + // Event Loop Delay + let eventLoopDelay = 0; + performance.mark("start"); + await new Promise((resolve) => setTimeout(resolve, 0)); + performance.mark("end"); + performance.measure("eventLoopDelay", "start", "end"); + const entries = performance.getEntriesByName("eventLoopDelay"); + if (entries.length > 0) { + eventLoopDelay = entries[0].duration; + } + + // Uptime + const uptimeMs = process.uptime() * 1000; // ms + + // Combine Metrics + const diagnostics = { + osStats, + memoryUsage, + cpuUsage: cpuMetrics, + v8HeapStats: v8Metrics, + eventLoopDelayMs: eventLoopDelay, + uptimeMs, + }; + + return diagnostics; + }; +} + +export default DiagnosticService;