<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tatva-Artha</title>
	<atom:link href="http://www.tatvartha.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.tatvartha.com</link>
	<description>meaning of &#34;it&#34;</description>
	<lastBuildDate>Wed, 01 Sep 2010 23:06:58 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Monitoring rails processes (apache, passenger, delayed_job) using god and capistrano</title>
		<link>http://www.tatvartha.com/2010/09/monitoring-rails-processes-apache-passenger-delayed_job-using-god-and-capistrano-2/</link>
		<comments>http://www.tatvartha.com/2010/09/monitoring-rails-processes-apache-passenger-delayed_job-using-god-and-capistrano-2/#comments</comments>
		<pubDate>Wed, 01 Sep 2010 23:06:57 +0000</pubDate>
		<dc:creator>Sharad</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[ruby rails god monitoring capistrano passenger delayed_job apache]]></category>

		<guid isPermaLink="false">http://www.tatvartha.com/?p=452</guid>
		<description><![CDATA[
When it comes to monitoring servers and processes in production, there is quite a few open source tools: nagios and hyperic are proven solutions for enterprise apps. Monit and god are the favorites of ruby/rails community. God has been around for a few years now and most critical issues with god seem resolved. So, I [...]


Related posts:<ol><li><a href='http://www.tatvartha.com/2009/09/defining-custom-rolesservers-in-capistrano/' rel='bookmark' title='Permanent Link: Defining custom roles/servers in capistrano'>Defining custom roles/servers in capistrano</a> <small>Capistrano works seamlessly for standard deployment where your app is...</small></li>
<li><a href='http://www.tatvartha.com/2009/11/upgrading-ubuntu-from-904-to-910/' rel='bookmark' title='Permanent Link: Upgrading Ubuntu: from 9.04 to 9.10'>Upgrading Ubuntu: from 9.04 to 9.10</a> <small>So, after ignoring the new upgrade in my update-manager for...</small></li>
<li><a href='http://www.tatvartha.com/2009/09/setting-up-sphinx-search-on-remote-server/' rel='bookmark' title='Permanent Link: Setting up Sphinx Search on remote server'>Setting up Sphinx Search on remote server</a> <small>If you are using sphinx gem for search functionality in...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm4.static.flickr.com/3156/2573042453_ff7a8c35d9.jpg" style="float: left; height; 150px; width: 300px;"/><br />
When it comes to monitoring servers and processes in production, there is quite a few open source tools: <a href="http://www.nagios.org/">nagios</a> and <a href="http://www.hyperic.com/">hyperic</a> are proven solutions for enterprise apps. Monit and <a href="http://god.rubyforge.org/">god</a> are the favorites of ruby/rails community. God has been around for a few years now and most <a href="http://blog.bradgessler.com/use-monit-with-rails-not-god">critical</a> <a href="http://stackoverflow.com/questions/768184/god-vs-monit">issues</a> with god seem resolved. So, I decided to use that on my project.</p>
<p>If you&#8217;ve worked with any deployment related stuff before, you know that it hardly ever goes as planned. With few machines involved, few processes, file/folder permissions and process permissions, there is bound to be things that will take longer. God is no different. And no wonder you will find wiki/forum posts from folks who&#8217;ve been thru it. I had my share of those and in the end I am happy with the config I found.</p>
<p>Here is a journey as it went:<br />
<span id="more-452"></span><br />
<strong>Goal-1: Monitor delayed_job using god:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># run with: god -c /path/to/file.god -D</span>
RAILS_ROOT = <span style="color:#996600;">&quot;/home/sjain/projects/pfa/omt&quot;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># Watch for delayed_job</span>
God.<span style="color:#9900CC;">watch</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>w<span style="color:#006600; font-weight:bold;">|</span>
&nbsp;
  w.<span style="color:#9900CC;">name</span> = <span style="color:#996600;">&quot;delayed_job&quot;</span>
  w.<span style="color:#9900CC;">interval</span> = 30.<span style="color:#9900CC;">seconds</span> <span style="color:#008000; font-style:italic;"># default</span>
  w.<span style="color:#9900CC;">dir</span> = RAILS_ROOT
  w.<span style="color:#9900CC;">start</span> = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>RAILS_ROOT, <span style="color:#996600;">&quot;script/delayed_job start&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  w.<span style="color:#9900CC;">stop</span> = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>RAILS_ROOT, <span style="color:#996600;">&quot;script/delayed_job stop&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  w.<span style="color:#9900CC;">restart</span> = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>RAILS_ROOT, <span style="color:#996600;">&quot;script/delayed_job restart&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  w.<span style="color:#9900CC;">start_grace</span> = 10.<span style="color:#9900CC;">seconds</span>
  w.<span style="color:#9900CC;">restart_grace</span> = 10.<span style="color:#9900CC;">seconds</span>
  w.<span style="color:#9900CC;">pid_file</span> = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>RAILS_ROOT, <span style="color:#996600;">&quot;tmp/pids/delayed_job.pid&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  w.<span style="color:#9900CC;">log</span> = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>RAILS_ROOT, <span style="color:#996600;">'log/god.log'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  w.<span style="color:#9900CC;">behavior</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:clean_pid_file</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  w.<span style="color:#9900CC;">start_if</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>on<span style="color:#006600; font-weight:bold;">|</span>
    on.<span style="color:#9900CC;">condition</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:process_running</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>c<span style="color:#006600; font-weight:bold;">|</span>
      c.<span style="color:#9900CC;">interval</span> = 5.<span style="color:#9900CC;">seconds</span>
      c.<span style="color:#9900CC;">running</span> = <span style="color:#0000FF; font-weight:bold;">false</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># lifecycle stuff goes here ...</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>This is fairly standard from God&#8217;s website. The only interesting thing here is I kept RAILS_ROOT as a string constant at the top since I know I will have to make it configurable as part of my capistrano deploy script. With this, I could run following command and have god monitor my delayed job:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ god <span style="color: #660033;">-c</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>html<span style="color: #000000; font-weight: bold;">/</span>application<span style="color: #000000; font-weight: bold;">/</span>current<span style="color: #000000; font-weight: bold;">/</span>config<span style="color: #000000; font-weight: bold;">/</span>app.conf
<span style="color: #666666; font-style: italic;"># Verify with 'god status'</span></pre></div></div>

<p><strong>Goal-2: Monitor apache using god:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># Watch for apache</span>
God.<span style="color:#9900CC;">watch</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>w<span style="color:#006600; font-weight:bold;">|</span>
&nbsp;
  watch_name = <span style="color:#996600;">&quot;app_server&quot;</span>
  w.<span style="color:#9900CC;">name</span> = watch_name
  w.<span style="color:#9900CC;">interval</span> = 30.<span style="color:#9900CC;">seconds</span> <span style="color:#008000; font-style:italic;"># default</span>
  w.<span style="color:#9900CC;">dir</span> = RAILS_ROOT
  w.<span style="color:#9900CC;">start</span> = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>RAILS_ROOT, <span style="color:#996600;">&quot;/etc/init.d/httpd start&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  w.<span style="color:#9900CC;">stop</span> = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>RAILS_ROOT, <span style="color:#996600;">&quot;/etc/init.d/httpd stop&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  w.<span style="color:#9900CC;">restart</span> = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>RAILS_ROOT, <span style="color:#996600;">&quot;/etc/init.d/httpd restart&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  w.<span style="color:#9900CC;">start_grace</span> = 10.<span style="color:#9900CC;">seconds</span>
  w.<span style="color:#9900CC;">restart_grace</span> = 10.<span style="color:#9900CC;">seconds</span>
&nbsp;
  w.<span style="color:#9900CC;">start_if</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>on<span style="color:#006600; font-weight:bold;">|</span>
    on.<span style="color:#9900CC;">condition</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:http_response_code</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>c<span style="color:#006600; font-weight:bold;">|</span>
      c.<span style="color:#9900CC;">host</span> = <span style="color:#996600;">'localhost'</span>
      c.<span style="color:#9900CC;">port</span> = <span style="color:#006666;">3000</span>
      c.<span style="color:#9900CC;">path</span> = <span style="color:#996600;">'/'</span>
      c.<span style="color:#9900CC;">code_is_not</span> = <span style="color:#006666;">200</span>
      c.<span style="color:#9900CC;">timeout</span> = 10.<span style="color:#9900CC;">seconds</span>
      c.<span style="color:#9900CC;">times</span> = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">2</span>, <span style="color:#006666;">5</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>This was a straight modification from the delayed_job config, which didn&#8217;t work for a few reasons:</p>
<p>1) Since I was starting god under my account, it couldn&#8217;t execute the start/stop commands specified in the watch file. For those to work, I had to start god script under sudo permissions.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">$ sudo god <span style="color:#006600; font-weight:bold;">-</span>c <span style="color:#006600; font-weight:bold;">/</span>var<span style="color:#006600; font-weight:bold;">/</span>www<span style="color:#006600; font-weight:bold;">/</span>html<span style="color:#006600; font-weight:bold;">/</span>application<span style="color:#006600; font-weight:bold;">/</span>current<span style="color:#006600; font-weight:bold;">/</span>config<span style="color:#006600; font-weight:bold;">/</span>app.<span style="color:#9900CC;">conf</span>
<span style="color:#008000; font-style:italic;"># Once you start god as sudo, all other commands for god need sudo as well ... 'sudo god status'</span></pre></div></div>

<p>2) The other issue with the above apache monitoring config was that once I start god as sudo, I still need my apache process to run under restricted user on the destination machine. Since we use CentOS for our production environment, this use is &#8216;www-data&#8217;. So, updated my god config with following:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># Watch for apache</span>
God.<span style="color:#9900CC;">watch</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>w<span style="color:#006600; font-weight:bold;">|</span>
  ...
  <span style="color:#9900CC;">w</span>.<span style="color:#9900CC;">uid</span> = <span style="color:#996600;">'www-data'</span>
  w.<span style="color:#9900CC;">gid</span> = <span style="color:#996600;">'www-data'</span>
  ...
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Also, now that I am starting god as sudo, all watches now need to specify uid/gid. So, I had to go back and update my delayed_job watch with uid/gid to be that of my &#8216;railsdeploy&#8217; user. My rails app gets deployed under &#8216;railsdeploy&#8217; user account and delayed_job process runs under this user as well.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># Watch for delayed_job</span>
USER = <span style="color:#996600;">&quot;railsdeploy&quot;</span>
GROUP = <span style="color:#996600;">&quot;railsdeploy&quot;</span>
&nbsp;
God.<span style="color:#9900CC;">watch</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>w<span style="color:#006600; font-weight:bold;">|</span>
  ...
  <span style="color:#9900CC;">w</span>.<span style="color:#9900CC;">uid</span> = USER
  w.<span style="color:#9900CC;">gid</span> = GROUP
  ...
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Notice, how we are not hard-coding user/group directly. We know that eventually our capistrano script will need to replace those variables with configurable values. I kept all such things at the top of my .god file. There is a few more to come.</p>
<p>3) No, that was not all. The next problem I ran into was related to user environment. Since I am starting my god under sudo now, it was not guaranteed that my environment variables are still the same under that user. I found this the hard way (another 1/2 hr.) and in my case the default PATH under sudo was setup to give access to a different ruby version that the one we use for our production environment. So, I had to update both of my watches to have few necessary environment variables.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">RAILS_ROOT = <span style="color:#996600;">&quot;/var/www/html/application/current&quot;</span>
RAILS_ENV = <span style="color:#996600;">&quot;sandbox&quot;</span>
RUBY_PATH = <span style="color:#996600;">&quot;/opt/ruby-enterprise/bin&quot;</span>
&nbsp;
God.<span style="color:#9900CC;">watch</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>w<span style="color:#006600; font-weight:bold;">|</span>
  ...
  <span style="color:#9900CC;">w</span>.<span style="color:#9900CC;">dir</span> = RAILS_ROOT
  w.<span style="color:#9900CC;">env</span> = <span style="color:#006600; font-weight:bold;">&#123;</span>
    <span style="color:#996600;">'RAILS_ROOT'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> RAILS_ROOT,
    <span style="color:#996600;">'RAILS_ENV'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> RAILS_ENV,
    <span style="color:#996600;">'PATH'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;#{RUBY_PATH}:/usr/bin:/bin&quot;</span>	
  <span style="color:#006600; font-weight:bold;">&#125;</span>
  ...
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>A few tricks to remember when working with god is where to look for clues in case something doesn&#8217;t work. I found following things useful.</p>
<p>Adding log-level of debug when firing up god:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">$ sudo god <span style="color:#006600; font-weight:bold;">--</span>log<span style="color:#006600; font-weight:bold;">-</span>level debug <span style="color:#006600; font-weight:bold;">-</span>c <span style="color:#006600; font-weight:bold;">/</span>var<span style="color:#006600; font-weight:bold;">/</span>www<span style="color:#006600; font-weight:bold;">/</span>html<span style="color:#006600; font-weight:bold;">/</span>application<span style="color:#006600; font-weight:bold;">/</span>current<span style="color:#006600; font-weight:bold;">/</span>config<span style="color:#006600; font-weight:bold;">/</span>app.<span style="color:#9900CC;">conf</span>
<span style="color:#008000; font-style:italic;"># with this god prints information each time it does a check on your monitored processes. These are big help to validate your frequency of poll and tweak your retry limits etc.</span></pre></div></div>

