0

I want to get the CPU and Memory utilization of a process in Ubuntu. My problem is those numbers are lower than 0.01%. So how can I get the very detailed number, for example 0.00123%?

1 Answers1

0

This is a small bash script I've written to get the detailed CPU usage of a process.

#!/bin/bash

# A simple script that prints the CPU usage
# of a process with ten (10) decimals points
# (based on this https://stackoverflow.com/a/1424556/1930099).
#
# Usage: bash cpu-usage.bsh {PID_NUM}

PID=$1 # The process id
CLK_TCK=$(getconf CLK_TCK) # CPU clock ticks
CORES=$(nproc) # Number of CPU cores

main() {
    while true; do    
        local total_time_before=$(get_cpu_total_times)
        local stats_before=$(get_process_stats)
        local utime_before=$(echo $stats_before | cut -d " " -f14) # Amount of time that this process has been scheduled in user mode
        local stime_before=$(echo $stats_before | cut -d " " -f15) # Amount of time that this process has been scheduled in kernel mode

        sleep 1

        local total_time_after=$(get_cpu_total_times)
        local stats_after=$(get_process_stats)
        local utime_after=$(echo $stats_after | cut -d " " -f14)
        local stime_after=$(echo $stats_after | cut -d " " -f15)

        local user_util=$(echo "scale=10; $CORES * $CLK_TCK * ($utime_after - $utime_before) / ($total_time_after - $total_time_before)" |  bc -l | awk '{printf "%.10f\n", $0}')
        local sys_util=$(echo "scale=10; $CORES * $CLK_TCK * ($stime_after - $stime_before) / ($total_time_after - $total_time_before)" |  bc -l | awk '{printf "%.10f\n", $0}')

        echo -ne "User Utilization: $user_util % | Kernel utilization: $sys_util % \r"
    done    
}

get_cpu_total_times() {
    # The amount of time, measured in units of USER_HZ, 
    # that the system or the specific CPU spent in various states.
    local cpu_times=$(cat /proc/stat | head -n 1) # This tells you the cumulative CPU time that's been used in various categories
    local cpu_times_arr=($cpu_times)

    local user=${cpu_times_arr[1]} # Time spent in user mode
    local nice=${cpu_times_arr[2]} # Time spent in user mode with low priority (nice)
    local system=${cpu_times_arr[3]} # Time spent in system mode
    local idle=${cpu_times_arr[4]} # Time spent in the idle task

    echo $(($user + $nice + $system + $idle))
}

# Status information about the process
get_process_stats() {
    local stats=$(cat "/proc/${PID}/stat") # A pseudo-file which implements an interface to retrieve process execution statistics from the kernel 
    echo "$stats"
}

main "$@"

You'll have to read the man page of proc to understand a bit of the logic behind it. This script was based on the answer of @caf. Given that, it won't be that difficult to implement the memory utilization of a process as well.

Check /proc/[pid]/statm in proc's man page

mackatozis
  • 252
  • 1
  • 5
  • 15