From 1b8f4f2219dc09388bfce0ce12342db7a061de11 Mon Sep 17 00:00:00 2001 From: Philipp Kunz Date: Sat, 14 Aug 2021 17:01:54 +0200 Subject: [PATCH] fix(core): update --- package-lock.json | 78 +++++++++++++++++++++ package.json | 3 + test/test.ts | 3 +- ts/smartmetrics.classes.smartmetrics.ts | 93 +++++++++++-------------- ts/smartmetrics.interfaces.ts | 2 + ts/smartmetrics.plugins.ts | 4 ++ 6 files changed, 129 insertions(+), 54 deletions(-) diff --git a/package-lock.json b/package-lock.json index 025c81e..30f0186 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,9 @@ "dependencies": { "@pushrocks/smartdelay": "^2.0.13", "@pushrocks/smartlog": "^2.0.44", + "@types/pidusage": "^2.0.1", + "pidtree": "^0.5.0", + "pidusage": "^2.0.21", "prom-client": "^13.2.0" }, "devDependencies": { @@ -3054,6 +3057,12 @@ "@types/express-serve-static-core": "*" } }, + "node_modules/@types/pidusage": { + "version": "2.0.1", + "resolved": "https://verdaccio.lossless.one/@types%2fpidusage/-/pidusage-2.0.1.tgz", + "integrity": "sha512-tYYcz/+5v/EGYT83C0pIXrJGOiVBLksQvxgJboG4nGqx/gZTvq0Ro4SkAjECqMk7L4Ww58VWB4j48qeYh4/YJg==", + "license": "MIT" + }, "node_modules/@types/puppeteer": { "version": "5.4.4", "resolved": "https://verdaccio.lossless.one/@types%2fpuppeteer/-/puppeteer-5.4.4.tgz", @@ -10453,6 +10462,50 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pidtree": { + "version": "0.5.0", + "resolved": "https://verdaccio.lossless.one/pidtree/-/pidtree-0.5.0.tgz", + "integrity": "sha512-9nxspIM7OpZuhBxPg73Zvyq7j1QMPMPsGKTqRc2XOaFQauDvoNz9fM1Wdkjmeo7l9GXOZiRs97sPkuayl39wjA==", + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pidusage": { + "version": "2.0.21", + "resolved": "https://verdaccio.lossless.one/pidusage/-/pidusage-2.0.21.tgz", + "integrity": "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pidusage/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://verdaccio.lossless.one/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://verdaccio.lossless.one/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -17032,6 +17085,11 @@ "@types/express-serve-static-core": "*" } }, + "@types/pidusage": { + "version": "2.0.1", + "resolved": "https://verdaccio.lossless.one/@types%2fpidusage/-/pidusage-2.0.1.tgz", + "integrity": "sha512-tYYcz/+5v/EGYT83C0pIXrJGOiVBLksQvxgJboG4nGqx/gZTvq0Ro4SkAjECqMk7L4Ww58VWB4j48qeYh4/YJg==" + }, "@types/puppeteer": { "version": "5.4.4", "resolved": "https://verdaccio.lossless.one/@types%2fpuppeteer/-/puppeteer-5.4.4.tgz", @@ -22566,6 +22624,26 @@ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, + "pidtree": { + "version": "0.5.0", + "resolved": "https://verdaccio.lossless.one/pidtree/-/pidtree-0.5.0.tgz", + "integrity": "sha512-9nxspIM7OpZuhBxPg73Zvyq7j1QMPMPsGKTqRc2XOaFQauDvoNz9fM1Wdkjmeo7l9GXOZiRs97sPkuayl39wjA==" + }, + "pidusage": { + "version": "2.0.21", + "resolved": "https://verdaccio.lossless.one/pidusage/-/pidusage-2.0.21.tgz", + "integrity": "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==", + "requires": { + "safe-buffer": "^5.2.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://verdaccio.lossless.one/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, "pkg-dir": { "version": "4.2.0", "resolved": "https://verdaccio.lossless.one/pkg-dir/-/pkg-dir-4.2.0.tgz", diff --git a/package.json b/package.json index cd17ceb..0fd4ad0 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,9 @@ "dependencies": { "@pushrocks/smartdelay": "^2.0.13", "@pushrocks/smartlog": "^2.0.44", + "@types/pidusage": "^2.0.1", + "pidtree": "^0.5.0", + "pidusage": "^2.0.21", "prom-client": "^13.2.0" } } diff --git a/test/test.ts b/test/test.ts index 25f209c..ac1554c 100644 --- a/test/test.ts +++ b/test/test.ts @@ -19,7 +19,8 @@ tap.test('should start smartmetrics', async () => { testSmartMetrics.start(); }); -tap.test('should produce valid metrics', async () => { +tap.test('should produce valid metrics', async (tools) => { + console.log('calling .getMetrics from Testfile:') console.log(await testSmartMetrics.getMetrics()); }) diff --git a/ts/smartmetrics.classes.smartmetrics.ts b/ts/smartmetrics.classes.smartmetrics.ts index 211f1ca..8f4d558 100644 --- a/ts/smartmetrics.classes.smartmetrics.ts +++ b/ts/smartmetrics.classes.smartmetrics.ts @@ -20,43 +20,21 @@ export class SmartMetrics { this.setup(); } - public async start() { - if (this.started) { - return; - } - this.started = true; - while (this.started) { - this.logger.log('info', `sending heartbeat for ${this.sourceNameArg} with metrics`, { - eventType: 'heartbeat', - metrics: await this.getMetrics(), - }); - await plugins.smartdelay.delayFor(60000, null, true); - } - } - - public getCpuUsagePercentage() { - // Take the first CPU, considering every CPUs have the same specs - // and every NodeJS process only uses one at a time. - const cpus = plugins.os.cpus(); - let total: number = 0; - - for (const cpu of cpus) { - total += - cpu.times.user + - cpu.times.sys + - cpu.times.nice + - cpu.times.nice + - cpu.times.irq + - cpu.times.idle; - } - - const usage = process.cpuUsage(); - const currentCPUUsage = (usage.user + usage.system); - - // Find out the percentage used for this specific CPU - const perc = (currentCPUUsage / total) * 100; - - return perc; + public start() { + const unattendedStart = async () => { + if (this.started) { + return; + } + this.started = true; + while (this.started) { + this.logger.log('info', `sending heartbeat for ${this.sourceNameArg} with metrics`, { + eventType: 'heartbeat', + metrics: await this.getMetrics(), + }); + await plugins.smartdelay.delayFor(10000, null, true); + } + }; + unattendedStart(); } public formatBytes(bytes: number, decimals = 2) { @@ -73,6 +51,26 @@ export class SmartMetrics { public async getMetrics() { const originalMetrics = await this.registry.getMetricsAsJSON(); + const pids = await plugins.pidtree(process.pid); + const stats = await plugins.pidusage([process.pid, ...pids]); + + // lets compute cpu usage + let cpuPercentage = 0; + for (const stat of Object.keys(stats)) { + if (!stats[stat]) continue; + cpuPercentage += stats[stat].cpu / 100; + } + let cpuUsageText = `${cpuPercentage * 100} %`; + + // lets compute memory usage + let memoryUsageBytes = 0; + for (const stat of Object.keys(stats)) { + if (!stats[stat]) continue; + memoryUsageBytes += stats[stat].memory; + } + let memoryUsageText = this.formatBytes(memoryUsageBytes); + let memoryPercentage = Math.round((memoryUsageBytes / plugins.os.totalmem()) * 100) / 100; + const returnMetrics: interfaces.IMetricsSnapshot = { originalMetrics, process_cpu_seconds_total: ( @@ -91,22 +89,11 @@ export class SmartMetrics { (metricSet) => metricSet.name === 'nodejs_heap_size_total_bytes' ) as any ).values[0].value, - cpuPercentage: Math.round(this.getCpuUsagePercentage() * 100) / 100, - memoryUsageText: this.formatBytes( - ( - originalMetrics.find( - (metricSet) => metricSet.name === 'nodejs_heap_size_total_bytes' - ) as any - ).values[0].value - ), - memoryPercentage: - Math.round((( - originalMetrics.find( - (metricSet) => metricSet.name === 'nodejs_heap_size_total_bytes' - ) as any - ).values[0].value / - plugins.os.totalmem()) * - 100 * 100) / 100, + cpuPercentage, + cpuUsageText, + memoryPercentage, + memoryUsageBytes, + memoryUsageText, }; return returnMetrics; } diff --git a/ts/smartmetrics.interfaces.ts b/ts/smartmetrics.interfaces.ts index bde23d1..15464e1 100644 --- a/ts/smartmetrics.interfaces.ts +++ b/ts/smartmetrics.interfaces.ts @@ -6,6 +6,8 @@ export interface IMetricsSnapshot { nodejs_active_requests_total: number; nodejs_heap_size_total_bytes: number; cpuPercentage: number; + cpuUsageText: string; memoryPercentage: number; + memoryUsageBytes: number; memoryUsageText: string; } \ No newline at end of file diff --git a/ts/smartmetrics.plugins.ts b/ts/smartmetrics.plugins.ts index ec2d835..6392356 100644 --- a/ts/smartmetrics.plugins.ts +++ b/ts/smartmetrics.plugins.ts @@ -15,8 +15,12 @@ export { } // third party scope +import pidusage from 'pidusage'; +import pidtree from 'pidtree'; import * as promClient from 'prom-client'; export { + pidusage, + pidtree, promClient }