Daemonizing Ruby Scripts for Monit

Monit is a very useful, if not occasionally frustrating tool for monitoring processes on a server. Many of you have probably used monit to keep your mongrel clusters up and running. Monit plays well with anything that has built in deamonization, but if you have a plain old Ruby script (to do file cleanups, synchronizations, or whatnot), you'll find that monit leaves you out to dry.

Luckily, there's a nice gem called daemons that makes it dead simple to daemonize your Ruby scripts. Once you've daemonized a script, you can start, stop, and restart it by calling the script with one of those commands as the first argument. It takes care of writing out a PID file and redirecting STDOUT to a logfile.

One very useful thing I needed to do was daemonize a Camping app, and since Camping doesn't have a -d option yet (hopefully someday it will), it's up to us to add that functionality. Let's see just how easy it is to write a control file for a Camping app. Here's a file named campyctl.rb:

1
2
3
4
5
6
7
8
9
10
#!/usr/local/lib/ruby
require 'rubygems'
require 'daemons'

Daemons.run('/var/www/campy/campy.rb',
            {:mode => :exec,
             :dir => '/var/www/campy/',
             :dir_mode => :normal,
             :log_output => true,
             :app_name => 'campy'})

Now we can call campyctl.rb start to fire up the camping app. Doing so will also give us a file called campy.pid that will contain the PID of the Ruby process that's running Camping, and a campy.log file with the redirected STDOUT. With a true daemon in place, we can easily set up monit to keep an eye on the process and issue a start command if it goes down!

If you need daemon functionality, totally check out daemons. In addition to the control file paradigm above it offers several other ways to daemonize your code. Great stuff, and a huge timesaver!


About this entry