<p>If you didn&#8217;t specify the log file location for god in command line, they go to system messages. This can be /var/log/messages on CentOS or /var/log/Syslog on Ubuntu (I guess). You can also specify log file in command line:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">$ sudo god <span style="color:#006600; font-weight:bold;">--</span>log<span style="color:#006600; font-weight:bold;">-</span>level debug <span style="color:#006600; font-weight:bold;">-</span>c <span style="color:#006600; font-weight:bold;">/</span>var<span style="color:#006600; font-weight:bold;">/</span>www<span style="color:#006600; font-weight:bold;">/</span>html<span style="color:#006600; font-weight:bold;">/</span>application<span style="color:#006600; font-weight:bold;">/</span>current<span style="color:#006600; font-weight:bold;">/</span>config<span style="color:#006600; font-weight:bold;">/</span>app.<span style="color:#9900CC;">conf</span> <span style="color:#006600; font-weight:bold;">-</span>l <span style="color:#006600; font-weight:bold;">/</span>var<span style="color:#006600; font-weight:bold;">/</span>log<span style="color:#006600; font-weight:bold;">/</span>god.<span style="color:#9900CC;">log</span></pre></div></div>

<p>Or, during your test setup, you can run god in non-daemon mode to have it print all messages in console.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># -D option for non-daemon mode</span>
$ sudo god <span style="color:#006600; font-weight:bold;">--</span>log<span style="color:#006600; font-weight:bold;">-</span>level debug <span style="color:#006600; font-weight:bold;">-</span>c <span style="color:#006600; font-weight:bold;">/</span>var<span style="color:#006600; font-weight:bold;">/</span>www<span style="color:#006600; font-weight:bold;">/</span>html<span style="color:#006600; font-weight:bold;">/</span>application<span style="color:#006600; font-weight:bold;">/</span>current<span style="color:#006600; font-weight:bold;">/</span>config<span style="color:#006600; font-weight:bold;">/</span>app.<span style="color:#9900CC;">conf</span> <span style="color:#006600; font-weight:bold;">-</span>D</pre></div></div>

<p>So, with this, I have 2 processes being monitored and each with different user/group setting. So far, so good.</p>
<p><strong>Goal-3: Monitor passenger using god (failed):</strong></p>
<p>Since we run apache+passenger combo in our environments, I wanted to see if I can restart passenger also if http-response didn&#8217;t work as part of apache watch. So I attempted this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># adding passenger to apache monitoring</span>
God.<span style="color:#9900CC;">watch</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>w<span style="color:#006600; font-weight:bold;">|</span>
  ...
  <span style="color:#9900CC;">apache_init</span> = <span style="color:#996600;">&quot;/etc/init.d/httpd&quot;</span>
  passenger_restart = <span style="color:#996600;">&quot;touch #{RAILS_ENV}/tmp/restart.txt&quot;</span>
  w.<span style="color:#9900CC;">start</span> = <span style="color:#996600;">&quot;#{apache_init} start; #{passenger_restart}&quot;</span>
  w.<span style="color:#9900CC;">stop</span> = <span style="color:#996600;">&quot;#{apache_init} stop; #{passenger_restart}&quot;</span>
  w.<span style="color:#9900CC;">restart</span> = <span style="color:#996600;">&quot;#{apache_init} restart; #{passenger_restart}&quot;</span>
  ...
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>So, what I trying to do here is run 2 commands as part of one watch. Apparently, this doesn&#8217;t work. I believe, this has more to do with how god hands over those commands to under lying system that anything else. I couldn&#8217;t figure this one and I am not aware of the best way to monitor passenger outside of apache to I left it at that. My guess if the http-response is not working and I restart apache, it should technically restart passenger as well and fix the issue.</p>
<p><strong>Goal-4: Leverage capistrano to help with god configuration:</strong></p>
<p>Since I don&#8217;t even run apache locally for development (I run mongrel), I had to test all these things on a sandbox machine. I leveraged capistrano to help me out with deploying these god config files after I modified them each time locally. Here is what capistrano tasks looked like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"> namespace <span style="color:#ff3333; font-weight:bold;">:god</span> <span style="color:#9966CC; font-weight:bold;">do</span>
   task <span style="color:#ff3333; font-weight:bold;">:start</span>, <span style="color:#ff3333; font-weight:bold;">:roles</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:app</span> <span style="color:#9966CC; font-weight:bold;">do</span>
     god_config_file = <span style="color:#996600;">&quot;#{latest_release}/config/omt.god&quot;</span>
     sudo <span style="color:#996600;">&quot;god --log-level debug -c #{god_config_file}&quot;</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
   task <span style="color:#ff3333; font-weight:bold;">:stop</span>, <span style="color:#ff3333; font-weight:bold;">:roles</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:app</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    sudo <span style="color:#996600;">&quot;god terminate&quot;</span> <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#0000FF; font-weight:bold;">nil</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  task <span style="color:#ff3333; font-weight:bold;">:restart</span>, <span style="color:#ff3333; font-weight:bold;">:roles</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:app</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    god.<span style="color:#9900CC;">stop</span>
    god.<span style="color:#9900CC;">start</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
   task <span style="color:#ff3333; font-weight:bold;">:status</span>, <span style="color:#ff3333; font-weight:bold;">:roles</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:app</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    sudo <span style="color:#996600;">&quot;god status&quot;</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
   task <span style="color:#ff3333; font-weight:bold;">:log</span>, <span style="color:#ff3333; font-weight:bold;">:roles</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:app</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    sudo <span style="color:#996600;">&quot;tail -f /var/log/messages&quot;</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
  task <span style="color:#ff3333; font-weight:bold;">:deploy_config</span>, <span style="color:#ff3333; font-weight:bold;">:roles</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:app</span> <span style="color:#9966CC; font-weight:bold;">do</span>
     god_config_file = <span style="color:#996600;">&quot;#{latest_release}/config/omt.god&quot;</span>
     god_script_template = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">dirname</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">__FILE__</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">&quot;/deploy/templates/omt.god.erb.rb&quot;</span>
     data = <span style="color:#CC00FF; font-weight:bold;">ERB</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">IO</span>.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#40;</span>god_script_template<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">result</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">binding</span><span style="color:#006600; font-weight:bold;">&#41;</span>
     sudo <span style="color:#996600;">&quot;god load #{god_config_file}&quot;</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
   task <span style="color:#ff3333; font-weight:bold;">:redeploy</span>, <span style="color:#ff3333; font-weight:bold;">:roles</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:app</span> <span style="color:#9966CC; font-weight:bold;">do</span>
     god.<span style="color:#9900CC;">deploy_config</span>
     god.<span style="color:#9900CC;">load_config</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
 <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Most tasks are straight forward with managing god itself (start/stop/restart/log). The deploy_config tasks worked great with the following config file in order to generate proper .god config file on the destination machine:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"># run with: god -c /path/to/file.god -D
