Wrestling with Monit and Mongrel
Many people, including myself, have had difficulty in getting Monit to properly stop and start mongrel processes. The problem stems from the fact that Monit restricts the PATH environment variable such that it does not work with the mongrel_rails cluster::* commands. I decided to investigate this issue to find a workable solution.
First I had to decide if I even wanted to use Monit. I had written a quick script that queried the status of a cluster of Mongrels through the command mongrel cluster::status and restarted any that were not running. This would have been enough except that one aspect of Monit that is useful is that it can monitor memory consumption and restart if process uses an excessive amount of memory. This is a nice feature for running Rails applications with Mongrel as memory usage can grow substantially over time. Since I was already using Monit to monitor other processes (such as Puppet) it made sense to use for as much as possible. Though I do realize that God requires far less repetition in the configuration file.
So given that I was going to use Monit to monitor my Mongrel cluster I started looking for ways to get a functional setup. It was clear that one could forgo the cluster commands and use the process commands instead. However the problem with this approach is that the ‘clean’ option, which is a requirement to restart crashed Mongrels that leave a stale PID file, is only available using the Mongrel cluster commands. So I could have written a restart command that incorporated a PID check but that seem too cumbersome. I read examples of people setting the PATH variable with the env command but I could not get that work (along with several other people apparently).
The solution I chose was to write a short script that handled the PATH setting and called the mongrel_rails command but required the minimum number of variables. I called it monitgrel:
#!/usr/bin/ruby
# monitgrel 1.0.0
def start(dir, pid)
cmd = "/usr/local/bin/mongrel_rails cluster::start -C #{dir}/current/config/mongrel_cluster.yml --clean --only #{pid}"
system(cmd)
end
def stop(dir, pid)
cmd = "/usr/local/bin/mongrel_rails cluster::stop -C #{dir}/current/config/mongrel_cluster.yml --clean --only #{pid}"
system(cmd)
end
if ARGV.length < 3
puts "monit_helper start|stop path pid"
exit 1
end
ENV["PATH"] = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
case ARGV[0]
when 'start': start(ARGV[1], ARGV[2])
when 'stop': stop(ARGV[1], ARGV[2])
else puts 'What?'
end
It can be called from a Monit configuration file like so:
start program = "/usr/local/bin/monitgrel start /rails/app 3000"
stop program = "/usr/local/bin/monitgrel stop /rails/app 3000"
So far this is working well. Ultimately this is another hack to get around the fact that Rails is not multithreaded but in the short term it’s a good bandage.




Recent comments
20 hours 16 min ago
20 hours 17 min ago
1 week 5 days ago
11 weeks 5 days ago
12 weeks 3 days ago
17 weeks 5 days ago
17 weeks 5 days ago
17 weeks 5 days ago
18 weeks 3 days ago
18 weeks 3 days ago