Convert the output of os.cpus() in Node.js to percentage
Asked Answered
O

9

20

Is there a way to convert the os.cpus() info to percentage? Just like the output of iostat (on the CPU section).

My code:

var os = require('os');
console.log(os.cpus());

The output:

[ { model: 'MacBookAir4,2',
    speed: 1800,
    times: 
     { user: 5264280,
       nice: 0,
       sys: 4001110,
       idle: 58703910,
       irq: 0 } },
  { model: 'MacBookAir4,2',
    speed: 1800,
    times: 
     { user: 2215030,
       nice: 0,
       sys: 1072600,
       idle: 64657440,
       irq: 0 } },
  { model: 'MacBookAir4,2',
    speed: 1800,
    times: 
     { user: 5973360,
       nice: 0,
       sys: 3197990,
       idle: 58773760,
       irq: 0 } },
  { model: 'MacBookAir4,2',
    speed: 1800,
    times: 
     { user: 2187650,
       nice: 0,
       sys: 1042550,
       idle: 64714820,
       irq: 0 } } ]

I would like to have the "times" metric converted to percentage, just like is show on the iostat command:

  cpu
us sy id
6  3 91

I understand that the values in the nodejs function are in CPU ticks, but I have no idea what formula should I use to convert them to percentage :)

Thanks.

Orestes answered 5/3, 2012 at 11:33 Comment(0)
H
38

According to the docs, times is

an object containing the number of CPU ticks spent in: user, nice, sys, idle, and irq

So you should just be able to sum the times and calculate the percentage, like below:

var cpus = os.cpus();

for(var i = 0, len = cpus.length; i < len; i++) {
    console.log("CPU %s:", i);
    var cpu = cpus[i], total = 0;

    for(var type in cpu.times) {
        total += cpu.times[type];
    }

    for(type in cpu.times) {
        console.log("\t", type, Math.round(100 * cpu.times[type] / total));
    }
}

EDIT: As Tom Frost says in the comments, this is the average usage since system boot. This is consistent with the question, since the same is true of iostat. However, iostat has the option of doing regular updates, showing the average usage since the last update. Tom's method would work well for implementing that.

Hydroxylamine answered 5/3, 2012 at 13:22 Comment(3)
That's it! That was the formula I was looking for. Thanks :)Orestes
Can't believe I missed the os.* API when looking :-/ There you go that should be all you need.Sike
It's worth noting that this only gives you the usage averaged over time since the machine was last booted. If you run idle for a week and spike to 100% CPU usage, this script will still show the machine as nearly idle. A better approach might be to use setTimeout to measure the stats before and after a second or two wait, subtract the start ticks from the end ticks, and do the calculations on that.Illegality
A
7

This module, that caN be installed using NPM provides what you need:

https://github.com/oscmejia/os-utils

calle the cpuUsage(callback) method and you will get what you need.

Aircrewman answered 7/8, 2012 at 18:5 Comment(0)
E
6

This is my Solution

Interval is in Seconds.

10 will calculate load over the last 10 seconds!

var _  = require("underscore");
var os = require("os"); 
var interval = 1;
var old = _.map(os.cpus(),function(cpu){ return cpu.times;})

setInterval(function() {
    var result = [];
    var current = _.map(os.cpus(),function(cpu){ return cpu.times; })
    _.each(current, function(item,cpuKey){
        result[cpuKey]={}

        var oldVal = old[cpuKey];
        _.each(_.keys(item),function(timeKey){
            var diff = (  parseFloat((item[timeKey]) - parseFloat(oldVal[timeKey])) / parseFloat((interval*100)));
            var name = timeKey;
            if(timeKey == "idle"){
                name = "CPU"        
                diff = 100 - diff;
            }
            //console.log(timeKey + ":\t" + oldVal[timeKey] + "\t\t" + item[timeKey] + "\t\t" + diff);  
            result[cpuKey][name]=diff.toFixed(0);
        });
    });
    console.log(result);
    old=current;
}, (interval * 1000));

Outputs something like this on my 8-core every n-seconds

[ { user: '82', nice: '0', sys: '18', CPU: '100', irq: '0' },
  { user: '1', nice: '0', sys: '1', CPU: '3', irq: '0' },
  { user: '1', nice: '0', sys: '1', CPU: '3', irq: '0' },
  { user: '9', nice: '0', sys: '2', CPU: '11', irq: '0' },
  { user: '1', nice: '0', sys: '0', CPU: '1', irq: '0' },
  { user: '1', nice: '0', sys: '1', CPU: '2', irq: '0' },
  { user: '1', nice: '0', sys: '2', CPU: '2', irq: '0' },
  { user: '1', nice: '0', sys: '2', CPU: '3', irq: '0' } ]

Pushing this via socket.io into my Flow-Charts ;)

Eversion answered 4/6, 2014 at 17:49 Comment(1)
Note: I changed "idle" to "CPU" and substracted it from 100. So you have 80% cpu usage. Which i prefer to 20% idleEversion
W
4

If you are looking at the CPU Usage per process try node-usage

Wonderment answered 3/3, 2013 at 19:3 Comment(0)
P
3

a simple hack:

var os = require('os')
var samples = []
var prevCpus = os.cpus()

setInterval(sample,100)
setInterval(print,1000)

function print() {
  var result = {last10:null, last50:null, last100:null}
  var percent = 0
  var i = samples.length
  var j = 0
  while (i--) {
    j++
    if (samples[i].total > 0)
      percent += (100 - Math.round(100 * samples[i].idle / samples[i].total))
    if (j == 10)       result.last10  = percent/j   
    else if (j == 50)  result.last50  = percent/j    
    else if (j == 100) result.last100 = percent/j
  }
  console.log(result)
}