RAILS_ROOT = &quot;<span style="color:#006600; font-weight:bold;">&lt;%</span>= latest_release <span style="color:#006600; font-weight:bold;">%&gt;</span>&quot;
RAILS_ENV = &quot;<span style="color:#006600; font-weight:bold;">&lt;%</span>= rails_env <span style="color:#006600; font-weight:bold;">%&gt;</span>&quot;
USER = &quot;<span style="color:#006600; font-weight:bold;">&lt;%</span>= user <span style="color:#006600; font-weight:bold;">%&gt;</span>&quot;
GROUP = &quot;<span style="color:#006600; font-weight:bold;">&lt;%</span>= group <span style="color:#006600; font-weight:bold;">%&gt;</span>&quot;
RUBY_PATH = &quot;<span style="color:#006600; font-weight:bold;">&lt;%</span>= ruby_home <span style="color:#006600; font-weight:bold;">%&gt;</span>/bin&quot;
GOD_ENVIRONMENT = {
  'RAILS_ROOT' =&gt; RAILS_ROOT,
  'RAILS_ENV' =&gt; RAILS_ENV,
  'PATH' =&gt; &quot;#{RUBY_PATH}:/usr/bin:/bin&quot;
}
&nbsp;
God.watch do |w|
  ...
  w.dir = RAILS_ROOT
  w.env = GOD_ENVIRONMENT
  w.uid = USER
  w.gid = GROUP
  ...
end</pre></div></div>

<p>As you can see above, the constants defined at the top of .god.erb.rb template file picked values for variables from the capistrano script and replace them in template to generate the actual .god config file. Now, I could use this file to generate script for each environment and have it generate this with each god deploy. The god script once configured doesn&#8217;t change often but I still like to regenerate it with each capistrano deploy just as I would generate apache vhost file using capistrano with each deploy. This is debatable but I just like it that way.</p>
<p><strong>Goal-5: Configure god as init script</strong></p>
<p>Any monitoring solution isn&#8217;t complete until it takes care of starting/stopping itself automatically. God has to be configured to start automatically on server reboot. Now, it was time to create init script for god itself. After a few trial errors I ended up with following init script template:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># God</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># chkconfig: - 99 1</span>
<span style="color: #666666; font-style: italic;"># description: start, stop, restart God (bet you feel powerful)</span>
<span style="color: #666666; font-style: italic;">#</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># source function library</span>
. <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rc.d<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>functions
&nbsp;
<span style="color: #007800;">RUBY_PATH</span>=<span style="color: #ff0000;">&quot;&lt;%= ruby_home %&gt;/bin&quot;</span>
<span style="color: #007800;">PATH</span>=<span style="color: #007800;">$RUBY_PATH</span>:<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>sbin:<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin:<span style="color: #000000; font-weight: bold;">/</span>sbin:<span style="color: #000000; font-weight: bold;">/</span>bin:<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>sbin:<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin
<span style="color: #007800;">DAEMON</span>=<span style="color: #007800;">$RUBY_PATH</span><span style="color: #000000; font-weight: bold;">/</span>god
<span style="color: #007800;">PIDFILE</span>=<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>god.pid
<span style="color: #007800;">LOGFILE</span>=<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>god.log
<span style="color: #007800;">SCRIPTNAME</span>=<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>god
<span style="color: #007800;">CONFIGFILEDIR</span>=<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>god
&nbsp;
<span style="color: #666666; font-style: italic;">#DEBUG_OPTIONS=&quot;--log-level debug&quot;</span>
<span style="color: #007800;">DEBUG_OPTIONS</span>=<span style="color: #ff0000;">&quot;&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Gracefully exit if 'god' gem is not available.</span>
<span style="color: #7a0874; font-weight: bold;">test</span> <span style="color: #660033;">-x</span> <span style="color: #007800;">$DAEMON</span> <span style="color: #000000; font-weight: bold;">||</span> <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span>
&nbsp;
<span style="color: #007800;">RETVAL</span>=<span style="color: #000000;">0</span>
&nbsp;
god_start<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #007800;">start_cmd</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$DAEMON</span> -l <span style="color: #007800;">$LOGFILE</span> -P <span style="color: #007800;">$PIDFILE</span> <span style="color: #007800;">$DEBUG_OPTIONS</span>&quot;</span>
  <span style="color: #666666; font-style: italic;">#stop_cmd=&quot;kill -QUIT `cat $PIDFILE`&quot;</span>
  <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$start_cmd</span>
  <span style="color: #007800;">$start_cmd</span> <span style="color: #000000; font-weight: bold;">||</span> <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-en</span> <span style="color: #ff0000;">&quot;god already running&quot;</span>
  <span style="color: #007800;">RETVAL</span>=<span style="color: #007800;">$?</span>
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$RETVAL</span>&quot;</span> == <span style="color: #ff0000;">'0'</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #c20cb9; font-weight: bold;">sleep</span> <span style="color: #000000;">2</span> <span style="color: #666666; font-style: italic;"># wait for server to load before loading config files</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #007800;">$CONFIGFILEDIR</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
      <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #c20cb9; font-weight: bold;">file</span> <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-1</span> <span style="color: #007800;">$CONFIGFILEDIR</span><span style="color: #000000; font-weight: bold;">/*</span>.god<span style="color: #000000; font-weight: bold;">`</span>; <span style="color: #000000; font-weight: bold;">do</span>
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;god: loading <span style="color: #007800;">$file</span> ...&quot;</span>
        <span style="color: #007800;">$DAEMON</span> load <span style="color: #007800;">$file</span>
      <span style="color: #000000; font-weight: bold;">done</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
  <span style="color: #000000; font-weight: bold;">fi</span>
  <span style="color: #7a0874; font-weight: bold;">return</span> <span style="color: #007800;">$RETVAL</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
god_stop<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  <span style="color: #007800;">stop_cmd</span>=<span style="color: #ff0000;">&quot;god terminate&quot;</span>
  <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$stop_cmd</span>
  <span style="color: #007800;">$stop_cmd</span> <span style="color: #000000; font-weight: bold;">||</span> <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-en</span> <span style="color: #ff0000;">&quot;god not running&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #000000; font-weight: bold;">in</span>
  start<span style="color: #7a0874; font-weight: bold;">&#41;</span>
    god_start
    <span style="color: #007800;">RETVAL</span>=<span style="color: #007800;">$?</span>
    <span style="color: #000000; font-weight: bold;">;;</span>
  stop<span style="color: #7a0874; font-weight: bold;">&#41;</span>
    god_stop
    <span style="color: #007800;">RETVAL</span>=<span style="color: #007800;">$?</span>
    <span style="color: #000000; font-weight: bold;">;;</span>
  restart<span style="color: #7a0874; font-weight: bold;">&#41;</span>
    god_stop
    god_start
    <span style="color: #007800;">RETVAL</span>=<span style="color: #007800;">$?</span>
    <span style="color: #000000; font-weight: bold;">;;</span>
  status<span style="color: #7a0874; font-weight: bold;">&#41;</span>
    <span style="color: #007800;">$DAEMON</span> status
    <span style="color: #007800;">RETVAL</span>=<span style="color: #007800;">$?</span>
    <span style="color: #000000; font-weight: bold;">;;</span>
  <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Usage: god {start|stop|restart|status}&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span>
    <span style="color: #000000; font-weight: bold;">;;</span>
<span style="color: #000000; font-weight: bold;">esac</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #007800;">$RETVAL</span></pre></div></div>

<p>A few things to note here. If you look carefully at the god_start() function, it starts the god process as daemon and then loads any *.god files in /etc/god/ folder. This has several benefits. When the server reboots, god doesn&#8217;t need to hunt around for config files in various places. And whatever application needs to be monitored can have one of their config files installed here for god to pickup. The capistrano deploy can now be updated to deploy a .god file in this folder and then call &#8220;god load app.god&#8221; to have it loaded during each deploy. The next time machine/god restarts, it will pick up monitoring of configured apps automatically.</p>
<p>The capistrano task could look like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">namespace <span style="color:#ff3333; font-weight:bold;">:god</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  task <span style="color:#ff3333; font-weight:bold;">:deploy_config</span>, <span style="color:#ff3333; font-weight:bold;">:roles</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:app</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#008000; font-style:italic;"># deploy omt.god file</span>
    god_config_file = <span style="color:#996600;">&quot;#{latest_release}/config/omt.god&quot;</span>
    god_script_template = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">dirname</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">__FILE__</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">&quot;/deploy/templates/omt.god.erb.rb&quot;</span>
    data = <span style="color:#CC00FF; font-weight:bold;">ERB</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">IO</span>.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#40;</span>god_script_template<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">result</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">binding</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    put data, god_config_file
    sudo <span style="color:#996600;">&quot;mkdir -p /etc/god&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:pty</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
    sudo <span style="color:#996600;">&quot;ln -sf #{god_config_file} /etc/god/omt.god&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:pty</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
    <span style="color:#008000; font-style:italic;"># load file into god service (assumes god is already running)</span>
    god_config_file = <span style="color:#996600;">&quot;#{latest_release}/config/omt.god&quot;</span>
    sudo <span style="color:#996600;">&quot;god load #{god_config_file}&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Since each deployed environment (sandbox, staging, production) can have ruby-home in different folder location. I couldn&#8217;t use static init script file. I leveraged capistrano to use a template file (with ERB engine) to replace variables on the fly. The capistrano task for this looks as follows:</p>
<p>Even deploying god init script file could be done using capistrano:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">namespace <span style="color:#ff3333; font-weight:bold;">:god</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  task <span style="color:#ff3333; font-weight:bold;">:deploy_init_script</span>, <span style="color:#ff3333; font-weight:bold;">:roles</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:app</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#008000; font-style:italic;"># Note: god gem (version &gt;= 0.11.0) must be installed as system gem for this to work</span>
    god_init_template = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">dirname</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">__FILE__</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">&quot;/deploy/templates/god.init.template.sh&quot;</span>
    data = <span style="color:#CC00FF; font-weight:bold;">ERB</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">IO</span>.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#40;</span>god_init_template<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">result</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">binding</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    put<span style="color:#006600; font-weight:bold;">&#40;</span>data, <span style="color:#996600;">&quot;/tmp/god_init_script&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:via</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:scp</span>, <span style="color:#ff3333; font-weight:bold;">:mode</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;755&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;"># put command doesn't support sudo, so we can't directly copy to /etc/init.d folder</span>
    sudo <span style="color:#996600;">&quot;mv /tmp/god_init_script /etc/init.d/god&quot;</span>
    sudo <span style="color:#996600;">&quot;/sbin/chkconfig --level 35 god on&quot;</span> <span style="color:#008000; font-style:italic;"># enable run levels 3 and 5</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>As you can see above, we copy the init script in /etc/init.d/god folder and then run chkconfig command to have it restart automatically in unix run-levels 3 and 5. Now, assuming god is already setup on your server to run as init script. We can modify our capistrano task for god start/stop/restart/status commands to leverage unix&#8217;s standard &#8220;service&#8221; command.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># capistrano tasks: god:start, god:stop, god:restart, god:status</span>
