From b1a7ad555babccfd091be333441b07cb6f6d62ca Mon Sep 17 00:00:00 2001 From: Kiran Niranjan Date: Thu, 5 Sep 2024 19:32:47 +0530 Subject: [PATCH] SDA-4442 - remove systeminformation module (#2195) * SDA-4442 - remove systeminformation module * SDA-4442 - Return false for VDI --- package-lock.json | 18 ++-------- package.json | 7 ++-- src/app/stats.ts | 92 ++++++++++++++++++++++++++++++++--------------- 3 files changed, 70 insertions(+), 47 deletions(-) diff --git a/package-lock.json b/package-lock.json index b6caf406..62ef5691 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "symphony", - "version": "24.10.0", + "version": "24.11.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "symphony", - "version": "24.10.0", + "version": "24.11.0", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -24,8 +24,7 @@ "react-dom": "16.14.0", "rimraf": "^4.3.1", "save-svg-as-png": "^1.4.17", - "shell-path": "^3.0.0", - "systeminformation": "5.21.7" + "shell-path": "^3.0.0" }, "devDependencies": { "@types/cheerio": "^0.22.22", @@ -16193,17 +16192,6 @@ "acorn-node": "^1.2.0" } }, - "node_modules/systeminformation": { - "version": "5.21.7", - "resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/systeminformation/-/systeminformation-5.21.7.tgz", - "integrity": "sha512-K3LjnajrazTLTD61+87DFg8IXFk5ljx6nSBqB8pQLtC1UPivAjDtTYGPZ8jaBFxcesPaCOkvLRtBq+RFscrsLw==", - "bin": { - "systeminformation": "lib/cli.js" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/tar": { "version": "6.2.0", "resolved": "https://repo.symphony.com/artifactory/api/npm/npm-virtual-dev/tar/-/tar-6.2.0.tgz", diff --git a/package.json b/package.json index 38216a93..94602581 100644 --- a/package.json +++ b/package.json @@ -176,6 +176,7 @@ "@types/react-dom": "16.9.17", "browserify": "17.0.0", "builder-util-runtime": "^9.0.3", + "cheerio": "v1.0.0-rc.12", "cross-env": "7.0.3", "del": "3.0.0", "electron": "32.0.1", @@ -210,8 +211,7 @@ "ts-jest": "25.3.0", "tslint": "5.20.1", "tslint-config-prettier": "^1.18.0", - "typescript": "^4.9.5", - "cheerio": "v1.0.0-rc.12" + "typescript": "^4.9.5" }, "dependencies": { "@types/lazy-brush": "^1.0.0", @@ -228,8 +228,7 @@ "react-dom": "16.14.0", "rimraf": "^4.3.1", "save-svg-as-png": "^1.4.17", - "shell-path": "^3.0.0", - "systeminformation": "5.21.7" + "shell-path": "^3.0.0" }, "optionalDependencies": { "@symphony/symphony-c9-shell": "3.30.0-37.176", diff --git a/src/app/stats.ts b/src/app/stats.ts index c9b0a0e4..387bde38 100644 --- a/src/app/stats.ts +++ b/src/app/stats.ts @@ -1,6 +1,5 @@ import { app } from 'electron'; import * as os from 'os'; -import * as si from 'systeminformation'; import { buildNumber, version } from '../../package.json'; import { logger } from '../common/logger'; @@ -17,12 +16,6 @@ const MAX_USAGE_CHECK_INTERVAL = 15 * 60 * 1000; // every 15min export class AppStats { public startTime = new Date().toISOString(); private MB_IN_BYTES = 1048576; - private cpu: si.Systeminformation.CpuData | undefined; - private mem: si.Systeminformation.MemData | undefined; - private cpuUsage: si.Systeminformation.CurrentLoadData | undefined; - private osInfo: si.Systeminformation.OsData | undefined; - private uuid: si.Systeminformation.UuidData | undefined; - private time: si.Systeminformation.TimeData | undefined; private maxMemoryUsed: number = 0; private maxCPUUsage: number = 0; @@ -52,35 +45,31 @@ export class AppStats { crashProcess: string = '', ) { console.time(`stats ${actionType}`); - this.cpu = this.cpu ?? (await si.cpu()); - this.mem = this.mem ?? (await si.mem()); - this.cpuUsage = this.cpuUsage ?? (await si.currentLoad()); - this.osInfo = this.osInfo ?? (await si.osInfo()); - this.uuid = this.uuid ?? (await si.uuid()); - this.time = this.time ?? si.time(); const totalMem = this.convertToMB(os.totalmem()); - const usedMem = this.convertToMB(this.mem.used); + const freeMem = this.convertToMB(os.freemem()); + const usedMem = totalMem - freeMem; + const cpuUsagePercentage = await this.getCPUUsage(); console.timeEnd(`stats ${actionType}`); const event: ISessionData = { element: AnalyticsElements.SDA_SESSION, action_type: actionType, extra_data: { sessionStartDatetime: this.startTime, - machineStartDatetime: this.convertUptime(this.time.uptime), - machineId: this.uuid.os, + machineStartDatetime: this.convertUptime(os.uptime()), + machineId: '', osName: os.platform(), - osVersion: this.osInfo.release, + osVersion: os.release(), osLanguage: app.getLocale(), - cpuNumberOfCores: this.cpu.cores, - cpuMaxFrequency: this.cpu.speedMax, - cpuUsagePercent: Math.round(this.cpuUsage.currentLoad), + cpuNumberOfCores: os.cpus().length, + cpuMaxFrequency: this.getMaxCPUSpeed(), + cpuUsagePercent: cpuUsagePercentage, maxCPUUsagePercent: this.maxCPUUsage, memoryTotal: this.convertToMB(os.totalmem()), memoryUsedPercent: this.calculatePercentage(usedMem, totalMem), maxMemoryUsedPercent: this.maxMemoryUsed, sdaUsedMemory: this.convertToMB(process.memoryUsage().heapUsed), - memoryAvailable: this.convertToMB(this.mem.available), - vdi: !!this.osInfo.hypervizor, + memoryAvailable: totalMem, + vdi: false, endReason: endReason ? endReason : undefined, crashProcess, }, @@ -226,18 +215,65 @@ export class AppStats { return uptimeDatetime.toISOString(); } + /** + * Gets the maximum CPU speed in MHz. + * + * @returns {number} The maximum CPU speed in MHz. + */ + private getMaxCPUSpeed(): number { + return Math.max(...os.cpus().map((cpu) => cpu.speed)) / 1000; + } + + /** + * Calculates the average CPU usage across all cores. + * @returns {{ idle: number, total: number }} An object + */ + private calculateCPUUsage(): { idle: number; total: number } { + const cpus = os.cpus(); + + let totalIdle = 0; + let totalTick = 0; + + cpus.forEach((cpu) => { + const { user, nice, sys, idle, irq } = cpu.times; + totalIdle += idle; + totalTick += user + nice + sys + idle + irq; + }); + + return { idle: totalIdle / cpus.length, total: totalTick / cpus.length }; + } + + /** + * Calculates the average CPU usage over a 1-second interval. + * + * @returns {Promise} A promise that resolves to a string representing + * the CPU usage percentage, formatted to two decimal places. + */ + private getCPUUsage(): Promise { + return new Promise((resolve) => { + const start = this.calculateCPUUsage(); + + // Wait for 1 second and then calculate the CPU usage + setTimeout(() => { + const end = this.calculateCPUUsage(); + const idleDiff = end.idle - start.idle; + const totalDiff = end.total - start.total; + const usage = 100 - (100 * idleDiff) / totalDiff; + + resolve(parseInt(usage.toFixed(2), 10)); + }, 1000); + }); + } + /** * Captures the max CPU & Memory value * @private */ private async retrieveLatestData(): Promise { - this.mem = await si.mem(); - this.cpu = await si.cpu(); - this.cpuUsage = await si.currentLoad(); - - const cpuUsagePercent = Math.round(this.cpuUsage.currentLoad); + const cpuUsagePercent = await this.getCPUUsage(); const totalMem = this.convertToMB(os.totalmem()); - const usedMem = this.convertToMB(this.mem.used); + const freeMem = this.convertToMB(os.freemem()); + const usedMem = totalMem - freeMem; const memUsedPercentage = this.calculatePercentage(usedMem, totalMem); if (memUsedPercentage > this.maxMemoryUsed) { this.maxMemoryUsed = memUsedPercentage;