#!/bin/bash max_cpu='80' # MAX CPU USAGE ALLOWED (around 40) max_mem='50' # MAX MEM USAGE ALLOWED (around 30) wait_time='7' # WAIT BEFORE KILLING PROCESS (min 5 sec) check_wait='25' # SEC BETWEEN MAIN LOOP (smaller num needs more cpu) alw_rst="2" # NUM OF RESTARTS BEFORE SHUTDOWN (around 2) max_dif="180" # SEC BETWEEN RESTARTS INSTANCES (around 180) log_file='/var/log/GameMon.log' # FULL PATH TO LOG FILE email="macie@linuxfusion.net" # NOTIFICATION EMAIL # Make it last while true; do # Seperate CPU/MEM Credentials vars='CPU MEM' for x in $vars; do # Check for % credentials if [ "$x" == "CPU" ]; then all_stats=`top -b -n1 |awk '{print $9, $1}' |grep -v "root" |grep -v ":" |grep -v "," |grep -v '%CPU' |grep -v "0[.]0"` stat_count=`echo $all_stats |wc -w` let stat_count=stat_count/2 max_stat=$max_cpu elif [ "$x" == "MEM" ]; then all_stats=`top -b -n1 |awk '{print $10, $1}' |grep -v "root" |grep -v ":" |grep -v "load" |grep -v '%MEM' |grep -v "0[.]0"` stat_count=`echo $all_stats |wc -w` let stat_count=stat_count/2 max_stat=$max_mem else check="FALSE" fi chk=1; cid=2 check="TRUE" echo ""; echo "Checking $x ($stat_count active processes)" # Do The Checking while [ "$check" == "TRUE" ]; do stat=`echo $all_stats | cut -d' ' -f"$chk" |cut -d'.' -f'1'` pid=` echo $all_stats | cut -d' ' -f"$cid"` # Test % used if [ "$stat" -ge "$max_stat" ]; then echo ""; echo "UhOh... found something" echo "Someone eating up $stat % of $x" sleep $wait_time if [ "$x" == "CPU" ]; then stat2=`top -b -n1 |awk '{print $9, $1}' |grep "$pid" |cut -d' ' -f'1' |cut -d'.' -f'1'` fi if [ "$x" == "MEM" ]; then stat2=`top -b -n1 |awk '{print $10, $1}' |grep "$pid" |cut -d' ' -f'1' |cut -d'.' -f'1'` fi # Lets see if it's still high if [ "$stat2" == "" ]; then stat2="0" fi if [ $stat2 -ge $max_stat ]; then echo "Usage verified... lets do something:" user=`ps -p $pid -o user=` echo " - It's user $user" echo " - Eating $stat/$stat2 but only $max_stat is allowed" # Verify this is a game account if [ -d "/home/$user/.cfg/" ]; then echo " - Game account verified (valid user)" if [ -f "/home/$user/.cfg/.mmt" ]; then sCount=`cat /home/$user/.cfg/.mmt |cut -d':' -f'1'` sTime=`cat /home/$user/.cfg/.mmt |cut -d':' -f'2'` cTime=`date +%s` let time_dif=$cTime-$sTime echo " - Last restart time differenceis $time_dif sec" if [ "$time_dif" -ge "$max_dif" ]; then sCount="1" echo " - BUT, time difference expired... resetting" else let sCount=sCount+1 fi if [ "$sCount" -gt "$alw_rst" ]; then echo "$sCount:`date +%s`" > /home/$user/.cfg/.mmt cmd1="stop" cmd2="stop" else echo "$sCount:`date +%s`" > /home/$user/.cfg/.mmt cmd1="stop" cmd2="restart" fi else echo "1:`date +%s`" > /home/$user/.cfg/.mmt cmd1="stop" cmd2="restart" fi # LOG IT echo "`date +'[ %D %T ]'` User ($user) requires help:" >> $log_file echo " - Attempt: $sCount" >> $log_file echo " - ($user) PID: $pid used $stat:$stat2 % of $x" >> $log_file echo " - ($user) PID: $pid needs to $cmd1 and $cmd2" >> $log_file echo "" >> $log_file # DO IT echo " - Commands issuing: ($cmd1) & ($cmd2)" su - $user -c "gamespawn $cmd1" su - $user -c "gamespawn $cmd2" if [ "$cmd1" == "$cmd2" ]; then echo "`/sbin/service sendmail start`" echo "Sending email to $email" echo "High usage has been detected! Action: Server Stopped User: $user Box: `hostname` Reason: used $stat/$stat2% $x" | mail -s "- AUTO NOTICE: Account $user stopped! -" mail $email sleep 15 echo "`/sbin/service sendmail stop`" fi else echo "`date +'[ %D %T ]'` User ($user) NOT a game account:" >> $log_file echo " - ($user) PID: $pid used $stat:$stat2 % of $x" >> $log_file echo " - ($user) PID: $pid needs to $cmd1 and $cmd2" >> $log_file echo "" >> $log_file fi fi fi usleep 500000 let cid=cid+2 let chk=chk+2 let chk_up=chk+2 test_stat=`echo $all_stats | cut -d' ' -f"$chk_up" |cut -d'.' -f'1'` printf "." if [ "$test_stat" == "" ]; then check="FALSE" fi done done echo ""; echo "Pausing GameMon for $check_wait sec!" sleep $check_wait done