System and user CPU usage of a process

MKM
thesystemadmin
Published in
2 min readOct 31, 2021

--

pidstat command helps to find utilization of a pid.

pidstat -u -p PID_NUMBER

But I’ll explain the origins of this calculation at this post. Tools like pidstat or nmon which can display detailed CPU statistics by PID use /proc/PID/stat folders.

If you run cat /proc/ANY_PID/stat you will see an output like that;

1876 (gnome-shell) S 1754 1876 1876 0 -1 4194560 142005 2538 73 8 28020 8904 7 1 20 0 17 0 1974 4344999936 53127 18446744073709551615 1 1 0 0 0 0 0 16781312 83192 0 0 0 17 2 0 0 0 0 0 0 0 0 0 0 0 0 0

The first number is PID, second is command name, third one is state…We need 14th, 15th and 22nd numbers. If you read man proc;

...
(14) utime %lu Amount of time that this process has been scheduled in user mode, measured in clock ticks (divide by sysconf(_SC_CLK_TCK)). This includes guest time, guest_time (time spent running a virtual CPU, see below), so that applications that are not aware of the guest time field do not lose that time from their calculations.
(15) stime %lu Amount of time that this process has been scheduled in kernel mode, measured in clock ticks (divide by sysconf(_SC_CLK_TCK))....(22) starttime %llu The time the process started after system boot. In kernels before Linux 2.6, this value was expressed in jiffies. Since Linux 2.6, the value is expressed in clock ticks (divide by sysconf(_SC_CLK_TCK)).
...

This values are in clock ticks. So wee need to find clock ticks per second of the system to calculate these values as seconds. This value can taken by CLK_TCK configuration variable using getconf. A typical value of clock ticks per second is 100. That is, in this case, there is a clock tick every 10 milliseconds or 0.01 second.

Calculating CPU usage of a process is conceptually;

(Seconds process ran on system / Total seconds system is up) * 100

So sys and usr usage of a process;

total_seconds = uptime — (starttime/clock_tick)
sys_cpu_usage = 100*((stime/clock_tick)/total_seconds)
usr_cpu_usage = 100*((utime/clock_tick)/total_seconds)

Code of it with Python;

#!/usr/bin/env pythonimport os
import sys
pid=str(sys.argv[1])
stream = os.popen("cat /proc/uptime | awk '{print $1}'")
uptime = int(float(stream.read()))
stream = os.popen("cat /proc/" + pid + "/stat | awk '{print $22}'")
start_time = int(stream.read())
stream = os.popen("cat /proc/" + pid + "/stat | awk '{print $14}'")
usr_usage = int(stream.read())
stream = os.popen("cat /proc/" + pid + "/stat | awk '{print $15}'")
sys_usage = int(stream.read())
stream = os.popen("getconf CLK_TCK")
clock_tick = int(stream.read())
seconds = uptime - int((start_time/clock_tick))
sys_cpu_usage = 100*((sys_usage/clock_tick)/seconds)
usr_cpu_usage = 100*((usr_usage/clock_tick)/seconds)
sys_usage = round(sys_cpu_usage,2)
usr_usage = round(usr_cpu_usage,2)
print("sys usage: " + str(sys_usage) + ", usr usage: " + str(usr_usage))

Let’s compare with pidstat;

--

--