Get CPU usage in shell script? - linux

I'm running some JMeter tests against a Java process to determine how responsive a web application is under load (500+ users). JMeter will give the response time for each web request, and I've written a script to ping the Tomcat Manager every X seconds which will get me the current size of the JVM heap.
I'd like to collect stats on the server of the % of CPU being used by Tomcat. I tried to do it in a shell script using ps like this:
PS_RESULTS=`ps -o pcpu,pmem,nlwp -p $PID`
...running the command every X seconds and appending the results to a text file. (for anyone wondering, pmem = % mem usage and nlwp is number of threads)
However I've found that this gives a different definition of "% of CPU Utilization" than I'd like - according to the manpages for ps, pcpu is defined as:
cpu utilization of the process in "##.#" format. It is the CPU time used divided by the time the process has been running (cputime/realtime ratio), expressed as a percentage.
In other words, pcpu gives me the % CPU utilization for the process for the lifetime of the process.
Since I want to take a sample every X seconds, I'd like to be collecting the CPU utilization of the process at the current time only - similar to what top would give me
(CPU utilization of the process since the last update).
How can I collect this from within a shell script?

Use top -b (and other switches if you want different outputs). It will just dump to stdout instead of jumping into a curses window.

The most useful tool I've found for monitoring a server while performing a test such as JMeter on it is dstat. It not only gives you a range of stats from the server, it outputs to csv for easy import into a spreadsheet and lets you extend the tool with modules written in Python.

User load: top -b -n 2 |grep Cpu |tail -n 1 |awk '{print $2}' |sed 's/.[^.]*$//'
System load: top -b -n 2 |grep Cpu |tail -n 1 |awk '{print $3}' |sed 's/.[^.]*$//'
Idle load: top -b -n 1 |grep Cpu |tail -n 1 |awk '{print $5}' |sed 's/.[^.]*$//'
Every outcome is a round decimal.

Off the top of my head, I'd use the /proc filesystem view of the system state - Look at man 5 proc to see the format of the entry for /proc/PID/stat, which contains total CPU usage information, and use /proc/stat to get global system information. To obtain "current time" usage, you probably really mean "CPU used in the last N seconds"; take two samples a short distance apart to see the current rate of CPU consumption. You can then munge these values into something useful. Really though, this is probably more a Perl/Ruby/Python job than a pure shell script.
You might be able to get the rough data you're after with /proc/PID/status, which gives a Sleep average for the process. Pretty coarse data though.

also use 1 as iteration count, so you will get current snapshot without waiting to get another one in $delay time.
top -b -n 1

This will not give you a per-process metric, but the Stress Terminal UI is super useful to know how badly you're punishing your boxes. Add -c flag to make it dump the data to a CSV file.

Related

How to find the average CPU of a process over X amount of time in Linux

I'm trying to find out how I can get \ calculate the CPU utilization of a specific process over X amount of time ( I write my code in python over a Linux based system ).
What I want to get for example is the average CPU of a process in the last hour\day\10 minutes...
Is there a command or a calculation I can run?
*I can't run a command like "top" in the background for X time and calculate the CPU, I need it to be in one set of commands or calculation.
I tried top research on top command but I didn't found useful info for my case.
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu - give the average consumption on the process lifetime
Can there be a way to use uptime or proc[pid]\stat to calculate this?
Thanks,
What about using pidstat?
$ pidstat -p 12345 10
Will output the stats for pid 12345 every 10 seconds. This include CPU%
From there you can run it on background, and redirect output to a file:
$ pidstat -p 12345 10 > my_pid_stats.txt &
Here is a Link with several examples. There is a lot of flexibility in the output, so you can probably customize it to better suit your needs:
https://www.thegeekstuff.com/2014/11/pidstat-examples/
pidstat is part of the sysstat package on ubuntu, in case you decide to install it.

Calculating CPU usage of a program in Linux

I want to calculate CPU usage % for a given program in Linux. Lets say I want to calculate how much amount of CPU is being used by oracle. When I do ps -elf | grep oracle I get multiple process. How can I get the cumulative result.
You cannot do simple ps -ef|grep oracle because -ef will output full information of all processes, including the command path. If you have any path containing string oracle (in this case), it will be selected, finally, it will make your calculation incorrect.
I would do with pgrep and ps to pick out the right processes you want, and list only CPU usage, finally do the sum:
ps -fho' %C' -p $(pgrep -d, oracle )|awk '{s+=($0+0)}END{printf "CPU Usage:%.2f%%",s}'
pgrep -d, oracle will list out the processes whose name contains oracle; you can use -x to do exact match, if you are sure what process name you want to search. This will output all pid in a csv format, like 123,234
ps -fho '%C' -p '123,234' will output only CPU usage for the given pids, without header, each usage percentage in a line
The final awk script will sum the value up, and print. The output should look like
CPU Usage:xx.xx%

How to make a function work in background in bash / replace text / CPU usage

