Skip to content
Snippets Groups Projects
freedombone-cpu-monitor 4.3 KiB
Newer Older
#!/bin/bash
#  _____               _           _
# |   __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
# |   __|  _| -_| -_| . | . |     | . | . |   | -_|
# |__|  |_| |___|___|___|___|_|_|_|___|___|_|_|___|
#
#                              Freedom in the Cloud
#
# Daemon which monitors the cpu and looks for anomalous
# levels of usage
#
# License
# =======
#
# Copyright (C) 2018 Bob Mottram <bob@freedombone.net>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

PROJECT_NAME='freedombone'

export TEXTDOMAIN=${PROJECT_NAME}-cpu-monitor
export TEXTDOMAINDIR="/usr/share/locale"

# The initial number of samples to take before calculating
# cpu usage average
INITIAL_SAMPLES=10

# number of samples so far
no_of_samples=0

# current running average cpu usage
running_average=0
prev_running_average=0

# percent usage threshold for warnings
THRESHOLD_WARNING=80
THRESHOLD_CRITICAL=90

UPDATE_INTERVAL=10

# A timer used to count down to zero after a notification
# has been sent. This helps to suppress hunting, which could
# be annoying
suppress=0

if [ "$debug_mode" ]; then
    echo $'CPU monitor Debug mode'
    UPDATE_INTERVAL=1
fi

while true
do
    cpu_usage=$(grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage "%"}' | awk -F '.' '{print $1}')

Bob Mottram's avatar
Bob Mottram committed
    # get a number of samples first so that we're working from
    # an initial good average
    if [ $no_of_samples -lt $INITIAL_SAMPLES ]; then
        running_average=$((running_average + cpu_usage))
        no_of_samples=$((no_of_samples+1))
        if [ "$debug_mode" ]; then
            echo -n '.'
        fi
Bob Mottram's avatar
Bob Mottram committed
    # calculate the initial average cpu usage
    if [ $no_of_samples -eq $INITIAL_SAMPLES ]; then
        # calculate the initial running average value
        new_running_average=$((running_average / INITIAL_SAMPLES))
        running_average=$new_running_average
        if [ "$debug_mode" ]; then
            echo ''
            echo "initial $running_average"
        fi
        no_of_samples=$((no_of_samples+1))
    fi

Bob Mottram's avatar
Bob Mottram committed
    # subsequently calculate running average
    if [ $no_of_samples -gt $INITIAL_SAMPLES ]; then
        temp1=$((running_average*9))
        temp2=$((temp1+cpu_usage))
        running_average=$((temp2 / 10))
        if [ "$debug_mode" ]; then
            echo "$cpu_usage ${running_average}%"
        fi

Bob Mottram's avatar
Bob Mottram committed
        # if we exceed the warning threshold
        if [ $prev_running_average -lt $THRESHOLD_WARNING ]; then
            if [ $running_average -ge $THRESHOLD_WARNING ]; then
                if [ "$debug_mode" ]; then
                    echo "Warning"
                else
                    if [ $suppress -eq 0 ]; then
                        /usr/local/bin/${PROJECT_NAME}-notification -s $'High CPU usage' -m $"CPU usage is getting high. ${running_average}%"
                        suppress=180
                    fi
Bob Mottram's avatar
Bob Mottram committed
        # if we exceed the critical threshold
        if [ $prev_running_average -lt $THRESHOLD_CRITICAL ]; then
            if [ $running_average -ge $THRESHOLD_CRITICAL ]; then
                if [ "$debug_mode" ]; then
                    echo "Critical"
                else
                    if [ $suppress -eq 0 ]; then
                        /usr/local/bin/${PROJECT_NAME}-notification -s $'Critical CPU usage' -m $"CPU usage is reaching critical level. ${running_average}%"
                        suppress=180
                    fi
    # count down the suppression of messages
    if [ $suppress -gt 0 ]; then
        new_suppress=$((suppress-1))
        suppress=$new_suppress
    fi

Bob Mottram's avatar
Bob Mottram committed
    # sleep most of the time
    sleep $UPDATE_INTERVAL