function sample() {
  currCpus = os.cpus()
  for (var i=0,len=currCpus.length;i<len;i++) {
    var prevCpu = prevCpus[i]
    var currCpu = currCpus[i]
    var deltas = {total:0}
    for (var t in prevCpu.times) 
      deltas.total += currCpu.times[t] - prevCpu.times[t]
    for (var t in prevCpu.times) 
      deltas[t] = currCpu.times[t] - prevCpu.times[t]
  }
  prevCpus = currCpus
  samples.push(deltas)
  if (samples.length>100) samples.shift()
}

you could use a metrics-lib like https://github.com/felixge/node-measured to plumb something more prolific

Parcae answered 31/3, 2013 at 7:42 Comment(0)
C
2

Here how I did it:

var OS = require('os');
var oldCPUTime = 0
var oldCPUIdle = 0
function getLoad(){
    var cpus = OS.cpus()
    var totalTime = -oldCPUTime
    var totalIdle = -oldCPUIdle
    for(var i = 0; i < cpus.length; i++) {
        var cpu = cpus[i]
        for(var type in cpu.times) {
            totalTime += cpu.times[type];
            if(type == "idle"){
                totalIdle += cpu.times[type];
            }
        }
    }

    var CPUload = 100 - Math.round(totalIdle/totalTime*100))
    oldCPUTime = totalTime
    oldCPUIdle = totalIdle

    return {
        CPU:CPUload,
        mem:100 - Math.round(OS.freemem()/OS.totalmem()*100)
    }       
}
Campanile answered 4/5, 2017 at 2:17 Comment(0)
B
1

i'm using this code:

var cpu_used = function(){
var cpu = os.cpus();

var counter = 0;
var total=0;

var free=0;
var sys=0;
var user=0;

for (var i = 0; i<cpu.length ; i++) {

    counter++;
    total=parseFloat(cpu[i].times.idle)+parseFloat(cpu[i].times.sys)+parseFloat(cpu[i].times.user)+parseFloat(cpu[i].times.irq)+parseFloat(cpu[i].times.nice);

    free+=100*(parseFloat(cpu[i].times.idle)/total);
    sys+=100*(parseFloat(cpu[i].times.sys)/total);
    user+=100*(parseFloat(cpu[i].times.user)/total);
};

console.log('CPU %s : %s + %s + %s',i,(free/counter),(user/counter),(sys/counter));

}
Ballon answered 10/2, 2014 at 15:26 Comment(0)
S
1

If you want to watch real time CPU and memory usage, you can try os-usage.

The basic usage is like following:

var usage = require('os-usage');

// create an instance of CpuMonitor
var cpuMonitor = new usage.CpuMonitor();

// watch cpu usage overview
cpuMonitor.on('cpuUsage', function(data) {
    console.log(data);

    // { user: '9.33', sys: '56.0', idle: '34.66' }
});

You can also get processes that use most cpu resources:

cpuMonitor.on('topCpuProcs', function(data) {
    console.log(data);

    // [ { pid: '21749', cpu: '0.0', command: 'top' },
    //  { pid: '21748', cpu: '0.0', command: 'node' },
    //  { pid: '21747', cpu: '0.0', command: 'node' },
    //  { pid: '21710', cpu: '0.0', command: 'com.apple.iCloud' },
    //  { pid: '21670', cpu: '0.0', command: 'LookupViewServic' } ]
});
Shanks answered 7/4, 2016 at 11:13 Comment(0)
A
0

This variant covers the cpu-usage for a particular core or for all cores calculated between two different CPU usage samples taken within a configurable 1000 ms.

One thing we should consider when implementing such function is reducing the code overhead between CPU samples code block. Otherwise the code execution will affect the second CPU sample and thus the "averaged" result.

Caveat emptor: the following sample implementation does not fully answer the original question (see SY, USER, IDLE), however it can be easily refactored to return the three metrics instead of the summarized one.

var os = require("os");

/**
 * @description Measure the CPU usage calculated between two different CPU usage samples
 * @param {function} cb A callback function the result is passed to
 * @param {number} [core=-1] The CPU core index to measure. When is not greater than -1 then it is "averaged" for all CPU cores.
 * @param {number} [sampleMs=1000]  The number of milliseconds between the CPU usage samples
 */    
function cpuUsage(cb, core, sampleMs) {
    var deltaUsed;
    var deltaIdle;
    var timesKeys = ["user", "nice", "sys", "irq"];

    var allCores = null === core || !(core > -1);

    var byCore = (cpu, i) => allCores || core === i;

    var bySampleKey = (sample, key) => sample.filter(byCore).reduce((sum, cpu) => sum + cpu.times[key], 0);

    var sample0 = os.cpus();

    setTimeout(function() {
        var sample1 = os.cpus();

        deltaUsed = timesKeys.reduce(
            (diff, key) => diff + bySampleKey(sample1, key) - bySampleKey(sample0, key), 0);

        deltaIdle = bySampleKey(sample1, "idle") - bySampleKey(sample0, "idle");

        if ("function" === typeof cb) {
            cb(100 * (deltaUsed / (deltaUsed + deltaIdle)));
        }
    }, sampleMs || 1000);
}

Usage example:

cpuUsage(perc => console.log(perc));
Arjuna answered 29/1, 2021 at 9:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.