patternbashMinor
To calculate the total CPU usage as a percentage
Viewed 0 times
totaltheusagecalculatecpupercentage
Problem
I have been developing the below method to calculate the CPU usage of a Linux system at a point in time, as a percentage of the total number of cores available in the system.
Would this be considered a reasonably accurate way of doing this? Any suggestions to increase efficiency/accuracy would be greatly appreciated.
#!/bin/bash
# Get number of cores from proc cpuinfo
CORECOUNT=`grep -c ^processor /proc/cpuinfo`
# Use top, skip the first 7 rows, count the sum of the values in column 9 - the CPU column, do some simple rounding at the end.
CPUUSAGE=`top -bn 1 | awk 'NR>7{s+=$9} END {print s/'$CORECOUNT'}' | awk '{print int($1+0.5)}'`
printf "$CPUUSAGE\n"Would this be considered a reasonably accurate way of doing this? Any suggestions to increase efficiency/accuracy would be greatly appreciated.
Solution
There are a few problems you have here. The first, is the concept of getting the usage at a point in time, which is not possible. But, you can get it for a span of time. You are using
Since you are accessing the
With the above file, I would calculate it manually.... (also using the documentation here: http://www.mjmwired.net/kernel/Documentation/filesystems/proc.txt#1212 )
I have taken the liberty of programming it myself.... since the recommendation is sucha deviation from your solution, it makes sense:
top -bn 1 which will get the usage for the span of a second.Since you are accessing the
/proc system to get the number of CPU's, you may as well use the right /proc file for what you want:cat /proc/stat:~ $ cat /proc/stat
cpu 177206 161827 1274669 3582291272 144435 154779 0 0 0 0
cpu0 32170 48533 914773 894903107 30650 69784 0 0 0 0
cpu1 52790 41088 180295 895685563 76035 14410 0 0 0 0
cpu2 18745 40955 49422 895959636 11295 2234 0 0 0 0
cpu3 73500 31249 130178 895742965 26454 68350 0 0 0 0
intr 339571688 48 10 0 0 0 0 2 0 1 0 0 0 152 0 0 8750527 0 322394 40428015 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
......
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 660707018
btime 1401123121
processes 196075
procs_running 1
procs_blocked 0
softirq 322202763 0 136092603 1792784 40737199 4701209 0 6 133008518 51951 5818493With the above file, I would calculate it manually.... (also using the documentation here: http://www.mjmwired.net/kernel/Documentation/filesystems/proc.txt#1212 )
I have taken the liberty of programming it myself.... since the recommendation is sucha deviation from your solution, it makes sense:
#!/bin/bash
#CORECOUNT=$(grep cpu /proc/stat | grep -v 'cpu ' | wc -l)
#echo $CORECOUNT cores not needed for calculation though
DELAY=${1:-1}
function getstat() {
grep 'cpu ' /proc/stat | sed -e 's/ */x/g' -e 's/^cpux//'
}
function extract() {
echo $1 | cut -d 'x' -f $2
}
function change() {
local e=$(extract $ENDSTAT $1)
local b=$(extract $STARTSTAT $1)
local diff=$(( $e - $b ))
echo $diff
}
#Record the start statistics
STARTSTAT=$(getstat)
sleep $DELAY
#Record the end statistics
ENDSTAT=$(getstat)
#http://www.mjmwired.net/kernel/Documentation/filesystems/proc.txt#1236
#echo "From $STARTSTAT"
#echo "TO $ENDSTAT"
# usr nice sys idle iowait irq guest
#From 177834 168085 1276260 3584351494 144468 154895 0 0 0 0
#TO 177834 168085 1276261 3584351895 144468 154895 0 0 0 0
USR=$(change 1)
SYS=$(change 3)
IDLE=$(change 4)
IOW=$(change 5)
#echo USR $USR SYS $SYS IDLE $IDLE IOW $IOW
ACTIVE=$(( $USR + $SYS + $IOW ))
TOTAL=$(($ACTIVE + $IDLE))
PCT=$(( $ACTIVE * 100 / $TOTAL ))
echo "BUSY $ACTIVE TOTAL $TOTAL $PCT %"Code Snippets
~ $ cat /proc/stat
cpu 177206 161827 1274669 3582291272 144435 154779 0 0 0 0
cpu0 32170 48533 914773 894903107 30650 69784 0 0 0 0
cpu1 52790 41088 180295 895685563 76035 14410 0 0 0 0
cpu2 18745 40955 49422 895959636 11295 2234 0 0 0 0
cpu3 73500 31249 130178 895742965 26454 68350 0 0 0 0
intr 339571688 48 10 0 0 0 0 2 0 1 0 0 0 152 0 0 8750527 0 322394 40428015 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
......
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 660707018
btime 1401123121
processes 196075
procs_running 1
procs_blocked 0
softirq 322202763 0 136092603 1792784 40737199 4701209 0 6 133008518 51951 5818493#!/bin/bash
#CORECOUNT=$(grep cpu /proc/stat | grep -v 'cpu ' | wc -l)
#echo $CORECOUNT cores not needed for calculation though
DELAY=${1:-1}
function getstat() {
grep 'cpu ' /proc/stat | sed -e 's/ */x/g' -e 's/^cpux//'
}
function extract() {
echo $1 | cut -d 'x' -f $2
}
function change() {
local e=$(extract $ENDSTAT $1)
local b=$(extract $STARTSTAT $1)
local diff=$(( $e - $b ))
echo $diff
}
#Record the start statistics
STARTSTAT=$(getstat)
sleep $DELAY
#Record the end statistics
ENDSTAT=$(getstat)
#http://www.mjmwired.net/kernel/Documentation/filesystems/proc.txt#1236
#echo "From $STARTSTAT"
#echo "TO $ENDSTAT"
# usr nice sys idle iowait irq guest
#From 177834 168085 1276260 3584351494 144468 154895 0 0 0 0
#TO 177834 168085 1276261 3584351895 144468 154895 0 0 0 0
USR=$(change 1)
SYS=$(change 3)
IDLE=$(change 4)
IOW=$(change 5)
#echo USR $USR SYS $SYS IDLE $IDLE IOW $IOW
ACTIVE=$(( $USR + $SYS + $IOW ))
TOTAL=$(($ACTIVE + $IDLE))
PCT=$(( $ACTIVE * 100 / $TOTAL ))
echo "BUSY $ACTIVE TOTAL $TOTAL $PCT %"Context
StackExchange Code Review Q#62388, answer score: 8
Revisions (0)
No revisions yet.