Brad's Musings http://blog.bradgessler.com A Smörgåsbord of gray gooey stuff from my brain posterous.com Thu, 30 Apr 2009 14:02:00 -0700 Rails on Monit http://blog.bradgessler.com/rails-on-monit http://blog.bradgessler.com/rails-on-monit

We’ve recently switched our process monitor on our Poll Everywhere servers from the God process monitor (read about my frustrations with god and why we switched) to monit. So far things have been running great, but I ran into a few "gotchya's" while setting up monit.

Below are a few tips and tricks that I wish had appeared in Google while I was configuring monit on all of our servers:

Monit from the command line won’t work with HTTPS enabled

Actually it does work; I titled this section as-is so that others may Google and fix this problem faster. Here is what my httpd file looked like:

set httpd port 4567
         ssl enable
         pemfile /etc/monit/certs/monit.pem
         allow crypt /etc/monit/htpasswd

Then from terminal I kept running into this problem:

~# monit status
monit: cannot read status from the monit daemon

It turns out monit had no way to authenticate to the HTTP server because it didn’t have access to a clear-text password (the ones in my htpasswd file were encrypted). I just added a new user with a clear-text password to my httpd directive:

set httpd port 4567
        ssl enable
        pemfile /etc/monit/certs/monit.pem
        allow crypt /etc/monit/htpasswd
        allow monit:some-big-random-string-of-chars

When monit fires up, it reads the password from this config file and uses those credentials to control the HTTP interface.

Passing environmental variables to daemons in Monit

If you’re like us, you need to pass the RAILS_ENV=production (and maybe a few other environmental variables) into thin when booting Rails. My first swing at the problem looked like:

check process lemonade_stand_thin_9001
    with pidfile /var/run/thin.9001.pid
    start = "RAILS_ENV=production thin --port 9001 
     \ --pid /var/run/thin.9001.pid --daemonize start"

Unfortunately that didn’t work until I discovered:

check process lemonade_stand_thin_9001
    with pidfile /var/run/thin.9001.pid
    start = "/usr/bin/env RAILS_ENV=production thin --port 9001
     \ --pid /var/run/thin.9001.pid --daemonize start"

Monit XML Format

Monit exposes status information in an XML format that you could consume and use in your own apps. To get at this data format the mont url as:

http://yourserver.net:2812/_status?format=xml

I may consolidate the web interfaces on all of our machines into one console with a Sinatra app that I have yet to write. M/Monit is also available as a commercial product that consolidates monits for you starting at approximately $200.


So far monit has been pretty solid. Its already improved our uptime by quickly restarting processes that mess up and notifying us about the situation. Aside from the small pains I had getting the monit console working with HTTPS, the downside of monit is the verbosity of the configuration files when setting up a cluster:

check process lemonade_stand_thin_9000
    with pidfile /var/run/thin.9000.pid
    start = "/usr/bin/env RAILS_ENV=production thin --port 9000  
     \ --rackup /home/lemonade_stand/web/current/config.ru 
     \ --log /home/lemonade_stand/web/current/log/thin.log 
     \ --pid /var/run/thin.9000.pid --daemonize start" 
    stop = "/usr/bin/env thin --pid /var/run/thin.9000.pid stop" 
    if totalmem > 190.0 MB for 3 cycles then alert
    if totalmem > 200.0 MB for 3 cycles then restart
    if 9 restarts within 9 cycles then timeout
    group lemonade_stand
    
  check process lemonade_stand_thin_9001
    with pidfile /var/run/thin.9001.pid
    start = "/usr/bin/env RAILS_ENV=production thin --port 9001 
     \ --rackup /home/lemonade_stand/web/current/config.ru 
     \ --log /home/lemonade_stand/web/current/log/thin.log 
     \ --pid /var/run/thin.9001.pid --daemonize start" 
    stop = "/usr/bin/env thin --pid /var/run/thin.9001.pid stop" 
    if totalmem > 190.0 MB for 3 cycles then alert
    if totalmem > 200.0 MB for 3 cycles then restart
    if 9 restarts within 9 cycles then timeout
    group lemonade_stand
    
  # ... and so on ...

That is a whole lot of copy and pasting! This is an area where God has an advantage because you could iterate through an array and instanciate a God::Watch block through each pass; however, it wouldn’t be that hard to implement some sort of templating system with ERB that could compile monit configurations like this:

