<?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>chrisadams.me.uk &#187; rails</title>
	<atom:link href="http://chrisadams.me.uk/tag/rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://chrisadams.me.uk</link>
	<description>Hoping to think more clearly, through thinking out loud</description>
	<lastBuildDate>Sun, 29 Aug 2010 09:29:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Avoiding that Face Palm moment with Logrotate</title>
		<link>http://chrisadams.me.uk/2010/05/10/avoiding-that-face-palm-moment-with-logrotate/</link>
		<comments>http://chrisadams.me.uk/2010/05/10/avoiding-that-face-palm-moment-with-logrotate/#comments</comments>
		<pubDate>Mon, 10 May 2010 22:08:33 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[logrotate]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://chrisadams.me.uk/?p=264</guid>
		<description><![CDATA[A runaway log file brought down on a previously built Rails app I was involved in building recently, and the solution to the problem here is so simple and easy to implement that a) I feel like a total dunce for not having this setup here in the first place b) it's almost churlish not [...]]]></description>
			<content:encoded><![CDATA[<p>A runaway log file brought down on a previously built Rails app I was involved in building recently, and the solution to the problem here is so simple and easy to implement that a) I feel like a total dunce for not having this setup here in the first place b) it's almost churlish not to list it here, for reference for someone else, in the hope that it saves them feeling this stupid themselves in the future, (oh, and keeps the site they're working on up...).</p>
