How to Get CPU Usage

How to get CPU usage

I had a similar issue and never found a lightweight implementation. Here is a slimmed down version of my solution that answers your specific question. I sample the /proc/stat file just like tylerl recommends. You'll notice that I wait 3 seconds between samples to match top's output, but I have also had good results with 1 or 2 seconds. I run similar code in a loop within a go routine, then I access the cpu usage when I need it from other go routines.

You can also parse the output of top -n1 | grep -i cpu to get the cpu usage, but it only samples for half a second on my linux box and it was way off during heavy load. Regular top seemed to match very closely when I synchronized it and the following program:

package main

import (
"fmt"
"io/ioutil"
"strconv"
"strings"
"time"
)

func getCPUSample() (idle, total uint64) {
contents, err := ioutil.ReadFile("/proc/stat")
if err != nil {
return
}
lines := strings.Split(string(contents), "\n")
for _, line := range(lines) {
fields := strings.Fields(line)
if fields[0] == "cpu" {
numFields := len(fields)
for i := 1; i < numFields; i++ {
val, err := strconv.ParseUint(fields[i], 10, 64)
if err != nil {
fmt.Println("Error: ", i, fields[i], err)
}
total += val // tally up all the numbers to get total ticks
if i == 4 { // idle is the 5th field in the cpu line
idle = val
}
}
return
}
}
return
}

func main() {
idle0, total0 := getCPUSample()
time.Sleep(3 * time.Second)
idle1, total1 := getCPUSample()

idleTicks := float64(idle1 - idle0)
totalTicks := float64(total1 - total0)
cpuUsage := 100 * (totalTicks - idleTicks) / totalTicks

fmt.Printf("CPU usage is %f%% [busy: %f, total: %f]\n", cpuUsage, totalTicks-idleTicks, totalTicks)
}

It seems like I'm allowed to link to the full implementation that I wrote on bitbucket; if it's not, feel free to delete this. It only works on linux so far, though: systemstat.go

How is CPU usage calculated?

The CPU doesn't do the usage calculations by itself. It may have hardware features to make that task easier, but it's mostly the job of the operating system. So obviously the details of implementations will vary (especially in the case of multicore systems).

The general idea is to see how long is the queue of things the CPU needs to do. The operating system may take a look at the scheduler periodically to determine the number of things it has to do.

This is a function Linux in (ripped from Wikipedia) that performs said calculation:

#define FSHIFT   11  /* nr of bits of precision */
#define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */
#define LOAD_FREQ (5*HZ) /* 5 sec intervals */
#define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */
#define EXP_5 2014 /* 1/exp(5sec/5min) */
#define EXP_15 2037 /* 1/exp(5sec/15min) */

#define CALC_LOAD(load,exp,n) \
load *= exp; \
load += n*(FIXED_1-exp); \
load >>= FSHIFT;

unsigned long avenrun[3];

static inline void calc_load(unsigned long ticks)
{
unsigned long active_tasks; /* fixed-point */
static int count = LOAD_FREQ;

count -= ticks;
if (count < 0) {
count += LOAD_FREQ;
active_tasks = count_active_tasks();
CALC_LOAD(avenrun[0], EXP_1, active_tasks);
CALC_LOAD(avenrun[1], EXP_5, active_tasks);
CALC_LOAD(avenrun[2], EXP_15, active_tasks);
}
}

As for the second part of your question, most modern operating systems are multi-tasked. That means the OS is not going to let programs take up all the processing time and not have any for itself (unless you make it do that). In other words, even if an application appears hung, the OS can still steal some time away for its own work.

Retrieve CPU usage and memory usage of a single process on Linux?


ps -p <pid> -o %cpu,%mem,cmd

(You can leave off "cmd" but that might be helpful in debugging).

Note that this gives average CPU usage of the process over the time it has been running.

CPU usage as a percentage for the whole system?

I found a way to do it. There's a function in node-os-utils (https://www.npmjs.com/package/node-os-utils) called loadavgTime that needs to be used with loadavg-windows (https://www.npmjs.com/package/loadavg-windows) if you're on windows. It takes the os.loadavg from the last minute by default. I then divided it by 2 and then multiplied by 10 cos for some reason it outputs a weird number (between 1.__ and 2.__). It gives it as a percentage, you just need to add the % after it when console.log ing it. Here's the code:

const osu = require('node-os-utils')
require('loadavg-windows')

const cpu = osu.cpu
const usage = (cpu.loadavgTime() / 2) * 10

console.log(usage)

How to get cpu usage using java?

It's done by using Oshi lib.

I can get cpu usage every 20 seconds
lib

import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.HardwareAbstractionLayer;

src

private SystemInfo si = new SystemInfo();
private HardwareAbstractionLayer hal = si.getHardware();
private CentralProcessor cpu = hal.getProcessor();
long[] prevTicks = new long[TickType.values().length];

public static double getCPU()
{
double cpuLoad = cpu.getSystemCpuLoadBetweenTicks( prevTicks ) * 100;
prevTicks = cpu.getSystemCpuLoadTicks();
System.out.println("cpuLoad : " + cpuLoad);
return cpuLoad;
}

public static void main(String[] args) throws Exception{
while(true) {
// Sleep 20 seconds
tCPU = (int)getCPU();
}
}

How to get the memory and cpu usage of a remote server?

After searching online and combining a few answers from other questions on stackflow. I get the following solution.

Solution

On your local computer, you might want to have the following bash script, named, say, usage_ssh

START=1
END=3
date
for i in $(seq $START $END)
do
printf '=%.0s' {1..50};
printf '\n'
echo myservery$i
ssh myserver$i -o LogLevel=QUIET -t "~/bin/usage"
done
printf '=%.0s' {1..50};
printf '\n'
printf 'CPU Load: \n'
printf 'First Field\tprocesses per processor\n'
printf 'Second Filed\tidling percentage in last 5 minutes\n'
printf '\n'
printf '\n'

On your remote server, you should have the following bash script named usage. This script should be located in ~/bin.

free -m | awk 'NR==2{printf "Memory Usage\t%s/%sMB\t\t%.2f%\n", $3, $2, $3/$2*100}';
top -n 1 | grep load | awk '{printf "CPU Load\t%.2f\t\t\t%.2f\n", $(NF-2), $(NF-1)}';

Explanation

The idea is that You will call the use ssh -t <your command> to run executable on your remote file and get the output on the screen of your local computer.

Output

Sat Mar 28 10:32:34 CDT 2020
==================================================
myserver1
Memory Usage 47418/48254MB 98.27%
CPU Load 0.01 0.02
==================================================
myserver2
Memory Usage 47421/48254MB 98.27%
CPU Load 0.01 0.02
==================================================
myserver3
Memory Usage 4300/84541MB 5.09%
CPU Load 0.02 0.02
==================================================
CPU Load:
First Field processes per processor
Second Filed idling percentage in last 5 minutes


Related Topics



Leave a reply



Submit