CPU performance is one aspect of measuring the performance of a system, which is essential to measure the overall system-performance.
When a Linux system CPU is occupied by multiple processes, it is not available to process other requests, and the remaining pending requests must wait until the CPU is free.
If your system is under stress, it will slow down your application and becomes a bottleneck in the system.
There are numerous tools available to monitor and display CPU performance in Linux such as top, htop, glances, etc.
In this tutorial we have added two shell scripts to monitor the CPU utilization on Linux system, which is very useful when user has only few systems to monitor.
These scripts will trigger an email to the corresponding email id when the system reaches a given threshold.
Refer the following articles to understand monitoring the Memory & Disk usage with the option of an email alert:
- How to monitor disk space usage with shell script
- How to Find Out Top Memory Consuming Processes in Linux
Method-1 : Linux Shell script to monitor CPU utilization with an email alert
If you just want to get the percentage of CPU utilization (via an email alert), instead of the information about the processes, when the system reaches a given threshold, then use the script given below.
This is a simple and straightforward one liner script which triggers an email when your system reaches CPU utilization of 80%
.
*/5 * * * * /usr/bin/cat /proc/loadavg | awk '{print $1}' | awk '{ if($1 > 80) printf("Current CPU Utilization is: %.2f%\n"), $0;}' | mail -s "High CPU Alert" [email protected]
Note: Please change the email id and CPU utilization threshold values as per your requirement.
Output: You will be getting an email alert similar to the one below.
Current CPU Utilization is: 80.40%
Method-2 : Linux Shell script to monitor CPU utilization with an email alert
If you want to get detailed information about the CPU utilization processes via email alerts, then use the following script.
This includes information about the Top-10 CPU consuming processes based on the top command and ps command.
This will instantly give an idea of what’s going on in your system.
It will trigger an email when your system reaches 90%
of CPU utilization.
Note: Please change the email id and CPU utilization threshold values as per your requirement.
# vi /opt/scripts/cpu-alert.sh #!/bin/bash cpuuse=$(cat /proc/loadavg | awk '{print $3}'|cut -f 1 -d ".") if [ "$cpuuse" -ge 90 ]; then SUBJECT="ATTENTION: CPU load is high on $(hostname) at $(date)" MESSAGE="/tmp/Mail.out" TO="[email protected]" echo "CPU current usage is: $cpuuse%" >> $MESSAGE echo "" >> $MESSAGE echo "+------------------------------------------------------------------+" >> $MESSAGE echo "Top 20 processes which consuming high CPU" >> $MESSAGE echo "+------------------------------------------------------------------+" >> $MESSAGE echo "$(top -bn1 | head -20)" >> $MESSAGE echo "" >> $MESSAGE echo "+------------------------------------------------------------------+" >> $MESSAGE echo "Top 10 Processes which consuming high CPU using the ps command" >> $MESSAGE echo "+------------------------------------------------------------------+" >> $MESSAGE echo "$(ps -eo pcpu,pid,user,args | sort -k 1 -r | head -10)" >> $MESSAGE mail -s "$SUBJECT" "$TO" < $MESSAGE rm /tmp/Mail.out else echo "Server CPU usage is in under threshold" fi
Finally, add a cronjob to automate this. It will run every 5 minutes.
# crontab -e */10 * * * * /bin/bash /opt/scripts/cpu-alert.sh
Note: Since the script is scheduled to run once every 5 minutes, you will get an email alert at an interval of 5 minutes.
Say for example your system reaches the given limit after 8.25 minutes, then you will get an email alert on the second cycle i.e after 10 minutes (at the second 5 minute cycle)
Output: You will be getting an email alert similar to the one below :
CPU Current Usage is: 80.51% +------------------------------------------------------------------+ Top CPU Process Using top command +------------------------------------------------------------------+ top - 13:23:01 up 1:43, 1 user, load average: 2.58, 2.58, 1.51 Tasks: 306 total, 3 running, 303 sleeping, 0 stopped, 0 zombie %Cpu0 : 6.2 us, 6.2 sy, 0.0 ni, 87.5 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu1 : 18.8 us, 0.0 sy, 0.0 ni, 81.2 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu2 : 50.0 us, 37.5 sy, 0.0 ni, 12.5 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu3 : 5.9 us, 5.9 sy, 0.0 ni, 88.2 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu4 : 0.0 us, 5.9 sy, 0.0 ni, 94.1 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu5 : 29.4 us, 23.5 sy, 0.0 ni, 47.1 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu6 : 0.0 us, 5.9 sy, 0.0 ni, 94.1 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu7 : 5.9 us, 0.0 sy, 0.0 ni, 94.1 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 16248588 total, 223436 free, 5816924 used, 10208228 buff/cache KiB Swap: 17873388 total, 17871340 free, 2048 used. 7440884 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 8867 daygeek 20 2743884 440420 360952 R 100.0 2.7 1:07.25 /usr/lib/virtualbox/VirtualBoxVM --comment CentOS7 --startvm 002f47b8-2af2-48f5-be1d-67b67e03514c --no-startvm-errormsgbox 9119 daygeek 20 36136 784 R 46.7 0.0 0:00.07 /usr/bin/CROND -n 1057 daygeek 20 889808 487692 461692 S 13.3 3.0 4:21.12 /usr/lib/Xorg vt2 -displayfd 3 -auth /run/user/1000/gdm/Xauthority -nolisten tcp -background none -noreset -keeptty -verbose 3 3098 daygeek 20 1929012 351412 120532 S 13.3 2.2 16:42.51 /usr/lib/firefox/firefox -contentproc -childID 6 -isForBrowser -prefsLen 9236 -prefMapSize 184485 -parentBuildID 20190521202118 -greomni /us+ 1 root 20 188820 10144 7708 S 6.7 0.1 0:06.92 /sbin/init 818 gdm 20 199836 25120 15876 S 6.7 0.2 0:01.85 /usr/lib/Xorg vt1 -displayfd 3 -auth /run/user/120/gdm/Xauthority -nolisten tcp -background none -noreset -keeptty -verbose 3 1170 daygeek 9 -11 2676516 16516 12520 S 6.7 0.1 1:28.30 /usr/bin/pulseaudio --daemonize=no 8271 root 20 I 6.7 0:00.21 [kworker/u16:4-i915] 9117 daygeek 20 13528 4036 3144 R 6.7 0.0 0:00.01 top -bn1 +------------------------------------------------------------------+ Top CPU Process Using ps command +------------------------------------------------------------------+ %CPU PID USER COMMAND 8.8 8522 daygeek /usr/lib/virtualbox/VirtualBox 86.2 8867 daygeek /usr/lib/virtualbox/VirtualBoxVM --comment CentOS7 --startvm 002f47b8-2af2-48f5-be1d-67b67e03514c --no-startvm-errormsgbox 76.1 8921 daygeek /usr/lib/virtualbox/VirtualBoxVM --comment Ubuntu-18.04 --startvm e8c32dbb-8b01-41b0-977a-bf28b9db1117 --no-startvm-errormsgbox 5.5 8080 daygeek /usr/bin/nautilus --gapplication-service 4.7 4575 daygeek /usr/lib/firefox/firefox -contentproc -childID 12 -isForBrowser -prefsLen 9375 -prefMapSize 184485 -parentBuildID 20190521202118 -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 1525 true tab 4.4 3511 daygeek /usr/lib/firefox/firefox -contentproc -childID 8 -isForBrowser -prefsLen 9308 -prefMapSize 184485 -parentBuildID 20190521202118 -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 1525 true tab 4.4 3190 daygeek /usr/lib/firefox/firefox -contentproc -childID 7 -isForBrowser -prefsLen 9237 -prefMapSize 184485 -parentBuildID 20190521202118 -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 1525 true tab 4.4 1612 daygeek /usr/lib/firefox/firefox -contentproc -childID 1 -isForBrowser -prefsLen 1 -prefMapSize 184485 -parentBuildID 20190521202118 -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 1525 true tab 4.2 3565 daygeek /usr/bin/../lib/notepadqq/notepadqq-bin
Closing Notes
These shell scripts can help you to monitor and prevent your system from becoming unresponsive due to high CPU usage issue.
If you found this article helpful, please do share with your friends and spread the knowledge. Please feel free to comment below if you have any queries/concerns. We will get back to you as soon as we can. Happy learning!
Hi…,
here syntax is wrong if [ “$cpuuse” > 80 ];
need to use if [ “$cpuuse -ge “80” ] then condition will check otherwise condtion will skip and will mail for every execution .
Thanks,
Ramana
@Ramana,
I have fixed the script issue by adding additional values. Let us know if you face any issues.
Hi. Thanks for this helpful share. I am not a pro on linux so I was wondering if you can update page about how to restart a service if CPU usage exceeds threshold.
Sure, we will check about this and update the article accordingly soon.
Hi Venakataramanareddy,
What is the meaning of ” -ge “80” ” ?
while as far as I know the maximum value of the cpu load average depends on the number of cpu cores available.
Hi…,
the above script is sending the mail even if its not crossed the threshold value .please check why its sending mail if not matched threshold criteria .