I have been playing around with the bashrc and one of the thing I want to see at all time is my cpu usage in percentage. I decided to set this data in my PS1. The problem is that to have an accurate estimation of my CPU usage I need to do operations that require waiting for at least 0.5 seconds.
As a result of this, my new command line only displays at the end of the CPU calculation, 0.5 seconds later, which is really not acceptable. To deal with this I thought that I could maybe use a thread to do the CPU calculation and only display it at the end but I don't know how to do so.
One of the problem is that I display other information after CPU percentage so I don't know if it is even possible to delay the CPU display while still displaying the rest of the command line. I thought that maybe I could display a temporary string such as ??.?? and then replace it by the real value but I am not sure how to do so since if I type commands fast the position of the ??.?? can change (for example typing ls 5 times in a row very fast).
Maybe there is an even simpler solution to my problem such as calculating the CPU percentage in an other way ?
My CPU percentage calculating function:
function cpuf(){
NonIdle=0;Idle=0;Total=0;TotalD=0;Idled=0
NonIdle=$((`cat /proc/stat | awk '/^cpu / {print$2+$3+$4+$7+$8+$9}'` - $NonIdle))
Idle=$((`cat /proc/stat | awk '/^cpu / {print$5+$6}'` - $Idle))
sleep 0.5
NonIdle=$((`cat /proc/stat | awk '/^cpu / {print$2+$3+$4+$7+$8+$9}'` - $NonIdle))
Idle=$((`cat /proc/stat | awk '/^cpu / {print$5+$6}'` - $Idle))
Total=$((Idle+NonIdle))
CPU=$(((Total-Idle)/Total))
echo `echo "scale=2;($Total*100-$Idle*100)/$Total" | bc -l`
}
How I call it in the bashrc:
alias cpu="cpuf"
PS1+="(\[${MAGENTA}\]CPU $(cpu)%"
There is no need to reinvent the wheel here, linux already takes care of capturing system stats in /proc/loadavg. The first number is average load in the last minute across all cpus, so we just need to divide by the number of cpus, which we can determine by reading /proc/cpuinfo. Rolling this into .bashrc we get:
.bashrc
...
# My fancy prompt, adjust as you like...
FANCY_PROMPT="$GREEN\u$YELLOW#\h:$PURPLE\w$BLUE$ $RESET"
CPUS=$( grep -c bogomips /proc/cpuinfo )
_prompt_command() {
LOAD_AVG_1_MIN=$( cut -d ' ' -f 1 /proc/loadavg )
PERCENT=$( echo "scale=0; $LOAD_AVG_1_MIN * 100 / $CPUS" | bc -l )
PS1="CPU $PERCENT% $FANCY_PROMPT"
true
}
PROMPT_COMMAND="_prompt_command"
In Use:
SO linux /proc/loadavg

How to get output of top command

I'm wondering how to get the output of the 'top' command. I'm looking to obtain the number of currently running processes.
I tried putting it to a text file and got garbage. I'm unsure on how to approach this. My assignment is to determine the number of processes considered by the short-term scheduler for process allocation (processes currently ready to run) at any given time.
Use top in batch mode:
top -bn1 > output.txt
See also this previous answer.
Easier than parsing top you could count the lines in the process list:
ps -ef | wc -l

Get the load, cpu usage and time of executing a bash script

I have a bash script that I plan to run every 5 or 15 mins using crontab based on the load it puts on server.
I can find time of running the script, but load, memory usage and CPU usage I am not sure how to find.
Can someone help me?
Also any suggestions of rough benchmark that will help me decide if the script puts too much load and should be run every 15 mins and not 5 mins.
Thanks in Advance!
You can use "top -b", top gives the CPU usage, memory usage etc,
Insert these lines in your script, this will process in background and will terminate the process as soon as your testing overs.
ssh server_name "nohup top -b -d 0.5 >> file_name &"
\top process will run in background because of &, -d 0.5 will give you the cpu status at every 0.5 secs, redirect the output in file_name for latter analysis.
for killing the process after your test, insert following in your script,
ssh server_name "kill \`ps -elf | grep 'top -b' | grep -v grep | sed 's/ */ /g' |cut -d ' ' -f4\`"
Your main testing script should be between top command and command for killing top.
I presumed you are running the script from client side, if not ignore "ssh server_name".
If you are running it from client side, because of "ssh", you will be asked for the password, for avoiding this follow these 3 simple steps
This will definitely solve the issue.
You can check following utilities
pidstat for CPU load, man page
pmap for memory load, man page
Although you might need to make measurements also for the child processes of your executable, in order to collect summarizing information
For memory, use free -m. Your actual memory available is the second number next to +/- buffers/cache (in megabytes with -m) (source).
For CPU, it's a bit more complicated. Start by looking at cat /proc/stat | grep 'cpu ' (note the space). You'll see something like this:
cpu 2255 34 2290 22625563 6290 127 456
The columns are from left to right, "user, nice, system, idle". CPU usage is usually calculated as (user+nice+system) / (user+nice+system+idle). However, these numbers show the number of "time units" that the CPU has spent doing that thing since boot, and thus are always increasing. If you were to do the aforementioned calculation, you'd get the CPU usage average since boot. To get a point-in-time usage, you have to take 2 samples, find their difference, and calculate the usage from that. To be clear, that will be the average CPU usage between your samples. (source)

Resources