namespace <span style="color:#ff3333; font-weight:bold;">:god</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;start&quot;</span>, <span style="color:#996600;">&quot;stop&quot;</span>, <span style="color:#996600;">&quot;restart&quot;</span>, <span style="color:#996600;">&quot;status&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>cmd<span style="color:#006600; font-weight:bold;">|</span>
    task cmd.<span style="color:#9900CC;">to_sym</span>, <span style="color:#ff3333; font-weight:bold;">:roles</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:app</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      sudo <span style="color:#996600;">&quot;service god #{cmd}&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>There is still a few more things I have to left to do. For example, monitoring  mysql database server. Since my database in production resides on a different server than app server, this will require installing a different script on mysql server machine or somehow monitor remotely from one of the app servers&#8230;</p>
<p>As I mentioned previously, deployment tasks never go as planned. There are always hiccups. But it is fun to see it all working at the end of the day!</p>


<p>Related posts:<ol><li><a href='http://www.tatvartha.com/2009/09/defining-custom-rolesservers-in-capistrano/' rel='bookmark' title='Permanent Link: Defining custom roles/servers in capistrano'>Defining custom roles/servers in capistrano</a> <small>Capistrano works seamlessly for standard deployment where your app is...</small></li>
<li><a href='http://www.tatvartha.com/2009/11/upgrading-ubuntu-from-904-to-910/' rel='bookmark' title='Permanent Link: Upgrading Ubuntu: from 9.04 to 9.10'>Upgrading Ubuntu: from 9.04 to 9.10</a> <small>So, after ignoring the new upgrade in my update-manager for...</small></li>
<li><a href='http://www.tatvartha.com/2009/09/setting-up-sphinx-search-on-remote-server/' rel='bookmark' title='Permanent Link: Setting up Sphinx Search on remote server'>Setting up Sphinx Search on remote server</a> <small>If you are using sphinx gem for search functionality in...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.tatvartha.com/2010/09/monitoring-rails-processes-apache-passenger-delayed_job-using-god-and-capistrano-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Bundler with rails 2.3.X</title>
		<link>http://www.tatvartha.com/2010/06/using-bundler-with-rails-2-3-x/</link>
		<comments>http://www.tatvartha.com/2010/06/using-bundler-with-rails-2-3-x/#comments</comments>
		<pubDate>Sat, 12 Jun 2010 01:14:57 +0000</pubDate>
		<dc:creator>Sharad</dc:creator>
				<category><![CDATA[All]]></category>

		<guid isPermaLink="false">http://www.tatvartha.com/?p=440</guid>
		<description><![CDATA[
Bundler is optional for rails 2.3.X. However, it is not a bad idea to upgrade to bundler for several reasons:

It is stable now and will solve your gem dependency conflicts better than rubygems require.
You will be better prepared to migrate to rails3 when you are ready.

Instructions for using bundler with rails 2.3 will get you [...]


Related posts:<ol><li><a href='http://www.tatvartha.com/2010/09/monitoring-rails-processes-apache-passenger-delayed_job-using-god-and-capistrano-2/' rel='bookmark' title='Permanent Link: Monitoring rails processes (apache, passenger, delayed_job) using god and capistrano'>Monitoring rails processes (apache, passenger, delayed_job) using god and capistrano</a> <small> When it comes to monitoring servers and processes in...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm3.static.flickr.com/2215/2386181060_06d0fbbaa6.jpg" style="float: right; height; 200px; width: 100px;"/><br />
<a href="http://gembundler.com/">Bundler</a> is optional for rails 2.3.X. However, it is not a bad idea to upgrade to bundler for several reasons:</p>
<ul>
<li>It is stable now and will solve your gem dependency conflicts better than rubygems require.</li>
<li>You will be better prepared to migrate to rails3 when you are ready.</li>
</ul>
<p>Instructions for using <a href="http://gembundler.com/rails23.html">bundler with rails 2.3</a> will get you off to a good start. We use <a href="http://github.com/thoughtbot/shoulda">shoulda</a> and <a href="http://github.com/floehopper/mocha">mocha</a> for our test suite. If you do too, you may run into an issue that Yehuda rightly blogged about <a href="http://yehudakatz.com/2010/04/17/ruby-require-order-problems/">here</a>.<br />
<span id="more-440"></span></p>
<p>To fix this, here is what you need to do:</p>
<p>In config/boot.rb, replace:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">def</span> load_gems
        <span style="color:#0066ff; font-weight:bold;">@bundler_loaded</span> <span style="color:#006600; font-weight:bold;">||</span>= Bundler.<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#ff3333; font-weight:bold;">:default</span>, Rails.<span style="color:#9900CC;">env</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>with:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">      <span style="color:#9966CC; font-weight:bold;">def</span> load_gems
        <span style="color:#0066ff; font-weight:bold;">@bundler_loaded</span> <span style="color:#006600; font-weight:bold;">||</span>= <span style="color:#9966CC; font-weight:bold;">begin</span>
          result = Bundler.<span style="color:#CC0066; font-weight:bold;">require</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:default</span><span style="color:#006600; font-weight:bold;">&#41;</span>
          Bundler.<span style="color:#CC0066; font-weight:bold;">require</span><span style="color:#006600; font-weight:bold;">&#40;</span>Rails.<span style="color:#9900CC;">env</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> Rails.<span style="color:#9900CC;">env</span>.<span style="color:#9900CC;">test</span>?
          result
        <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>And in your config/environments/test.rb, add following at the end:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">&quot;shoulda&quot;</span>
Bundler.<span style="color:#CC0066; font-weight:bold;">require</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:test</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>As Yehuda <a href="http://yehudakatz.com/2010/04/17/ruby-require-order-problems/">explains</a>, Mocha adds a few features depending on weather shoulda is loaded or not. The trick is to ensure that shoulda is loaded and is available before mocha is loaded.</p>
<p>Besides, if you are using mocha version 0.9.8, and have a &#8216;require &#8220;mocha&#8221;&#8216; line at the bottom of your test/test_helper.rb (as required by <a href="http://github.com/floehopper/mocha">mocha/README</a>), you can probably remove that here. Bundler takes care of it properly.</p>
<p>Again, don&#8217;t forget that non-rails commands must be executed with bundle exec:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">$ bundle <span style="color:#CC0066; font-weight:bold;">exec</span> cucumber</pre></div></div>

<p>Enjoy!</p>


<p>Related posts:<ol><li><a href='http://www.tatvartha.com/2010/09/monitoring-rails-processes-apache-passenger-delayed_job-using-god-and-capistrano-2/' rel='bookmark' title='Permanent Link: Monitoring rails processes (apache, passenger, delayed_job) using god and capistrano'>Monitoring rails processes (apache, passenger, delayed_job) using god and capistrano</a> <small> When it comes to monitoring servers and processes in...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.tatvartha.com/2010/06/using-bundler-with-rails-2-3-x/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Login as multiple users simultaneously for testing</title>
		<link>http://www.tatvartha.com/2010/05/login-as-multiple-users-simultaneously-for-testing/</link>
		<comments>http://www.tatvartha.com/2010/05/login-as-multiple-users-simultaneously-for-testing/#comments</comments>
		<pubDate>Thu, 27 May 2010 01:40:18 +0000</pubDate>
		<dc:creator>Sharad</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.tatvartha.com/?p=435</guid>
		<description><![CDATA[
Ever wondered how to login as two different users at the same time? The situation manifests in any project where you want to be able to test a workflow involving several actors with different roles. The problem is that browsers allow only one login for a given domain at any one time. So, you are [...]


Related posts:<ol><li><a href='http://www.tatvartha.com/2010/04/rails-email-unit-testing/' rel='bookmark' title='Permanent Link: Rails Email Unit Testing'>Rails Email Unit Testing</a> <small> ActionMailer classes, for sending out emails, typically reside with...</small></li>
<li><a href='http://www.tatvartha.com/2010/05/disabling-form-post-in-google-chrome-and-safari/' rel='bookmark' title='Permanent Link: Disabling form post in google chrome and safari'>Disabling form post in google chrome and safari</a> <small> So, I found this issue with google chrome and...</small></li>
<li><a href='http://www.tatvartha.com/2009/09/reverse-tunneling-and-mysql/' rel='bookmark' title='Permanent Link: Reverse Tunneling and mysql'>Reverse Tunneling and mysql</a> <small>Recently, I needed my app in staging to use my...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm3.static.flickr.com/2793/4028160820_0292417df2.jpg" style="float: left; height: 160px; width: 240px; padding: 2px; border: 1px solid black;"/></p>
<p>Ever wondered how to login as two different users at the same time? The situation manifests in any project where you want to be able to test a workflow involving several actors with different roles. The problem is that browsers allow only one login for a given domain at any one time. So, you are required to logout as current_user before logging in as another. One of the solution people use is install multiple browsers.</p>
<p><span id="more-435"></span></p>
<p><strong>Solution: Multiple Browsers</strong></p>
<p>So, lets say your favorite browser is firefox. And you also have IE7 installed by default on your windows machine. And you have a google chrome installed just so you can try out the new and blazing contribution by google. Most developers, I assume, more than a single browser installed on their system. Given this, you can login as different user in each browser.</p>
<p>This works but here is another solution that, as you will quickly realize, is better.</p>
<p><strong>Solution: Multiple names for your &#8220;localhost&#8221;</strong></p>
<p>Just update your /etc/hosts file to add more names for your local machine. Lets take a concrete example:</p>
<p>So, on a project, realted to mortgage industry, I have several actors like borrower, realtor, loan officer, mortgage-broker. I updated my /etc/hosts file (on linux) from this line:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">127.0.0.1 localhost</pre></div></div>

<p>to this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">127.0.0.1 localhost r lo mb b</pre></div></div>

<p>With this above line, I can access my local application using following URLs:</p>
<p>http://r:3000 (for realtor)<br />
http://lo:3000 (for loan officer)<br />
http://b:3000 (for borrower)<br />
http://mb:3000 (for mortage broker)</p>
<p>Now, I can open 4 tabs in a browser each with different URL and login as different users. Coupled this with password saving feature of browser, I don&#8217;t even have to type username/password for each user as long as I am disciplined about not cross-logging in as realtor inside borrower url (b:3000). Go ahead, leave yourself logged in and never logout!</p>
<p>This simple trick is better than multiple browser solution since it doesn&#8217;t require as many browser and you can have as many unique URLs as you want. And you are not limited to using this trick for local testing. If you have a staging server at http://staging.project.com that resolves to an IP, say, 192.1.2.3, you can repeat the same process:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># my /etc/hosts file</span>
127.0.0.1 localhost r lo mb b
192.1.2.3 staging.project.com sr slo smb sb
<span style="color: #666666; font-style: italic;"># Now I can</span>
<span style="color: #666666; font-style: italic;"># http://sr (staging realtor)</span>
<span style="color: #666666; font-style: italic;"># http://slo (staging loan officer)</span>
<span style="color: #666666; font-style: italic;"># you get the drill ...</span></pre></div></div>

<p>There you go. Happy testing!</p>


<p>Related posts:<ol><li><a href='http://www.tatvartha.com/2010/04/rails-email-unit-testing/' rel='bookmark' title='Permanent Link: Rails Email Unit Testing'>Rails Email Unit Testing</a> <small> ActionMailer classes, for sending out emails, typically reside with...</small></li>
<li><a href='http://www.tatvartha.com/2010/05/disabling-form-post-in-google-chrome-and-safari/' rel='bookmark' title='Permanent Link: Disabling form post in google chrome and safari'>Disabling form post in google chrome and safari</a> <small> So, I found this issue with google chrome and...</small></li>
<li><a href='http://www.tatvartha.com/2009/09/reverse-tunneling-and-mysql/' rel='bookmark' title='Permanent Link: Reverse Tunneling and mysql'>Reverse Tunneling and mysql</a> <small>Recently, I needed my app in staging to use my...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.tatvartha.com/2010/05/login-as-multiple-users-simultaneously-for-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Disabling form post in google chrome and safari</title>
		<link>http://www.tatvartha.com/2010/05/disabling-form-post-in-google-chrome-and-safari/</link>
		<comments>http://www.tatvartha.com/2010/05/disabling-form-post-in-google-chrome-and-safari/#comments</comments>
		<pubDate>Mon, 17 May 2010 22:36:07 +0000</pubDate>
		<dc:creator>Sharad</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[chrome webkit rails ajax bug]]></category>

		<guid isPermaLink="false">http://www.tatvartha.com/?p=433</guid>
		<description><![CDATA[
So, I found this issue with google chrome and safari web browser and I believe this applies to any webkit based browser. When a form submit is disabled by setting the submit button to disabled=true attribute, the browser is usually expected to prevent submission when the user hits &#8220;ENTER&#8221; on any of its text fields. [...]


Related posts:<ol><li><a href='http://www.tatvartha.com/2010/02/writing-your-greasemonkey-userscripts-in-jquery/' rel='bookmark' title='Permanent Link: Writing your Greasemonkey userscripts in jQuery'>Writing your Greasemonkey userscripts in jQuery</a> <small>I&#8217;ve played with greasemonkey and like them in concept. They...</small></li>
<li><a href='http://www.tatvartha.com/2010/05/login-as-multiple-users-simultaneously-for-testing/' rel='bookmark' title='Permanent Link: Login as multiple users simultaneously for testing'>Login as multiple users simultaneously for testing</a> <small> Ever wondered how to login as two different users...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.bruceongames.com/wp-content/uploads/2009/07/Google-Chrome-Logo.jpg" style="float: right; height: 100px; width: 100px"/><br />
So, I found this issue with google chrome and safari web browser and I believe this applies to any webkit based browser. When a form submit is disabled by setting the submit button to disabled=true attribute, the browser is usually expected to prevent submission when the user hits &#8220;ENTER&#8221; on any of its text fields. This works fine in Firefor, my default browser.</p>
<p>In my rails app, I had to do this to work around this.</p>
<p>We use haml rendering engine for our project and my form looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">-</span> remote_form_for <span style="color:#0066ff; font-weight:bold;">@product_search</span>, <span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> product_searches_path, <span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#ff3333; font-weight:bold;">:html</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:method <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:post</span>, <span style="color:#ff3333; font-weight:bold;">:id</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'product_search_form'</span><span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>form<span style="color:#006600; font-weight:bold;">|</span></pre></div></div>

<p><span id="more-433"></span><br />
This generates a form like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#006600; font-weight:bold;">&lt;</span>form onsubmit=<span style="color:#996600;">&quot;jQuery.ajax({data:jQuery.param(jQuery(this).serializeArray()) + '&amp;amp;authenticity_token=' + encodeURIComponent('MlHm/z3dsdYtETKwtNnwQlojx1NIduLlWFMECbjntsM='), dataType:'script', type:'post', url:'/product_searches'}); return false;&quot;</span>
  method=<span style="color:#996600;">&quot;post&quot;</span> id=<span style="color:#996600;">&quot;product_search_form&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">class</span>=<span style="color:#996600;">&quot;product_search&quot;</span>
  action=<span style="color:#996600;">&quot;/product_searches&quot;</span><span style="color:#006600; font-weight:bold;">&gt;</span></pre></div></div>

<p>I was working with an ajax form but I believe the bug happens even with traditional form POST as reported by another user <a href="http://code.google.com/p/chromium/issues/detail?id=37402">here</a>.</p>
<p>So, I had to create an onSubmit javascript myself to fix the situation:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">-</span> semantic_form_for <span style="color:#0066ff; font-weight:bold;">@product_search</span>, <span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> product_searches_path, <span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#ff3333; font-weight:bold;">:html</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:method <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:post</span>, <span style="color:#ff3333; font-weight:bold;">:id</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'product_search_form'</span>, <span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#ff3333; font-weight:bold;">:onsubmit</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;return jQuery.productSearchOnSubmit();&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>form<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">|</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&#40;</span>function<span style="color:#006600; font-weight:bold;">&#40;</span>$<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span>
  $.<span style="color:#9900CC;">productSearchOnSubmit</span> = function<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>$<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'#product_search_submit'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">attr</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'disabled'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
    <span style="color:#006600; font-weight:bold;">//</span> <span style="color:#9966CC; font-weight:bold;">do</span> nothing
    <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#9966CC; font-weight:bold;">else</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
      jQuery.<span style="color:#9900CC;">ajax</span><span style="color:#006600; font-weight:bold;">&#40;</span>
      <span style="color:#006600; font-weight:bold;">&#123;</span>
        data: jQuery.<span style="color:#9900CC;">param</span><span style="color:#006600; font-weight:bold;">&#40;</span>jQuery<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'#product_search_form'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">serializeArray</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">'&amp;authenticity_token='</span> <span style="color:#006600; font-weight:bold;">+</span>
        encodeURIComponent<span style="color:#006600; font-weight:bold;">&#40;</span>form_authenticity_token<span style="color:#006600; font-weight:bold;">&#41;</span>,
        dataType:<span style="color:#996600;">'script'</span>,
        type:<span style="color:#996600;">'post'</span>,
        url:<span style="color:#996600;">'/product_searches'</span>
      <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;
    <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">false</span>;
  <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#40;</span>jQuery<span style="color:#006600; font-weight:bold;">&#41;</span>;</pre></div></div>

<p>I also had to add global javascript variable for form_authenticity_token to make it available for javascript when performing submit.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">%</span>html<span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:xmlns</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;http://www.w3.org/1999/xhtml&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:lang</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;en&quot;</span>, <span style="color:#996600;">&quot;xml:lang&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;en&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#006600; font-weight:bold;">%</span>head
    <span style="color:#ff3333; font-weight:bold;">:javascript</span>
      var form_authenticity_token = <span style="color:#996600;">'#{form_authenticity_token}'</span>;</pre></div></div>

<p>If you think, this is a <a href="http://code.google.com/p/chromium/issues/detail?id=37402">bug</a> too, please vote for a fix.</p>


<p>Related posts:<ol><li><a href='http://www.tatvartha.com/2010/02/writing-your-greasemonkey-userscripts-in-jquery/' rel='bookmark' title='Permanent Link: Writing your Greasemonkey userscripts in jQuery'>Writing your Greasemonkey userscripts in jQuery</a> <small>I&#8217;ve played with greasemonkey and like them in concept. They...</small></li>
<li><a href='http://www.tatvartha.com/2010/05/login-as-multiple-users-simultaneously-for-testing/' rel='bookmark' title='Permanent Link: Login as multiple users simultaneously for testing'>Login as multiple users simultaneously for testing</a> <small> Ever wondered how to login as two different users...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.tatvartha.com/2010/05/disabling-form-post-in-google-chrome-and-safari/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails Email Unit Testing</title>
		<link>http://www.tatvartha.com/2010/04/rails-email-unit-testing/</link>
		<comments>http://www.tatvartha.com/2010/04/rails-email-unit-testing/#comments</comments>
		<pubDate>Fri, 23 Apr 2010 23:37:09 +0000</pubDate>
		<dc:creator>Sharad</dc:creator>
				<category><![CDATA[All]]></category>

		<guid isPermaLink="false">http://www.tatvartha.com/?p=427</guid>
		<description><![CDATA[
ActionMailer classes, for sending out emails, typically reside with models, inside app/models folder. Yet, they have traits that are similar to controllers. For example, each actionmailer class has a view folder inside app/views where email templates are defined. And testing support for email is provided as functional tests with assert_select macros such as assert_select_email.
In my [...]


Related posts:<ol><li><a href='http://www.tatvartha.com/2010/05/login-as-multiple-users-simultaneously-for-testing/' rel='bookmark' title='Permanent Link: Login as multiple users simultaneously for testing'>Login as multiple users simultaneously for testing</a> <small> Ever wondered how to login as two different users...</small></li>
<li><a href='http://www.tatvartha.com/2009/11/ruby-authlogic-lazy-initialization-based-on-defined-call/' rel='bookmark' title='Permanent Link: Ruby Authlogic: lazy initialization based on defined?() call'>Ruby Authlogic: lazy initialization based on defined?() call</a> <small>What is the difference between following two versions of code?...</small></li>
<li><a href='http://www.tatvartha.com/2009/09/environment-specific-routing-in-rails/' rel='bookmark' title='Permanent Link: Environment specific routing in rails'>Environment specific routing in rails</a> <small>For better application support, it is usually nice to build...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm1.static.flickr.com/86/265899766_bbf8b7e5d9.jpg" style="float: left; height: 100px; width: 140px; margin: 2px; border: 1px gray;"/></p>
<p>ActionMailer classes, for sending out emails, typically reside with models, inside app/models folder. Yet, they have traits that are similar to controllers. For example, each actionmailer class has a view folder inside app/views where email templates are defined. And testing support for email is provided as functional tests with assert_select macros such as <a href="http://guides.rubyonrails.org/testing.html#testing-views">assert_select_email</a>.</p>
<p>In my current project, most of our email hooks are defined on model classes as after_filter. This is in line with recommendation to keep controllers thin and models fat. However, testing email body&#8217;s html format is a pain since assert_select_email support is only available in ActionController::TestCase hierarchy, and not in ActionMailer::TestCase hierarchy.</p>
<p>Consider following ActionMailer test:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> MortgageBorrowerEmailerTest <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActionMailer::TestCase</span>
  should <span style="color:#996600;">&quot;invite borrowers&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    realtor, borrower = User.<span style="color:#9900CC;">make</span>, User.<span style="color:#9900CC;">make</span>
    response = MortgageBorrowerEmailer.<span style="color:#9900CC;">deliver_invite_borrowers</span><span style="color:#006600; font-weight:bold;">&#40;</span>realtor, borrower<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;"># test from/to/subject works now :-)</span>
    assert_same_elements<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#91;</span>borrower.<span style="color:#9900CC;">email</span><span style="color:#006600; font-weight:bold;">&#93;</span>, response.<span style="color:#9900CC;">to</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    assert_equal<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#91;</span>realtor.<span style="color:#9900CC;">email</span><span style="color:#006600; font-weight:bold;">&#93;</span>, response.<span style="color:#9900CC;">from</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    assert_equal<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{realtor.full_name} has invited you to manage your mortgage application in Lendable&quot;</span>, response.<span style="color:#9900CC;">subject</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;"># testing body is still primitive :-(</span>
    assert response.<span style="color:#9900CC;">body</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>realtor.<span style="color:#9900CC;">full_name</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    assert response.<span style="color:#9900CC;">body</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;/account_preferences/#{borrower.perishable_token}/edit&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>ActionMailer::TestCase has decent support for intercepting mail delivery and hold onto mails for introspection. This allows us to assert smaller pieces like from, to, subject etc. However, what it doesn&#8217;t support is more fine grained assertion on email&#8217;s html body. it would be nice to be able to apply assert_select assertion on email&#8217;s response body for critical pieces of information that needs to be present in an email.</p>
<p>So, I dug into ActionController::TestCase&#8217;s assert_select_email to see how I can duplicate it for my unit test. Here is what the original method looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># [rails]/actionpack/lib/action_controller/assertions/selector_assertions.rb</span>
<span style="color:#9966CC; font-weight:bold;">module</span> <span style="color:#6666ff; font-weight:bold;">ActionController::Assertions::SelectorAssertions</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> assert_select_email<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
    deliveries = <span style="color:#6666ff; font-weight:bold;">ActionMailer::Base</span>.<span style="color:#9900CC;">deliveries</span>
    assert !deliveries.<span style="color:#9900CC;">empty</span>?, <span style="color:#996600;">&quot;No e-mail in delivery list&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> delivery <span style="color:#9966CC; font-weight:bold;">in</span> deliveries
      <span style="color:#9966CC; font-weight:bold;">for</span> part <span style="color:#9966CC; font-weight:bold;">in</span> delivery.<span style="color:#9900CC;">parts</span>
        <span style="color:#9966CC; font-weight:bold;">if</span> part<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;Content-Type&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">to_s</span> =~ <span style="color:#006600; font-weight:bold;">/</span>^text\<span style="color:#006600; font-weight:bold;">/</span>html\W<span style="color:#006600; font-weight:bold;">/</span>
          root = <span style="color:#6666ff; font-weight:bold;">HTML::Document</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>part.<span style="color:#9900CC;">body</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">root</span>
          assert_select root, <span style="color:#996600;">&quot;:root&quot;</span>, <span style="color:#006600; font-weight:bold;">&amp;</span>block
        <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>As this implementation depicts, it is interesting to see how easy it is to take any html code snipped and create an HTML::Document out of it so that assert_select can be applied to it. Anyway, the default implementation for assert_select_email assumed multipart email with one or more parts in it. Since my email are simplistic text/html rendered as email body, I hacked to get what I needed. As follows:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> MortgageBorrowerEmailerTest <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActionMailer::TestCase</span>
  <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">ActionController::Assertions::SelectorAssertions</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> assert_select_with_string<span style="color:#006600; font-weight:bold;">&#40;</span>html_text, <span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
    root = <span style="color:#6666ff; font-weight:bold;">HTML::Document</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>html_text<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">root</span>
    assert_select root, <span style="color:#996600;">&quot;:root&quot;</span>, <span style="color:#006600; font-weight:bold;">&amp;</span>block
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>With this in place, I could now take my email response&#8217;s body and assert-select on it:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    should <span style="color:#996600;">&quot;share mortgage with existing client&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      ...
      <span style="color:#9900CC;">assert_select_with_string</span><span style="color:#006600; font-weight:bold;">&#40;</span>response.<span style="color:#9900CC;">body</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        assert_select <span style="color:#996600;">&quot;h1&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:text</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Greetings from Lendable&quot;</span>
        assert_select <span style="color:#996600;">&quot;tr#sender_identity td strong&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:text</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@realtor</span>.<span style="color:#9900CC;">full_name</span>
        assert_select <span style="color:#996600;">&quot;tr#rate_search_criteria&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
          assert_select <span style="color:#996600;">&quot;.purchase_price&quot;</span>
          assert_select <span style="color:#996600;">&quot;.loan_amount&quot;</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
        assert_select <span style="color:#996600;">&quot;tr#rate_info td a[href=?]&quot;</span>, <span style="color:#996600;">&quot;http://#{DEFAULT_HOST}/rate_selections/#{@rate_selection.id}&quot;</span>,
          <span style="color:#ff3333; font-weight:bold;">:text</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;#{@rate.program.type_and_term} Mortgage at #{number_with_precision(@rate.rate, :precision =&gt; 3)}% from #{@rate.program.lender.name}&quot;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>As we can imagine, this assert_select_with_string() can be useful in testing helper methods that return html snippets. I am not sure what the downside is for testing email body format as unit test vs. funcational test but I am happy that I can test it in isolation as unit test.</p>
<p>Do you know of any?</p>


<p>Related posts:<ol><li><a href='http://www.tatvartha.com/2010/05/login-as-multiple-users-simultaneously-for-testing/' rel='bookmark' title='Permanent Link: Login as multiple users simultaneously for testing'>Login as multiple users simultaneously for testing</a> <small> Ever wondered how to login as two different users...</small></li>
<li><a href='http://www.tatvartha.com/2009/11/ruby-authlogic-lazy-initialization-based-on-defined-call/' rel='bookmark' title='Permanent Link: Ruby Authlogic: lazy initialization based on defined?() call'>Ruby Authlogic: lazy initialization based on defined?() call</a> <small>What is the difference between following two versions of code?...</small></li>
<li><a href='http://www.tatvartha.com/2009/09/environment-specific-routing-in-rails/' rel='bookmark' title='Permanent Link: Environment specific routing in rails'>Environment specific routing in rails</a> <small>For better application support, it is usually nice to build...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.tatvartha.com/2010/04/rails-email-unit-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Internet, Email, Blogs, Forums &#8230; did we need twitter?</title>
		<link>http://www.tatvartha.com/2010/04/internet-email-blogs-forums-did-we-need-twitter/</link>
		<comments>http://www.tatvartha.com/2010/04/internet-email-blogs-forums-did-we-need-twitter/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 00:32:53 +0000</pubDate>
		<dc:creator>Sharad</dc:creator>
				<category><![CDATA[All]]></category>

		<guid isPermaLink="false">http://www.tatvartha.com/?p=423</guid>
		<description><![CDATA[
Yes, we did. And here&#8217;s why.
I was at a recent social gathering where we started talking about how funny and bizzare it is that people use twitter to post messages like .. sh**, woke up late .. having lunch at Gino&#8217;s East &#8230; driving to work &#8230; my dog peed on my bed &#8230; . [...]


No related posts.

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm3.static.flickr.com/2576/3703187062_8caebcca2f.jpg" style="float:right; width: 200px; height 150px"/><br />
Yes, we did. And here&#8217;s why.</p>
<p>I was at a recent social gathering where we started talking about how funny and bizzare it is that people use twitter to post messages like .. sh**, woke up late .. having lunch at Gino&#8217;s East &#8230; driving to work &#8230; my dog peed on my bed &#8230; . .. Oh ok, that last one is probably out of thin air but posting those kinds of messages probably don&#8217;t add much value for anybody, the author or the readers.</p>
<p>To test the waters, I created an account about 6 months ago. Very quickly I realized that twitter fills in a void that none of the other communication tools do.</p>
<p><!-- more --></p>
<p><strong>Keep in touch, I mean real touch:</strong><br />
We don&#8217;t make it a point to write email to every single one on our list of 200 or 500 contacts every once in a while. Why? Because you will have to walk down the list, write to each person individually. We would have to come up with something to talk about that this person might be interested in. Too much work. But we still want to peek into their life and vice versa to find out if there is anything that interests both of us. Twitter fits the bill. You tweet (by definition, short) about anything that touches your life. If the other person is interested in you, he/she will follow you and vaguely peruse over your tweets. You do the same and follow him. Even if you no longer meet each other (because one of you has moved to different city or different job), you can talk to each other over this channel. If everybody in my group did this, I&#8217;d be fully aware of what happens with them on a day by day, hour by hour basis without actually calling them up. And vice versa.</p>
<p>Another great advantage that isn&#8217;t apparent at first is that twitter allows me to follow person who I am not associated with directly but what he does has a large impact on my life. Since I am programming in Ruby these days, I want to know what ruby gurus (<a href="http://twitter.com/dhh">@dhh</a>, <a href="http://twitter.com/wycats">@wycats</a>) are upto each day. If you are a java programmer, you may want to follow <a href="http://twitter.com/SpringRod">RodJohnson</a>. These guys (I thank them) tweet few times a day and knowing that DHH and his team is upto each day is huge&#8230; it is gold mine!</p>
<p><strong>Mass conversation:</strong><br />
Twittering is like sitting at a bar with folks that share your interests and talk about interesting things, just that it happens in a very loosely coupled way. All the same conversation rules apply. You want to be having light and funny yet intelligent conversation without having to invest the time to walk to a bar. And you can be in multiple bars at the same time. It doesn&#8217;t replace the bar meetups but it does make it easier to have more of those in our daily life, a good thing isn&#8217;t it.</p>
<p><strong>You are never alone, even when you are alone:</strong><br />
We always had internet to keep us busy surfing and killing time when alone. One problem with plain vanilla internet surfing is that you have manually visit several websites to dig relevant pieces out that are important to you. Twitter makes it easier to subscribe to channels (people or companies or search tags) that are relevant and in very short message bursts gives you lots of superficial information. This is great for quickly perusing on channels and then dig deeper into stuff that interests you. With twitter account and a smartphone, those 5 minute wait at bus station, 10 minute wait at restaurant could be good investment in keeping in touch.</p>
<p><strong>Books, Articles, Blogs and now Twitter:</strong><br />
We couldn&#8217;t write books every month, so we started writing articles. We couldn&#8217;t write articles each week, so we invented blogs. We can&#8217;t write blogs every day, so we have twitter. It is just a very low cost way to get the message across.</p>
<p>After using it for a while here are some things I learnt as far as twitter etiquettes are concerned:</p>
<p><strong>Keep audience engaged:</strong><br />
My leg is hurting &#8230; nice weather &#8230; are boring tweets. They don&#8217;t initiate interesting conversation. Instead what I&#8217;ve found useful is to post an opinion on some news you just heard. Or some article, blog that you came across or commenting on a live TV cast of Presidents&#8217; speech. Ask quick yes/no type questions although not always. Talk about pair programming .. how about twitting a quick question to you programmer colleague on how to solve a pesky problem? beat that!</p>
<p><strong>Post often but not too often:</strong><br />
Posting 15, 20, 30 tweets a day on an account is good. Anything more is annoyance and you run the risk of loosing your followers. Posting less isn&#8217;t good either. It isn&#8217;t blog or article after all. Its purpose is to keep in touch &#8230; how about a tweet an hour on average.</p>
<p><strong>Have separate accounts:</strong><br />
You need separate accounts to match each of your personalities. By personalities, I mean you are a professional at work, music rockstar in your school circle and lazy bum in your family circle. Sometimes the differences in these personalities are so stark that you don&#8217;t want to mix those. For example, my mom and sister will have no interest what so ever in my ruby programming tweets. However, my colleague at work aren&#8217;t really interested (much) in my hindi movie reviews and cricket fan club conversations. Having separate accounts keeps things simple.</p>
<p>All in all, the concept of twitting is here to stay!</p>
<p>Certainly, a great innovation. Does twitter.com hold a patent for this <img src='http://www.tatvartha.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>


<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.tatvartha.com/2010/04/internet-email-blogs-forums-did-we-need-twitter/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Optimizing has_role? in acl9</title>
		<link>http://www.tatvartha.com/2010/03/optimizing-has_role-in-acl9/</link>
		<comments>http://www.tatvartha.com/2010/03/optimizing-has_role-in-acl9/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 16:47:00 +0000</pubDate>
		<dc:creator>Sharad</dc:creator>
				<category><![CDATA[All]]></category>

		<guid isPermaLink="false">http://www.tatvartha.com/?p=419</guid>
		<description><![CDATA[
acl9 is a an authorization library for rails applications. It is one of the widely used library if not the most widely used now. Our experience with acl9 shows that it might be heavy weight if your authorization needs are simpler (which most projects are) but could be useful for other projects.
If you&#8217;ve used acegi/spring-security [...]


Related posts:<ol><li><a href='http://www.tatvartha.com/2009/09/defining-custom-rolesservers-in-capistrano/' rel='bookmark' title='Permanent Link: Defining custom roles/servers in capistrano'>Defining custom roles/servers in capistrano</a> <small>Capistrano works seamlessly for standard deployment where your app is...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm1.static.flickr.com/84/235453953_b565f23939_m_d.jpg" alt="" style="display: inline; float: right;" height="240" border="1" width="191"/></p>
<p><a href="http://github.com/be9/acl9">acl9</a> is a an authorization library for rails applications. It is one of the widely used library if not the most widely used <a href="http://www.ruby-toolbox.com/categories/rails_authorization.html">now</a>. Our experience with acl9 shows that it might be heavy weight if your authorization needs are simpler (which most projects are) but could be useful for other projects.</p>
<p>If you&#8217;ve used <a href="http://www.acegisecurity.org/">acegi/spring-security</a> for authorization in your java apps, you know that acl9 is very similar in principle and hence very powerful. In addition to primary roles, it provides object level permissions which are stored in a generic way separately from the objects being controlled, all without the need for handcoding/distributing your authorization columns in each authorization-object tables.</p>
<p>One place where acl9 differs from acegi is how it doesn&#8217;t differentiate between a role and a permission. Acegi signifies roles as global permission level which allows you to do certain things (some action on any object of a given class). Where as, a &#8220;permission&#8221; controls whether your can take that action on a certain object of a class or not. Acl9 calls them all &#8220;roles&#8221; (primary-roles and object-roles). As you can imagine, a given user may have a few roles in system but end up with lot and lots of permissions in system depending on how many objects user owns  etc. This may seem like good idea at first but it presents a unique problem which is not apparent at first. Since roles and permissions are not conceptually separate in acl9 &#8211; and that a user can have lots of them (few roles and lots of permissions) &#8211; prevents us from loading and caching them in memory. Why do we need to keep them in memory? Because you are querying user&#8217;s primary roles most often in your rendering of pages.</p>
<p>For example, consider navigation-bar which is common in most applications. Different users are presented with different tabs in navigation-bar and this bar gets rendered on each request/response cycle. Whether to render a particular tab is conditional to whether a user has certain role (primary role in particular) or not. Since acl9 cannot keep all roles (and permissions) in memory, it has to perform database query every time it has to find whether a user has_role?(admin) or not. Given that there can be only a few primary-roles that the user will have in any system, it seems in-efficient to not cache them and go to database each time.</p>
<p>The solution would be to separate these primary-roles from permission-roles and cache them for each request. In acl9 this means overriding User.has_role? and user.has_role!.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> User
  <span style="color:#9966CC; font-weight:bold;">def</span> has_role?<span style="color:#006600; font-weight:bold;">&#40;</span>role, object = <span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> object <span style="color:#006600; font-weight:bold;">||</span> !Role.<span style="color:#9900CC;">primary</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>role<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">super</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      primary_roles.<span style="color:#9900CC;">collect</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>:name<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>role.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> has_role!<span style="color:#006600; font-weight:bold;">&#40;</span>role, object = <span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">super</span>
    <span style="color:#0066ff; font-weight:bold;">@primary_roles</span> = extract_primary_roles <span style="color:#9966CC; font-weight:bold;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span>Role.<span style="color:#9900CC;">primary</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>role<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> primary_roles
    <span style="color:#0066ff; font-weight:bold;">@primary_roles</span> <span style="color:#006600; font-weight:bold;">||</span>= extract_primary_roles
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> extract_primary_roles
     <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">role_objects</span>.<span style="color:#CC0066; font-weight:bold;">select</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>r<span style="color:#006600; font-weight:bold;">|</span> r.<span style="color:#9900CC;">primary</span>? <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  private <span style="color:#ff3333; font-weight:bold;">:extract_primary_roles</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>That does it. You cache the primary-roles and leverage those for has_role? queries.</p>


<p>Related posts:<ol><li><a href='http://www.tatvartha.com/2009/09/defining-custom-rolesservers-in-capistrano/' rel='bookmark' title='Permanent Link: Defining custom roles/servers in capistrano'>Defining custom roles/servers in capistrano</a> <small>Capistrano works seamlessly for standard deployment where your app is...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.tatvartha.com/2010/03/optimizing-has_role-in-acl9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>3 ways to send javascript alerts from rails</title>
		<link>http://www.tatvartha.com/2010/03/3-ways-to-send-javascript-alerts-from-rails/</link>
		<comments>http://www.tatvartha.com/2010/03/3-ways-to-send-javascript-alerts-from-rails/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 03:12:13 +0000</pubDate>
		<dc:creator>Sharad</dc:creator>
				<category><![CDATA[All]]></category>

		<guid isPermaLink="false">http://www.tatvartha.com/?p=415</guid>
		<description><![CDATA[


render :update do &#124;page&#124;
  page &#60;&#60; &#34;alert('message');&#34;
end




render :update do &#124;page&#124;
  page.call 'alert', &#34;message&#34;
end




render :js =&#62; &#34;alert('message');&#34;





No related posts.
Related posts brought to you by Yet Another Related Posts Plugin.


No related posts.

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<ol>
<li>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">render <span style="color:#ff3333; font-weight:bold;">:update</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>page<span style="color:#006600; font-weight:bold;">|</span>
  page <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;alert('message');&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
<li>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">render <span style="color:#ff3333; font-weight:bold;">:update</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>page<span style="color:#006600; font-weight:bold;">|</span>
  page.<span style="color:#9900CC;">call</span> <span style="color:#996600;">'alert'</span>, <span style="color:#996600;">&quot;message&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
<li>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">render <span style="color:#ff3333; font-weight:bold;">:js</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;alert('message');&quot;</span></pre></div></div>

</li>
</ol>


<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.tatvartha.com/2010/03/3-ways-to-send-javascript-alerts-from-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing your Greasemonkey userscripts in jQuery</title>
		<link>http://www.tatvartha.com/2010/02/writing-your-greasemonkey-userscripts-in-jquery/</link>
		<comments>http://www.tatvartha.com/2010/02/writing-your-greasemonkey-userscripts-in-jquery/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 05:14:46 +0000</pubDate>
		<dc:creator>Sharad</dc:creator>
				<category><![CDATA[All]]></category>

		<guid isPermaLink="false">http://www.tatvartha.com/?p=412</guid>
		<description><![CDATA[I&#8217;ve played with greasemonkey and like them in concept. They give users control of the webpage independent of the website where they are served from. I&#8217;ve used it to mostly replace default maps with google maps and to disable advertisement sections. Since, I am gaining more affinity to jQuery, it would be nice to write [...]


Related posts:<ol><li><a href='http://www.tatvartha.com/2010/05/disabling-form-post-in-google-chrome-and-safari/' rel='bookmark' title='Permanent Link: Disabling form post in google chrome and safari'>Disabling form post in google chrome and safari</a> <small> So, I found this issue with google chrome and...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve played with greasemonkey and like them in concept. They give users control of the webpage independent of the website where they are served from. I&#8217;ve used it to mostly replace default maps with google maps and to disable advertisement sections. Since, I am gaining more affinity to jQuery, it would be nice to write all my jQuery userscripts in jQuery. For this, we need to incorporate  jQuery into userscript before doing custom stuff.</p>
<p>Here is a <a href="http://joanpiedra.com/jquery/greasemonkey/">jquery userscript</a> that I found simple to integrate:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> GM_JQ <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'script'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
GM_JQ.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'http://jquery.com/src/jquery-latest.js'</span><span style="color: #339933;">;</span>
GM_JQ.<span style="color: #660066;">type</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'text/javascript'</span><span style="color: #339933;">;</span>
document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'head'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>GM_JQ<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Check if jQuery's loaded</span>
<span style="color: #003366; font-weight: bold;">function</span> GM_wait<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> unsafeWindow.<span style="color: #660066;">jQuery</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">'undefined'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> window.<span style="color: #660066;">setTimeout</span><span style="color: #009900;">&#40;</span>GM_wait<span style="color: #339933;">,</span><span style="color: #CC0000;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
	<span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span> $ <span style="color: #339933;">=</span> unsafeWindow.<span style="color: #660066;">jQuery</span><span style="color: #339933;">;</span> letsJQuery<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
GM_wait<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> letsJQuery<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #006600; font-style: italic;">// All your custom GM code must be inside this function</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>I am not sure if we can put this in a separate JS file and import this in all our customer userscripts. But it is small enough to be copy/pasted (yuck! but necessary) into each file.</p>
<p>As an example, I visit <a href="http://nationalmortgageprofessional.com/">NationalMortgageProfessional.com</a> website often for mortgage related news these days. But I hate the flashing ads on the right bar. All I needed is to hide this bar. Of course, you can do this in 2 lines in javascript, but jQuery is so much better. Here is how I did it:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> GM_JQ <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'script'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
GM_JQ.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'http://jquery.com/src/jquery-latest.js'</span><span style="color: #339933;">;</span>
GM_JQ.<span style="color: #660066;">type</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'text/javascript'</span><span style="color: #339933;">;</span>
document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'head'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>GM_JQ<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Check if jQuery's loaded</span>
<span style="color: #003366; font-weight: bold;">function</span> GM_wait<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> unsafeWindow.<span style="color: #660066;">jQuery</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">'undefined'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> window.<span style="color: #660066;">setTimeout</span><span style="color: #009900;">&#40;</span>GM_wait<span style="color: #339933;">,</span><span style="color: #CC0000;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
	<span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span> $ <span style="color: #339933;">=</span> unsafeWindow.<span style="color: #660066;">jQuery</span><span style="color: #339933;">;</span> letsJQuery<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
GM_wait<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> letsJQuery<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// hide the right sidebar with flashing ads</span>
 $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#sidebar-right'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hide</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>And there I went.<br />
Happy Reading!</p>


<p>Related posts:<ol><li><a href='http://www.tatvartha.com/2010/05/disabling-form-post-in-google-chrome-and-safari/' rel='bookmark' title='Permanent Link: Disabling form post in google chrome and safari'>Disabling form post in google chrome and safari</a> <small> So, I found this issue with google chrome and...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.tatvartha.com/2010/02/writing-your-greasemonkey-userscripts-in-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generating Time Entry from git log</title>
		<link>http://www.tatvartha.com/2010/01/generating-time-entry-from-git-log/</link>
		<comments>http://www.tatvartha.com/2010/01/generating-time-entry-from-git-log/#comments</comments>
		<pubDate>Sat, 23 Jan 2010 20:11:20 +0000</pubDate>
		<dc:creator>Sharad</dc:creator>
				<category><![CDATA[All]]></category>

		<guid isPermaLink="false">http://www.tatvartha.com/?p=408</guid>
		<description><![CDATA[Being able to track time automatically based on version control log is a recurring theme. Git makes it possible to generate ever more accurate since you can continue to perform tiny checkins to you local repository and then push it to main when you get a chance. Several folks have attempted to generate an approximation [...]


Related posts:<ol><li><a href='http://www.tatvartha.com/2009/09/rails-monkeypatching-to-pin-point-offending-code/' rel='bookmark' title='Permanent Link: Rails monkeypatching to pin-point offending code'>Rails monkeypatching to pin-point offending code</a> <small>Monkey-patching is generally a bad thing but it can help...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Being able to track time automatically based on version control log is a recurring theme. Git makes it possible to generate ever more accurate since you can continue to perform tiny checkins to you local repository and then push it to main when you get a chance. <a href="http://andy.delcambre.com/2008/02/06/git-time-tracking.html">Several</a> <a href="http://squarepush.com/articles/2009/08/06/time-taken-git-time-tracker/">folks</a> have attempted to generate an approximation of time-log based on git commit hooks.</p>
<p>I make an attempt that is less intrusive and uses just the git logs. Here is the rake task that does it:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">task <span style="color:#ff3333; font-weight:bold;">:timelog</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:environment</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  <span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'logger'</span>
  <span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'/home/sjain/projects/gems/ruby-git/lib/git'</span>
  <span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'fastercsv'</span>
  logger = <span style="color:#CC00FF; font-weight:bold;">Logger</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>STDOUT<span style="color:#006600; font-weight:bold;">&#41;</span>
  logger.<span style="color:#9900CC;">level</span> = <span style="color:#6666ff; font-weight:bold;">Logger::WARN</span>
  g = Git.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>Rails.<span style="color:#9900CC;">root</span>.<span style="color:#9900CC;">to_s</span>, <span style="color:#ff3333; font-weight:bold;">:log</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> logger<span style="color:#006600; font-weight:bold;">&#41;</span>
  logs = g.<span style="color:#9900CC;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">1000</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  log_entries = logs.<span style="color:#9900CC;">entries</span>.<span style="color:#9900CC;">reverse</span>
  worklog = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
  log_entries.<span style="color:#9900CC;">each_with_index</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>commit, index<span style="color:#006600; font-weight:bold;">|</span>
    author_date = commit.<span style="color:#9900CC;">author_date</span>.<span style="color:#9900CC;">to_date</span>
    daylog = worklog<span style="color:#006600; font-weight:bold;">&#91;</span>author_date<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">||</span> OpenStruct.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:date</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> author_date, <span style="color:#ff3333; font-weight:bold;">:duration</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    daylog.<span style="color:#9900CC;">message</span> = <span style="color:#996600;">&quot;#{daylog.message} --- #{commit.message}&quot;</span>
    daylog.<span style="color:#9900CC;">duration</span> = daylog.<span style="color:#9900CC;">duration</span> <span style="color:#006600; font-weight:bold;">+</span> calc_duration<span style="color:#006600; font-weight:bold;">&#40;</span>log_entries, index<span style="color:#006600; font-weight:bold;">&#41;</span>
    worklog<span style="color:#006600; font-weight:bold;">&#91;</span>author_date<span style="color:#006600; font-weight:bold;">&#93;</span> = daylog
  <span style="color:#9966CC; font-weight:bold;">end</span>
  FasterCSV.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;time_report.csv&quot;</span>, <span style="color:#996600;">&quot;w&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>csv<span style="color:#006600; font-weight:bold;">|</span>
    worklog.<span style="color:#9900CC;">keys</span>.<span style="color:#9900CC;">sort</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>date<span style="color:#006600; font-weight:bold;">|</span>
      duration_in_hours = <span style="color:#006600; font-weight:bold;">&#40;</span>worklog<span style="color:#006600; font-weight:bold;">&#91;</span>date<span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">duration</span><span style="color:#006600; font-weight:bold;">/</span>1.<span style="color:#9900CC;">hour</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">round</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{date.to_s(:db)} #{duration_in_hours}&quot;</span>
      csv <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span>date.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:db</span><span style="color:#006600; font-weight:bold;">&#41;</span>, duration_in_hours, worklog<span style="color:#006600; font-weight:bold;">&#91;</span>date<span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">message</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> calc_duration<span style="color:#006600; font-weight:bold;">&#40;</span>log_entries, index<span style="color:#006600; font-weight:bold;">&#41;</span>
  commit = log_entries<span style="color:#006600; font-weight:bold;">&#91;</span>index<span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> index <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">1</span>
    previous_commit = log_entries<span style="color:#006600; font-weight:bold;">&#91;</span>index<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    duration = commit.<span style="color:#9900CC;">author_date</span> <span style="color:#006600; font-weight:bold;">-</span> previous_commit.<span style="color:#9900CC;">author_date</span>
    <span style="color:#008000; font-style:italic;"># ASSUMPTION: if the gap between 2 commits is more than 3 hours, reduce it to 1-hour</span>
    duration = 0.5.<span style="color:#9900CC;">hour</span> <span style="color:#9966CC; font-weight:bold;">if</span> duration <span style="color:#006600; font-weight:bold;">&gt;</span> 3.<span style="color:#9900CC;">hour</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> duration
  <span style="color:#9966CC; font-weight:bold;">else</span>
    <span style="color:#008000; font-style:italic;"># ASSUMPTION: first commit took 1/2 hour</span>
    0.5.<span style="color:#9900CC;">hour</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>There are some sensible assumptions being made to account for that fact that you stopped working at night and continue next day. This script currently looks at all logs by everybody. On a typical project with several developers, we may want to select logs for particular authors. This script needs further enhancement in that sense.</p>
<p>What is nice about this script it doesn&#8217;t depend on any git commit hooks and can be run on any git repository, after the fact, to get an approximate hours count.</p>
<p>The more tiny commits you make, the more accurate the result is.<br />
Enjoy!</p>
<p>Note: I used <a href="http://github.com/schacon/ruby-git">ruby-git</a> for git api.</p>


<p>Related posts:<ol><li><a href='http://www.tatvartha.com/2009/09/rails-monkeypatching-to-pin-point-offending-code/' rel='bookmark' title='Permanent Link: Rails monkeypatching to pin-point offending code'>Rails monkeypatching to pin-point offending code</a> <small>Monkey-patching is generally a bad thing but it can help...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.tatvartha.com/2010/01/generating-time-entry-from-git-log/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
