Calculating CPU Utilisation in Linux

Metrics are really useful. It lets you monitor performance, and based on those metrics that you’ve gathered over time, you can make informed decisions on improving performance. One of these metrics is CPU utilisation.

Procfs in Linux is full of information, and CPU utilisation can be be calculated from the outputs of /proc/stat. Have a look at man proc for more details.

Here’s a small python app that reads /proc/stat and prints out the CPU utilisation time.

#!/usr/bin/python
import time

FNAME='/proc/stat'

def readBody():
    fp = open(FNAME, 'r')
    lines = []
    try:
        lines.extend([l.strip() for l in fp])
    finally:
        fp.close()
    return lines

def splitBody():
    lines = []
    lines.extend(l.split() for l in readBody())
    return lines

class CPUTime:
    user = 0
    nice = 0
    system = 0
    idle = 0
    total = 0

    def parse(self, line):
        self.user = long(line[1])
        self.nice = long(line[2])
        self.system = long(line[3])
        self.idle = long(line[4])
        self.total = float(self.user + self.nice + self.system + self.idle)

    def __repr__(self):
        return 'user=%s, nice=%s, sys=%s, idle=%s, total=%s' % (self.user, self.nice, self.system, self.idle, self.total)

    def usageUser(self):
        return self._doPercentage(self.user)

    def usageNice(self):
        return self._doPercentage(self.nice)

    def usageSystem(self):
        return self._doPercentage(self.system)

    def usageIdle(self):
        return self._doPercentage(self.idle)

    def delta(self, other):
        self.user -= other.user
        self.nice -= other.nice
        self.system -= other.system
        self.idle -= other.idle
        self.total -= other.total

    def copy(self):
        t = CPUTime()
        t.user = self.user
        t.nice = self.nice
        t.system = self.system
        t.idle = self.idle
        t.total = self.total
        return t

    def _doPercentage(self, a):
        return a / self.total * 100.0;

def main():
    print 'Collecting first sample'

    first = CPUTime()
    first.parse(splitBody()[0])

    while True:
        time.sleep(1)
        second = CPUTime()
        second.parse(splitBody()[0])
        secondCopy = second.copy()
        second.delta(first)
        print 'user=%s, nice=%s, sys=%s, idle=%s' % (second.usageUser(), second.usageNice(), second.usageSystem(), second.usageIdle())
        first = secondCopy

if __name__ == '__main__':
    main()

The source code can be downloaded from http://svn.xp-dev.com/svn/rs_scripts/trunk/get_cpu.py
as well.

Here’s an example run output:

rs@laptop:~/projects/scripts/pub$ ./get_cpu.py
Collecting first sample
user=2.5, nice=0.0, sys=0.5, idle=97.0
user=0.995024875622, nice=0.0, sys=1.49253731343, idle=97.5124378109
user=1.96078431373, nice=0.0, sys=0.490196078431, idle=97.5490196078
user=0.980392156863, nice=0.0, sys=0.980392156863, idle=98.0392156863
user=1.9512195122, nice=0.0, sys=0.975609756098, idle=97.0731707317
user=1.9801980198, nice=0.0, sys=0.990099009901, idle=97.0297029703
user=2.89855072464, nice=0.0, sys=1.44927536232, idle=95.652173913
user=2.42718446602, nice=0.0, sys=1.45631067961, idle=96.1165048544
user=6.34146341463, nice=0.0, sys=1.9512195122, idle=91.7073170732
user=1.9512195122, nice=0.0, sys=2.43902439024, idle=95.6097560976
user=3.98009950249, nice=0.497512437811, sys=1.49253731343, idle=94.0298507463
user=1.94174757282, nice=0.0, sys=0.970873786408, idle=97.0873786408
user=2.94117647059, nice=0.0, sys=0.490196078431, idle=96.568627451

Feel free to take it and do something useful from it. It’s in the public domain.

Tags: , , ,

3 Responses to “Calculating CPU Utilisation in Linux”

  1. [...] original post here: Calculating CPU Utilisation in Linux Share with [...]

  2. Haven’t you just re-invented ‘vmstat 1′?

  3. rs says:

    Well, to a certain extent, yes. But there are some advantages to this approach for those who do want to these numbers in python:

    1. No need to create another process using shutil or popen which can be clunky and resource intensive (depending on how many times you’ll be invoking it)

    2. Neater solution – only need to open a file and parse the contents. There’s no need to limit yourself to vmstat. An example will be for things like precision of the numbers, etc.

Leave a Reply