Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get process CPU usage in percentage

The process.cpuUsage() function displays some weird microsecond values. How to get cpu usage in percentage?

like image 655
Alex Avatar asked Aug 06 '20 18:08

Alex


4 Answers

An alternative, assuming you are running node under linux/macos O.S. is:

var exec = require("child_process").exec;

function getProcessPercent() {

  // GET current node process id.
  const pid = process.pid;
  console.log(pid);

  //linux command to get cpu percentage for the specific Process Id.
  var cmd = `ps up "${pid}" | tail -n1 | tr -s ' ' | cut -f3 -d' '`;

  setInterval(() => {
    //executes the command and returns the percentage value
    exec(cmd, function (err, percentValue) {
      if (err) {
        console.log("Command `ps` returned an error!");
      } else {
        console.log(`${percentValue* 1}%`);
      }
    });
  }, 1000);
}

getProcessPercent();

If your O.S is windows, your command must be different. As i'm not running windows i can't tell to you the exact command, but you can start from here:

tasklist

get-process

WMIC

You can also check the platform with process.platform and do an if/else statment setting the right command for the specific OS.

like image 123
Luis Paulo Pinto Avatar answered Nov 04 '22 23:11

Luis Paulo Pinto


You can achieve this using the additional os native module to get informations about your CPUs:

const os = require('os');

// Take the first CPU, considering every CPUs have the same specs
// and every NodeJS process only uses one at a time.
const cpus = os.cpus();
const cpu = cpus[0];

// Accumulate every CPU times values
const total = Object.values(cpu.times).reduce(
    (acc, tv) => acc + tv, 0
);

// Normalize the one returned by process.cpuUsage() 
// (microseconds VS miliseconds)
const usage = process.cpuUsage();
const currentCPUUsage = (usage.user + usage.system) * 1000;

// Find out the percentage used for this specific CPU
const perc = currentCPUUsage / total * 100;

console.log(`CPU Usage (%): ${perc}`);

If you want to get the global CPU usage (taking all your CPUs into account), you need to accumulate every times of every CPUs, not only the first one, but that should be less useful in most cases.

Note that only the "system" time can use more than the first CPU because the calls can run in other threads separated from the NodeJS core.

Sources :

  • https://nodejs.org/api/os.html#os_os_cpus

  • https://nodejs.org/api/process.html#process_process_cpuusage_previousvalue

like image 29
bob6664569 Avatar answered Nov 04 '22 23:11

bob6664569


Before answering we need to take care about a couple of facts:

  • Node.js does not uses only one CPU, but every async I/O operation may use additional CPUs
  • the times returned by process.cpuUsage are cumulative of all CPUs used by the Node.js process

so to calculate the CPU usage of Node.js considering all the CPUs of the host, we could use something similar to:

const ncpu = require("os").cpus().length;
let previousTime = new Date().getTime();
let previousUsage = process.cpuUsage();
let lastUsage;

setInterval(() => {
    const currentUsage = process.cpuUsage(previousUsage);

    previousUsage = process.cpuUsage();

    // we can't do simply times / 10000 / ncpu because we can't trust
    // setInterval is executed exactly every 1.000.000 microseconds
    const currentTime = new Date().getTime();
    // times from process.cpuUsage are in microseconds while delta time in milliseconds
    // * 10 to have the value in percentage for only one cpu
    // * ncpu to have the percentage for all cpus af the host

    // this should match top's %CPU
    const timeDelta = (currentTime - previousTime) * 10;
    // this would take care of CPUs number of the host
    // const timeDelta = (currentTime - previousTime) * 10 * ncpu;
    const { user, system } = currentUsage;

    lastUsage = { system: system / timeDelta, total: (system + user) / timeDelta, user: user / timeDelta };
    previousTime = currentTime;

    console.log(lastUsage);
}, 1000);

or we can read the value of lastUsage from where we need it rather printing it to the console.

like image 41
Daniele Ricci Avatar answered Nov 05 '22 00:11

Daniele Ricci


Try using the below code to get cpu usage in %

var startTime  = process.hrtime()
var startUsage = process.cpuUsage()

// spin the CPU for 500 milliseconds
var now = Date.now()
while (Date.now() - now < 500)

var elapTime = process.hrtime(startTime)
var elapUsage = process.cpuUsage(startUsage)

var elapTimeMS = secNSec2ms(elapTime)
var elapUserMS = secNSec2ms(elapUsage.user)
var elapSystMS = secNSec2ms(elapUsage.system)
var cpuPercent = Math.round(100 * (elapUserMS + elapSystMS) / elapTimeMS)

console.log('elapsed time ms:  ', elapTimeMS)
console.log('elapsed user ms:  ', elapUserMS)
console.log('elapsed system ms:', elapSystMS)
console.log('cpu percent:      ', cpuPercent)

function secNSec2ms (secNSec) {
  return secNSec[0] * 1000 + secNSec[1] / 1000000
}

try tweaking the secNSec2ms function to the following to check if it solves your problem.

function secNSec2ms(secNSec) {
  if (Array.isArray(secNSec))
  return secNSec[0] * 1000 + secNSec[1] / 1000000 return secNSec / 1000;
}
like image 45
Saddam Avatar answered Nov 04 '22 22:11

Saddam