<% (9000..9011).each do |port| %>
check process lemonade_stand_thin_<%= port %>
    with pidfile /var/run/thin.<%= port %>.pid
    start = "/usr/bin/env RAILS_ENV=production thin --port <%= port %> 
     \ --rackup /home/lemonade_stand/web/current/config.ru 
     \ --log /home/lemonade_stand/web/current/log/thin.log 
     \ --pid /var/run/thin.<%= port %>.pid --daemonize start" 
    stop = "/usr/bin/env thin --pid /var/run/thin.<%= port %>.pid stop" 
    if totalmem > 190.0 MB for 3 cycles then alert
    if totalmem > 200.0 MB for 3 cycles then restart
    if 9 restarts within 9 cycles then timeout
    group lemonade_stand
<% end %>

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/32100/bgessler.png http://posterous.com/people/2JKWmnyY Brad Gessler Brad Brad Gessler
Fri, 24 Apr 2009 09:33:00 -0700 Use Monit with Rails, not God http://blog.bradgessler.com/use-monit-with-rails-not-god http://blog.bradgessler.com/use-monit-with-rails-not-god

First, let me get a few things off my chest about God (the process monitor, I'm not being religious here)

"God - Process Monitoring Done Horribly Wrong"
"God (like monit, but doesn't work)"

Ok, I'm here to say that I hate the process monitor called God. Why? Because contrary to what Tom Preston-Werner says, it doesn't work and its not awesome. Where do I start?

Call a turd a turd
I have a serious problem with people in the Ruby community that throw a piece of crap, half baked open-source product out there, write about how "awesome" it is, build a lot of hype around it, and waste a lot of other peoples time for them to learn that the damn thing doesn't "just work". I don't care if something is version 0.0.5 and has serious problems, but call a turd a turd, not a Cadillac with shiney rims.

Can't stop (or start) daemons properly
Good luck wiring up God on Ubuntu to start a daemonized thin server. For some reason, thin exits with an exit code other than 0. Fine, ok, I understand that. That means I should be able to run thin without daemonizing it and have god daemonize for me, right? Nope, that doesn't work either. When you try to restart or stop a non-daemonized process in god it just won't work. Even if you manage getting a daemonized process running, God sometimes forgets about the pid and stops monitoring the process.

Straw buckets are leaky
Ruby leaks. God is written in ruby. If you run God long enough, it will run out of memory and stop working properly. In all fairness, this is not Tom Preston-Werner's fault. He spent a lot of time trying to minimize the leakage in God but its simply not possible in Ruby. Monit was written properly in C meaning it won't leak like a long-running Ruby application.

God is dead
The last commit to God on github was in February during the time this article went to Posterous. That means it has been over 2 months that god couldn't stop or restart a non-daemonized process. That seems like a serious bug that should be fixed pretty fast.

---

A dissection of bullshit
Just to drive this point home, I looked through the god website and found a few good quotes:

"God (like monit, only awesome)" - What the fuck does this mean? I'm not sure what's wrong with monit. Sure the configuration files seem a bit verbose if you have to monitor and bunch of servers, but one can get around this with some simple ruby code and ERB templates to generate the monitrc file. At least monit works.

"God is an easy to configure, easy to extend monitoring framework written in Ruby." - I don't trust people that sprinkle the word "easy" all over their software. When was the last time you trusted the phrase "easy to use" when evaluating a software package? This is something the end user should decide and is better left unsaid by the software developer. For me, god was impossible to use.

"FINALLY, A CONFIG FILE THAT MAKES SENSE" - Oh really? A giant ass ruby configuration file makes more sense than a monit configuration file? I beg the differ; monit has more documentation and is surprisingly laconic when compared to a god configuration file. With monit, you don't have to deal with nested blocks.

"That's it! Simple, huh?" - Yeah, so simple that it only takes 6 months to figure out that God doesn't actually work.

Tom, please tone down the hype on the http://god.rubyforge.org/ website and be more forthcoming about disclosing all of the issues that come with god. You make it look too easy, suck people in, and waste a lot of their time and energy. If you don't have time to maintain god thats understandable, but disclose that as well.

If there is one thing you walk away with from this post its that you do not use god to monitor your server processes. If you believe the Kool-aid on the god website you're in for a rough time. Consider monit, or any other process monitor that is not written in Ruby.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/32100/bgessler.png http://posterous.com/people/2JKWmnyY Brad Gessler Brad Brad Gessler