MonkeyBrains.net/~rudy/example Random examples

mongrel_watcher.sh

I don't know ruby, but mongrel seems to crash on my customers' boxes

Well, on FreeBSD, various parts of the mongrel cluster crash, and on Linux they seem to spiral out of control and consume a lot of RAM and CPU. I don't every plan on learning ruby, so the cronjob applies the whack-a-mole technique: whenever a mongrel runs astray, we kick it in the ribs and then it starts behaving.
!/bin/sh

### Copyright (c) 2008, Rudy Rucker All rights reserved.
### Redistribution and use of script, with or without modification, is
### permitted provided that the following condition is met:
###    Redistributions of source code must retain the above copyright
###    notice, this list of conditions and the following disclaimer.
### THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
### ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
### IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
### ARE DISCLAIMED.

# mongrel restart script.
#  +  added 'check', Tue Apr  3 11:49:58 PDT 2007 - rudy
#  +  added ram check, Thu Jul 17 14:23:35 PDT 2008 - rudy
#
# Add the next two lines to root's crontab
### monitor mongrel and restart if it has crashed
##*/10 * * * *  /usr/local/etc/rc.d/mongrel.sh check


NAME='mongrel'
PATH='/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin'

## The folder you need to start mongrel from
DOGHOUSE='/some/path/to.the.rails/current'

##  Need to pull the number of servers out of this CONF file...
NUMBER=0
CONF="${DOGHOUSE}/config/mongrel_cluster.yml"
NUMBER=`grep '^servers' $CONF | awk '{print \$2}'`


# KiloByte limit per mongrel process... a safe value is calculated like this:
#    (Total Ram RAM in box) * 90% / Number of Mongrels running
# You may want to pick a higher value if you only get a periodic run-away mongrel.
MAX_RAM_PER_MONG=300000

# If the site ever goes from DEV to something else, this next line needs to be fixed.
# Basically, PIDFILES variable needs to contain every pid-file-name.  The redirect
# errors to dev null makes it so ugly errors are not displayed if mongel is not running.
PIDFILES=`ls ${DOGHOUSE}/log/mongrel.*.pid 2> /dev/null`


case "$1" in
	restart)
		echo -n "re"
		$0 start
		;;
	start)
		echo "starting $NAME"
		$0 stop
		cd ${DOGHOUSE}
		/etc/init.d/mongrel_cluster restart
		;;
	check)
		RESTART='NO'
		IS_RUNNING='NO'
		COUNT=0
		for PIDFILE in $PIDFILES; do
			if [ -f $PIDFILE ]; then
				PID=`cat $PIDFILE`
				if kill -0 $PID 2> /dev/null; then
					IS_RUNNING='YES'
					COUNT=`echo "$COUNT + 1" | bc`
				else
					RESTART='YES'
				fi
			fi
		done

		# Check for number of Mongs...
		if [ $COUNT -lt $NUMBER ]; then
			echo " *** $COUNT mongrels out of $NUMBER are running... "
			logger "[WARN] only $COUNT out of $NUMBER mongrels running"
		fi

		# Check for run away RAM Mong
		# Thu Jul 17 14:23:07 PDT 2008, added RAM check.  rudy
		for RAM in `ps xo rss,comm | grep $NAME | awk '{print $1}'`; do
			if [ $RAM -gt $MAX_RAM_PER_MONG ]; then
				echo " *** Ram usage too high for $NAME: ${RAM}k (MAX allowed ${MAX_RAM_PER_MONG}k)";
				RESTART='YES'
				logger "[WARN] runaway mongrel.  Using ${RAM}k of RAM.  Restarting"
			fi
		done



		# Check to see if anything needs a restart OR if it is not running at all.
		if [ $RESTART = 'YES' ] || [ $IS_RUNNING = 'NO' ]; then
			echo
			echo "Here is a 'ps' of the current mongrels..."
			ps xo %mem,%cpu,rss,thcount,cputime,pid,comm | egrep '(COMMAND|mong)'
			echo; echo "OK, stopping and restarting the mongrel cluster"
			$0 start
		elif [ $COUNT -lt $NUMBER ]; then
			echo "Not all ${NAME}s are up.  Issuing a restart of the mongrel cluster."
			$0 start
		fi
		;;
	stop)
		echo "stopping $NAME"
		for PIDFILE in $PIDFILES; do
			if [ -f $PIDFILE ]; then
				PID=`cat $PIDFILE`
				echo -n "Checking for $PID from $PIDFILE"
				kill $PID 2> /dev/null; sleep 1;
				if kill -0 $PID 2> /dev/null; then
					echo -n " ."
					kill -9 $PID
					sleep 1
				fi
				if kill -0 $PID 2> /dev/null; then
					echo -n " ."
					kill -9 $PID
					sleep 2
				fi
				if kill -0 $PID 2> /dev/null; then
					echo "! Check to make sure pid $PID is gone..."
					echo "! I tried to tell it to stop 3 times and then gave up."
				else
					rm $PIDFILE 2> /dev/null
				fi
				echo;
			fi
		done
		### Added killall in case ruby got running and didn't make any PID files.
		### Fri Jan 18 16:10:54 PST 2008 - Rudy
		killall ruby 2> /dev/null && sleep 1
		;;
	*)
		echo ""
		echo "Usage: `basename $0` { start | restart | stop | check }"
		echo ""
		exit 64
		;;
esac


Host your server with monkeybrains.net