Linux Shell script to monitor CPU utilization with an email alert

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:

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!

About Magesh Maruthamuthu

Love to play with all Linux distribution

View all posts by Magesh Maruthamuthu

6 Comments on “Linux Shell script to monitor CPU utilization with an email alert”

  1. 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

      1. 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.

    1. 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.

  2. 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 .

Leave a Reply to 2daygeek Cancel reply

Your email address will not be published. Required fields are marked *