<p>If you're not using Rail's own to rotate the log files it generates, it really is good idea to make sure any log files it <em>does</em> make are being rotated, to make sure you don't get caught out when that innocuous seeming <code>development.log</code> file from a few months back goes live ends up bringing down your site because it's since grown from a 6k file to a 7 gigiabyte one, and eaten all the space on your server.</p>
<p>Making sure this doesn't happen is a pretty simple process:</p>
<ul>
<li>Find where the offending logfiles are eating up all your disk space.</li>
<li>Create a new <a href="http://gd.tuwien.ac.at/linuxcommand.org/man_pages/logrotate8.html" title="logrotate">logrotate</a> entry pointing to them.</li>
<li>Trigger the <a href="http://gd.tuwien.ac.at/linuxcommand.org/man_pages/logrotate8.html" title="logrotate">logrotate</a> daemon to test it</li>
<li>Relax and get on with your life</li>
</ul>
<p>Okay lets run through this in more detail.</p>
<h4>Find the offending logfiles</h4>
<p>The first step here is to find where the logs are being created. This here is the cause of the problem on a lot of boxes running Rails apps, because if you're using Capistrano to deploy an app, and you're using a stock Passenger config then your logs will end up in somewhere that the <a href="http://gd.tuwien.ac.at/linuxcommand.org/man_pages/logrotate8.html" title="logrotate">logrotate</a> daemon, the program that dutifully goes around compressing and sorting logfiles on your server, won't know where to look for by default.</p>
<p>Normally, you can expect to find these quietly ballooning log files somewhere like <code>/home/deploy/app/shared/log/</code>, or <code>/rails/deploy/appname.production/shared/log/</code>.</p>
<h4>Create the new logrotate entry</h4>
<p>Now that we know where the logs are that keep eating space, we can tell <a href="http://gd.tuwien.ac.at/linuxcommand.org/man_pages/logrotate8.html" title="logrotate">logrotate</a> about them, to make sure they won't grow too large. Create a text file named <code>railsapp</code> (or whatever makes the most sense to you) in <code>/etc/logrotate.d/</code>, the default place to leave instructions for <a href="http://gd.tuwien.ac.at/linuxcommand.org/man_pages/logrotate8.html" title="logrotate">logrotate</a> to follow:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">&nbsp;
<span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>deploy<span style="color: #000000; font-weight: bold;">/</span>app<span style="color: #000000; font-weight: bold;">/</span>shared<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/*</span>.log <span style="color: #7a0874; font-weight: bold;">&#123;</span>
  daily
  missingok
  rotate <span style="color: #000000;">30</span>
  compress
  delaycompress
  sharedscripts
  postrotate
    <span style="color: #c20cb9; font-weight: bold;">touch</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>deploy<span style="color: #000000; font-weight: bold;">/</span>app<span style="color: #000000; font-weight: bold;">/</span>current<span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>restart.txt
  endscript
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>Looking at that line by line:</p>
<ul>
<li><code>daily</code> calls this script daily </li>
<li><code>missingok</code> means it's okay if we're missing some log files, we'll still work without stopping</li>
<li><code>rotate 30</code> means keep the last 30 days of logs</li>
<li><code>compress</code> yup, compress the logs (using gzip by default)</li>
<li><code>delaycompress</code> means "wait til the next day before compressing this file, just incase there are still be processes writing to this logfile"</li>
<li><code>sharedscripts</code> means only call the next <code>postrotate</code> script once for all the files that match the pattern above, instead of restarting for each file</li>
<li><code>postrotate</code> ... <code>endscript</code> - this script here fires after a rotate, to restart the passenger server, so that future processes log to the fresh, empty logfile</li>
</ul>
<p>If you want to learn more, this article by <a href="http://overstimulate.com/articles/logrotate-rails-passenger" title="Log Rotation for Phusion Passenger | overstimulate">Jesse Andrews on how he uses it</a>  is an absolute gem.</p>
<h4>Trigger the logrotate daemon</h4>
<p>Now that we have a <a href="http://gd.tuwien.ac.at/linuxcommand.org/man_pages/logrotate8.html" title="logrotate">logrotate</a> entry, lets check it if works now rather than going to bed and finding out we had mistyped the path, by <em>forcing</em> a log rotate with this command (note the <code>-f</code> flag):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">logrotate <span style="color: #660033;">-f</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>logrotate.d<span style="color: #000000; font-weight: bold;">/</span>railsapp</pre></div></div>

<h4>Get on with your life</h4>
<p>If that's worked, then huzzah! That should be one less thing to worry about when looking after a webapp - though the usual "do some real homework before putting absolute faith in and deploying on a production system" disclaimers apply. As ever with Linux, be sure to <a href="http://gd.tuwien.ac.at/linuxcommand.org/man_pages/logrotate8.html" title="logrotate">read the man pages</a> before use.</p>
<p><em><em>nb.</em> While it's true that Rails is actually smart enough to rotate its own logs if you remember to configure it to behave this way, learning how to use <a href="http://gd.tuwien.ac.at/linuxcommand.org/man_pages/logrotate8.html" title="logrotate">logrotate</a> like this means we can use this on other apps too, without being too tied to a particular framework. Handy when you need it for a Merb, Sinatra, Django, or even Node.js project</em></p>
<p><!-- Links --></p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://chrisadams.me.uk/wordpress/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://chrisadams.me.uk/2010/05/10/avoiding-that-face-palm-moment-with-logrotate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Frustrating and Cryptic Ruby Idioms (#1 of a series)</title>
		<link>http://chrisadams.me.uk/2009/05/03/frustrating-and-cryptic-ruby-idioms-1-of-a-series/</link>
		<comments>http://chrisadams.me.uk/2009/05/03/frustrating-and-cryptic-ruby-idioms-1-of-a-series/#comments</comments>
		<pubDate>Sun, 03 May 2009 07:33:58 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Journal]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[idioms]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://chrisadams.me.uk/?p=150</guid>
		<description><![CDATA[I keep coming across these FACRI's (Frustrating and Cryptic Ruby Idioms) in my work, so I'm jotting them here in the hope that I'll remember them better in future. Ruby idioms Ruby is a wonderful, if somewhat slow and memory hungry language, with an incredibly flexible and expressive syntax. However this flexibility leads to the [...]]]></description>
			<content:encoded><![CDATA[<p>I keep coming across these FACRI's (Frustrating and Cryptic Ruby Idioms) in my work, so I'm jotting them here in the hope that I'll remember them better in future.</p>
<h4>Ruby idioms</h4>
<p>Ruby is a wonderful, if somewhat slow and memory hungry language, with an incredibly flexible and expressive syntax. However this flexibility leads to the creation of idioms that initially look totally opaque, if you don't know what to look for.</p>
<h5>Case in point: the object{:&amp;method} idiom</h5>
<p>If you want to take an array called names , want to create a new array by running a text manipulation on every member of that array, a terse, but readable way to do this would be:</p>
<pre><code>result = names.map { |name| name.upcase }
</code></pre>
<p>The intent is pretty clear here, and what happens programatically is also very readable. Another to do this though is write it like:</p>
<pre><code>result = names.map {&amp;:upcase}
</code></pre>
<p>Something called type coercion is occurring here; you normally pass the <code>map</code> method a <code>Proc</code> object to execute, with a placeholder name for each iteration, and the code to run and return. However because you're not passing a Proc object here, Ruby tries to convert it on the fly into a Proc object using a method called <code>to_proc</code>:</p>
<pre><code>def to_proc
  proc { |obj, *args| obj.send(self, *args) }
end
</code></pre>
<p>So in this case, it's passing in <code>names</code>, and the method in the <code>*args</code> is <code>upcase</code>. I wasn't familiar with the <code>send</code> method here either, so the <a href="http://www.ruby-doc.org/core/classes/Object.html#M000335" title="Class: Object.send">documentation for it from ruby core</a> may help here:</p>
<pre><code>class Klass
     def hello(*args)
       "Hello " + args.join(' ')
     end
   end
k = Klass.new
k.send :hello, "gentle", "readers"   #=&gt; "Hello gentle readers"
</code></pre>
<h5>An expensive idiom, by rockstars, for rockstars.</h5>
<p>Th end result of all these examples is a saving of about 12 characters, at the expense of readability, and a huge performance hit as each member in names of passed around and type coerced like there's no tomorrow.</p>
<p>If you're a coding savant, the elegance of this will probably make you weep tears of syntactic joy, and the clever brevity of this isn't lost on me.</p>
<p>However, coming to this, without too much knowledge of the Ruby extensions project, or <a href="http://pragdave.pragprog.com/pragdave/2005/11/symbolto_proc.html" title="PragDave: Symbol#to_proc">someone to talk you through what's happening</a> is likely to be a frustrating experience.</p>
<p>Hope fully this will save time for someone else in future.</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://chrisadams.me.uk/wordpress/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://chrisadams.me.uk/2009/05/03/frustrating-and-cryptic-ruby-idioms-1-of-a-series/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
