aboutsummaryrefslogtreecommitdiff
path: root/src/tasks/cpuUsage.ts
blob: 61e7a5489f47ca74d3b99e97be6531027a8432be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { BushTask, Time } from '#lib';
import os from 'node:os';

export default class CpuUsageTask extends BushTask {
	public constructor() {
		super('cpuUsage', {
			delay: Time.Minute,
			runOnStart: true
		});
	}

	public async exec() {
		const cpuStats = await cpu.usage(this.client.stats.cpu === undefined ? 100 * Time.Millisecond : Time.Minute);
		this.client.stats.cpu = cpuStats;
	}
}

/* Everything inside the cpu namespace is adapted from the "node-os-utils" npm package which is licensed under a MIT license by Sunil Wang */
namespace cpu {
	export function usage(interval = Time.Second): Promise<number> {
		return new Promise((resolve) => {
			const startMeasure = average();

			setTimeout(() => {
				const endMeasure = average();
				const idleDifference = endMeasure.avgIdle - startMeasure.avgIdle;
				const totalDifference = endMeasure.avgTotal - startMeasure.avgTotal;
				const cpuPercentage = (10000 - Math.round((10000 * idleDifference) / totalDifference)) / 100;

				return resolve(cpuPercentage);
			}, interval);
		});
	}

	export function average(): CpuAverageInfo {
		let totalIdle = 0;
		let totalTick = 0;
		const cpus = os.cpus();

		for (let i = 0, len = cpus.length; i < len; i++) {
			const cpu = cpus[i];
			for (const type in cpu.times) {
				totalTick += cpu.times[type as keyof typeof cpu.times];
			}
			totalIdle += cpu.times.idle;
		}

		return {
			totalIdle: totalIdle,
			totalTick: totalTick,
			avgIdle: totalIdle / cpus.length,
			avgTotal: totalTick / cpus.length
		};
	}

	export interface CpuAverageInfo {
		totalIdle: number;
		totalTick: number;
		avgIdle: number;
		avgTotal: number;
	}
}