#!/bin/bash
# react2load --- CPU load watchdog
# Looks after a process and takes action if both load and time are exceeded
# Author: Arto Jääskeläinen  temp001(at)pp.inet.fi 
# GPL3 
#
# Usage:   react2load  <load_limit_%>   <time_limit_s>
#
# Example:  react2load 90 15 my_prog
#
#           =If "my_prog" makes 90 % cpu load 15 seconds it will be shut down
#
#  v1.0  2013-08-08 Initial version
#
###############################################################################

get_cpu_load()
# Estimates cpu load using one second window
# Entry:  $1 = pid
# Return: $result = approximate load in %
{
local pid=$1
result=0
[[ -d "/proc/$pid" ]] || return 1
t14_1=$(cut -d ' ' -f14 /proc/$pid/stat) 
t15_1=$(cut -d ' ' -f15 /proc/$pid/stat)
sleep 1
[[ -d "/proc/$pid" ]] || return 1
t14_2=$(cut -d ' ' -f14 /proc/$pid/stat)
t15_2=$(cut -d ' ' -f15 /proc/$pid/stat)
d_t14=$[ $t14_2-$t14_1 ]
d_t15=$[ $t15_2-$t15_1 ]
result=$[d_t14+d_t15]
if [ $result -gt 100 ]; then result=100; fi
}

react_to_load()
{
local load_limit=$1  # [ % ]
local time_limit=$2  # [ seconds ]
local pid="$3"
hi_load_count=0
times_to_check=$time_limit # since 1 s per check
i=$times_to_check
while [ $i -gt 0 ] 
	do
	[[ -d "/proc/$pid" ]] || exit 1
	get_cpu_load $pid
	if [ $? = 1 ]; then
	echo; exit
	fi
	if [ $result -ge $load_limit ]
	then 
	((hi_load_count++ ))
	((i--))
	else
	hi_load_count=0
	i=$times_to_check
	fi
	echo -ne "\r                        \r"
	echo -n "Load is $result %  $i s"
	done
if [ $hi_load_count -eq $times_to_check ]; then
echo -en "\rHigh load action taken due to $prog\n"; kill $pid
fi 
}

### Main #######################################################


prog="$3"
[[ -z "$prog" ]] && echo "Name missing" && exit
pid=$( pgrep "$prog" | grep . -m1 )
[[ -z $pid ]] && echo "Error: $prog is NOT running" && exit 1

react_to_load "$1" "$2" "$pid"
