<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><description>Technologic.</description><title>bitmonkey</title><generator>Tumblr (3.0; @bitmonkey)</generator><link>http://bitmonkey.net/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/bitmonkey" /><feedburner:info uri="bitmonkey" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://tumblr.superfeedr.com/" /><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbitmonkey" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/bitmonkey" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbitmonkey" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fbitmonkey" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbitmonkey" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbitmonkey" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2Fbitmonkey" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2Fbitmonkey" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fbitmonkey" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fbitmonkey" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbitmonkey" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbitmonkey" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbitmonkey" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2Fbitmonkey" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><item><title>Introducing Metriks</title><description>&lt;p&gt;I was very inspired by &lt;a href="http://codahale.com/"&gt;Coda Hale&lt;/a&gt;&amp;#8217;s &lt;a href="http://codahale.com/codeconf-2011-04-09-metrics-metrics-everywhere.pdf"&gt;Metrics Metrics Everywhere&lt;/a&gt; talk at CodeConf 2011 and have spent a lot of time over the past year thinking about it. After seeing &lt;a href="https://github.com/github/rack-statsd"&gt;rack-statsd&lt;/a&gt; and how it kept important process stats in the proctitle, I wanted the same thing for the background tasks that run &lt;a href="https://papertrailapp.com/"&gt;Papertrail&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I hadn&amp;#8217;t been able to find a metrics library for ruby that provided the calculations I was looking for, so I decided to experiment with creating one myself.&lt;/p&gt;

&lt;p&gt;The end result was an API for measurement that I&amp;#8217;m really proud of. For example, to calculate how much work a process is doing, use a meter to measure how many times an event has happened by calling the &lt;code&gt;mark()&lt;/code&gt; method on the meter:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def perform(job)
  Metriks.meter('tasks').mark
  # the work
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The meter provides methods to give a 1, 5 and 15 minute average rate-per-second. The process title can be updated in with the rate returned by &lt;code&gt;one_minute_average()&lt;/code&gt; in another thread:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;meter = Metriks.meter('tasks')
loop do
  $0 = "worker: #{meter.one_minute_average.to_i} tasks/sec"
  sleep 5
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;…which will give you the output from &lt;code&gt;ps ax&lt;/code&gt; that looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="no-highlight"&gt;22665 ?        S     17:09 worker: 273 tasks/sec&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once you are tracking those metrics in-process it becomes very easy to start sending them to remote services in all sorts of ways.&lt;/p&gt;

&lt;p&gt;The library is called &lt;a href="https://github.com/eric/metriks/"&gt;Metriks&lt;/a&gt;, an experiment in creating a ruby metrics library with a simple interface and the ability to send the metrics to a number of services.&lt;/p&gt;

&lt;h2&gt;What sort of stuff are we tracking?&lt;/h2&gt;

&lt;p&gt;Error rates, database insertion times, cache hits vs misses, messages-per-second processed by workers.&lt;/p&gt;

&lt;h2&gt;Overview&lt;/h2&gt;

&lt;p&gt;The main components of the library are the metrics and reporters.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Metrics are responsible for doing a specific kind of measurement&lt;/li&gt;
&lt;li&gt;Reporters are responsible for sending metrics to a specific destination&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Today you can send to &lt;a href="http://graphite.wikidot.com/"&gt;Graphite&lt;/a&gt;, &lt;a href="https://metrics.librato.com/"&gt;Librato Metrics&lt;/a&gt; and a log file.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s a quick review of what it&amp;#8217;s like to use it and what the important pieces of the library are. It isn&amp;#8217;t a huge amount of code, so please &lt;a href="https://github.com/eric/metriks/"&gt;check it out&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have any questions or comments, feel free to &lt;a href="https://twitter.com/lindvall"&gt;say hi on twitter&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;What does it look like to use it?&lt;/h2&gt;

&lt;h3&gt;Using a meter to track web requests&lt;/h3&gt;

&lt;p&gt;To track the number of requests per second a rack app was doing but didn&amp;#8217;t care about timing info, use a &lt;code&gt;Metriks::Meter&lt;/code&gt; which can be created by calling &lt;code&gt;Metriks.meter('name')&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s a very simple example of what it would look like to track the number of requests per second a rack app was doing.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class MetriksMiddleware &amp;lt; Rack::Middleware
  def initialize(app)
    @app = app
  end
  def call(env)
    Metriks.meter('rack.requests').mark
    @app.call(env)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Sending that metric to &lt;a href="https://metrics.librato.com/"&gt;Librato Metrics&lt;/a&gt; could get you a pretty graph looking like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.skitch.com/20120306-1fyk9p6n3f5j58rsnh4rrq1x2y.png" alt="Librato Metrics Meter"/&gt;&lt;/p&gt;

&lt;h3&gt;Using a timer to measure how long a method takes to run&lt;/h3&gt;

&lt;p&gt;To track how long it took to run a method, use a &lt;code&gt;Metriks::Timer&lt;/code&gt; which can be created with &lt;code&gt;Metriks.timer('name')&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To time how long it took to run a &lt;code&gt;fib()&lt;/code&gt; method, all it takes is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def fib(n)
  n &amp;lt; 2 ? n : fib(n-1) + fib(n-2)
end

Metriks.timer('fib.time').time do
  puts fib(10)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Sending that metric to &lt;a href="https://metrics.librato.com/"&gt;Librato Metrics&lt;/a&gt; could get you a pretty graph looking like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.skitch.com/20120306-kef4nbpnmsr155y7weiaa9acmb.png" alt="Librato Metrics Timer"/&gt;&lt;/p&gt;

&lt;h2&gt;Try it&lt;/h2&gt;

&lt;p&gt;To install the gem just add this to your &lt;code&gt;Gemfile&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;gem 'metriks'&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The source is available &lt;a href="https://github.com/eric/metriks/"&gt;on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Metrics supported&lt;/h2&gt;

&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Meter&lt;/strong&gt;: used to measure the rate that something is happening (number of times per second a method is called).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Timer&lt;/strong&gt;: used to measure how long it takes to perform something. Also contains a meter to track how many times it&amp;#8217;s happening.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Counter&lt;/strong&gt;: used to keep track of how many times something has happened since the process started. This is mostly used by the other metrics and isn&amp;#8217;t often used directly.&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Meter&lt;/h3&gt;

&lt;p&gt;Meters are used to keep track of a rate of an action (how many times per second it happens).&lt;/p&gt;

&lt;p&gt;To mark when an action is performed:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;Metriks.meter('calls').mark&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Timer&lt;/h3&gt;

&lt;p&gt;Timers are used to keep track of how long it takes for an action to take. It also contains a &lt;code&gt;Meter&lt;/code&gt; in it to track how often it happens.&lt;/p&gt;

&lt;p&gt;To measure how long an action takes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Metriks.timer('fib.duration').time do
  fib(10)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It&amp;#8217;s also possible to use it without making it a block:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;timer = Metriks.timer('fib.duration').time
fib(10)
timer.stop
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Counter&lt;/h3&gt;

&lt;p&gt;Counters are used to keep track of an absolute number. They can be incremented and decremented. This metric is generally used as the basis for other metrics instead of being one that would be used directly.&lt;/p&gt;

&lt;p&gt;To increment:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;Metriks.counter('calls').increment&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Reporters&lt;/h2&gt;

&lt;p&gt;Reporters take a Registry and report the metrics to a remote store.&lt;/p&gt;

&lt;p&gt;For a detailed overview of the reporter API, it&amp;#8217;s available &lt;a href="https://github.com/eric/metriks/wiki/Reporters"&gt;on the wiki&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Metriks::Reporter::Graphite&lt;/h3&gt;

&lt;p&gt;Sends metrics to &lt;a href="http://graphite.wikidot.com/"&gt;graphite&lt;/a&gt; on a set interval. It takes a &lt;code&gt;host&lt;/code&gt; and &lt;code&gt;port&lt;/code&gt; of the carbon agent as required arguments. Example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Metriks::Reporter::Graphite.new('localhost', 3309).start
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Metriks::Reporter::LibratoMetrics&lt;/h3&gt;

&lt;p&gt;Send metrics to &lt;a href="https://metrics.librato.com/"&gt;Librato Metrics&lt;/a&gt; on a specified interval. It takes the &lt;a href="https://metrics.librato.com/account"&gt;API credentials&lt;/a&gt; as two required arguments: &lt;code&gt;email&lt;/code&gt; and &lt;code&gt;token&lt;/code&gt;. Example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Metriks::Reporter::LibratoMetrics.new('user@metriks.local', '186dbe1cf215').start
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Metriks::Reporter::Logger&lt;/h3&gt;

&lt;p&gt;Sends metrics to a logger on a specified interval. Example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;logger = Logger.new('log/metrics.log')
Metriks::Reporter::Logger.new(:logger =&amp;gt; logger).start
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The main reason behind this reporter was that I wanted to be able to aggregate the metrics collected by multiple processes on the same system before they were sent to &lt;a href="https://metrics.librato.com/"&gt;Librato Metrics&lt;/a&gt; similarly to how &lt;a href="https://github.com/etsy/statsd/"&gt;StatsD&lt;/a&gt; does. To facilitate that, I created a &lt;a href="https://papertrailapp.com/"&gt;Papertrail&lt;/a&gt; webhook receiver that took the logs, parsed the metrics, and submitted them to &lt;a href="https://metrics.librato.com/"&gt;Librato Metrics&lt;/a&gt;. The work resulted in a Sinatra app I&amp;#8217;ve posted on GitHub at &lt;a href="https://github.com/eric/metriks_log_webhook"&gt;metriks_log_webhook&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Metriks::Reporter::ProcTitle&lt;/h3&gt;

&lt;p&gt;Being inspired by &lt;a href="https://github.com/github/rack-statsd"&gt;rack-statsd&lt;/a&gt; I realized there are many metrics that are deep in my processes that would be very interesting to keep track of how my workers are running.&lt;/p&gt;

&lt;p&gt;This reporter isn&amp;#8217;t really like the others. It reports metrics by updating your proctitle so you can see select metrics when you run &lt;code&gt;ps aux&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Because space in the process title is limited, it requires configuration to specify what metrics are reported.&lt;/p&gt;

&lt;p&gt;Example usage:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;reporter = Metriks::Reporter::ProcTitle.new
reporter.add 'reqs', 'sec' do
  Metriks.meter('rack.requests').one_minute_rate
end
reporter.start
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It would allow you to see the metric when you run &lt;code&gt;ps ax&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="no-highlight"&gt;22665 ?        S     17:09 thin reqs: 273.3/sec&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Implementation Details&lt;/h2&gt;

&lt;p&gt;Metriks is thread-safe. It uses a combination of mutexes and the &lt;a href="https://github.com/headius/ruby-atomic"&gt;atomic&lt;/a&gt; gem. Using atomic reduces the need for mutexes without sacrificing thread safety.&lt;/p&gt;

&lt;p&gt;It uses the &lt;a href="https://github.com/copiousfreetime/hitimes"&gt;hitimes&lt;/a&gt; gem to get high granularity timing data without having to call &lt;code&gt;Time.now.to_f&lt;/code&gt; frequently.&lt;/p&gt;

&lt;p&gt;Metriks doesn&amp;#8217;t tie the gathering of metrics to how they are reported. This allows for swapping out where metrics are reported to without having to change any of the instrumentation.&lt;/p&gt;

&lt;p&gt;The metrics classes themselves are mostly ports of the metrics from Coda Hale&amp;#8217;s Java &lt;a href="https://github.com/codahale/metrics/tree/master/metrics-core/src/main/java/com/yammer/metrics"&gt;metrics library&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Thanks&lt;/h2&gt;

&lt;p&gt;Thanks to Troy Davis, Joe Ruscio and Mathias Meyer for their help reviewing drafts of this post.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bitmonkey/~4/n83PLO1glJ4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/bitmonkey/~3/n83PLO1glJ4/18854033582</link><guid isPermaLink="false">http://bitmonkey.net/post/18854033582</guid><pubDate>Tue, 06 Mar 2012 10:22:00 -0800</pubDate><feedburner:origLink>http://bitmonkey.net/post/18854033582</feedburner:origLink></item><item><title>Make your library a better citizen</title><description>&lt;p&gt;I&amp;#8217;ve recently ran into a case where I wanted the Rails logger to be at &lt;code&gt;:debug&lt;/code&gt; level, but really didn&amp;#8217;t care about the debug output from the &lt;a href="http://hoptoadapp.com/"&gt;Hoptoad&lt;/a&gt; plugin. It kept giving a big XML dump every time it reported an exception which just added noise to the log file that wasn&amp;#8217;t relevant.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve found many plugins including Dash (may it rest in peace) and &lt;a href="http://hoptoadapp.com/"&gt;Hoptoad&lt;/a&gt; who would steal the logger from Rails and reference that internally.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s the logger in &lt;a href="http://github.com/thoughtbot/hoptoad_notifier/blob/0e68e717b02e504ee5f2424998f56dd087c2de9a/lib/hoptoad_notifier.rb#L60-66"&gt;hoptoad&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Look for the Rails logger currently defined
def logger
  if defined?(Rails.logger)
    Rails.logger
  elsif defined?(RAILS_DEFAULT_LOGGER)
    RAILS_DEFAULT_LOGGER
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Many times it&amp;#8217;s useful to run your staging environment (or even production) with debug logging enabled, but the downside was that now all of these plugins would be logging at that level as well.&lt;/p&gt;

&lt;p&gt;One little change that plugin authors can start to do to help the rest of us out is make sure you &lt;code&gt;#dup&lt;/code&gt; the logger before you grab a copy.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def logger
  @logger ||= if defined?(Rails.logger)
    Rails.logger.dup
  elsif defined?(RAILS_DEFAULT_LOGGER)
    RAILS_DEFAULT_LOGGER.dup
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This would allow us to then say:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Hoptoad.logger.level = Logger::WARN
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and escape all of the noise from plugins that we don&amp;#8217;t care about.&lt;/p&gt;

&lt;p&gt;Much thanks to &lt;a href="http://twitter.com/wbruce"&gt;Bruce Williams&lt;/a&gt; for first proposing this trick.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bitmonkey/~4/ZDtK5-0Aetg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/bitmonkey/~3/ZDtK5-0Aetg/477722215</link><guid isPermaLink="false">http://bitmonkey.net/post/477722215</guid><pubDate>Sat, 27 Mar 2010 14:52:36 -0700</pubDate><feedburner:origLink>http://bitmonkey.net/post/477722215</feedburner:origLink></item><item><title>PSA: Doing less is more with system and exec</title><description>&lt;p&gt;I&amp;#8217;ve come across a lot of cases where people take an array of arguments and turn it into a string before passing them to &lt;code&gt;system&lt;/code&gt; or &lt;code&gt;exec&lt;/code&gt;. I want to spread the news that it isn&amp;#8217;t needed and that we can save ourselves from bugs in the future with a little &lt;em&gt;less&lt;/em&gt; code.&lt;/p&gt;

&lt;p&gt;I don&amp;#8217;t mean to pick on &lt;a href="http://twitter.com/defunkt"&gt;defunkt&lt;/a&gt; specifically — it&amp;#8217;s a pattern I see all the time, but this example is one I had available:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def self.perform(*args)
  script = args.join(' ')
  puts "$ #{script}"
  Open3.popen3(args.join(' ')) do |stdin, stdout, stderr|
    puts stdout.read.inspect
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can see the code on GitHub &lt;a href="https://gist.github.com/225360/4820eef38ceb979dee2672577a15f6d4ea09e358"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What is &lt;code&gt;Open3.popen3&lt;/code&gt; really doing? It calls a bunch of stuff, like &lt;code&gt;IO::pipe&lt;/code&gt;, but in the end, it &lt;a href="http://github.com/FooBarWidget/rubyenterpriseedition187/blob/d0546e75c86da27b8f184820166ea0854608349b/lib/open3.rb#L67"&gt;calls &lt;code&gt;exec&lt;/code&gt;&lt;/a&gt; with the same arguments that were passed to it:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;exec(*cmd)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can see the whole source for &lt;code&gt;popen3&lt;/code&gt; &lt;a href="http://github.com/FooBarWidget/rubyenterpriseedition187/blob/d0546e75c86da27b8f184820166ea0854608349b/lib/open3.rb"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What happens if we pass a multi-word argument to &lt;code&gt;perform&lt;/code&gt;?&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;ShellJob.perform('rm', '/Library/Keyboard Layouts/Qwerty.bundle')
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The arguments are joined and turn into:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;"rm /Library/Keyboard Layouts/Qwerty.bundle"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When this is passed to the ruby &lt;code&gt;exec&lt;/code&gt; method, the results are parsed with the ruby shell argument parser and it ends up with a child process holding an &lt;code&gt;ARGV&lt;/code&gt; of:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;["rm", "/Library/Keyboard", "Layouts/Qwerty.bundle"]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#8230;but this isn&amp;#8217;t what we wanted!&lt;/p&gt;

&lt;p&gt;To understand the basics of what is going on, we have to understand the underlying call that the ruby interpreter calls: &lt;code&gt;execv(3)&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;int
execv(const char *path, char *const argv[]);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;argv[]&lt;/code&gt; array that is passed into &lt;code&gt;execv(3)&lt;/code&gt; is copied into the child process as &lt;code&gt;ARGV&lt;/code&gt;. Handy isn&amp;#8217;t it?&lt;/p&gt;

&lt;p&gt;The problem is, there is no version of the C function that takes a single &lt;code&gt;char *&lt;/code&gt; of all of the arguments and Does The Right Thing. Because of this, the ruby interpreter has to fake it, using an approximation of how the shell parses arguments.&lt;/p&gt;

&lt;p&gt;But there &lt;strong&gt;is&lt;/strong&gt; a better way.&lt;/p&gt;

&lt;p&gt;From the documentation for &lt;a href="http://ruby-doc.org/core/classes/Kernel.html#M005968"&gt;Kernel#exec&lt;/a&gt; &lt;em&gt;(emphasis mine)&lt;/em&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Replaces the current process by running the given external command. If exec is given a single argument, that argument is taken as a line that is subject to shell expansion before being executed. &lt;strong&gt;If multiple arguments are given, the second and subsequent arguments are passed as parameters to command with no shell expansion.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What&amp;#8217;s great is, in this case (and in a lot of them), we actually already have an array with all of the arguments in it.&lt;/p&gt;

&lt;p&gt;So, we can actually just change the &lt;code&gt;popen3&lt;/code&gt; line to say:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Open3.popen3(*args) do |stdin, stdout, stderr|
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and everything will work the way we want.&lt;/p&gt;

&lt;p&gt;You can see the full code on GitHub &lt;a href="http://gist.github.com/226703"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bitmonkey/~4/cSyQ-OdyeVI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/bitmonkey/~3/cSyQ-OdyeVI/344842339</link><guid isPermaLink="false">http://bitmonkey.net/post/344842339</guid><pubDate>Wed, 20 Jan 2010 14:01:49 -0800</pubDate><feedburner:origLink>http://bitmonkey.net/post/344842339</feedburner:origLink></item><item><title>Making it easy to run a single test</title><description>&lt;p&gt;In the course of normal development I find myself focusing on specific tests that I want to make sure work properly before moving on to testing the entire test suite.&lt;/p&gt;

&lt;p&gt;There is a really great argument to &lt;code&gt;test/unit&lt;/code&gt; called &lt;code&gt;--name&lt;/code&gt; which will allow you to specify the test to run.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;test/unit&lt;/code&gt; &lt;code&gt;rake&lt;/code&gt; tasks provide the &lt;code&gt;TESTOPTS&lt;/code&gt; environment variable as a means to pass options to the tests runner. To run a specific test we can add our &lt;code&gt;--name&lt;/code&gt; option to &lt;code&gt;TESTOPTS&lt;/code&gt; like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rake test:units TEST=test/unit/user_test.rb TESTOPTS="--name=test_should_create_user"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;--name&lt;/code&gt; option even takes a regular expression, so we can even do this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rake test:units TEST=test/unit/user_test.rb TESTOPTS="--name='/create_user/'"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Because it&amp;#8217;s a pain in the ass to remember the option as well as doing the right amount of escaping and quoting, I created a simple rake task that you can have run before your real test tasks to set &lt;code&gt;TESTOPTS&lt;/code&gt; for you. It looks in the &lt;code&gt;TESTNAME&lt;/code&gt; environment variable and if it exists, sets &lt;code&gt;TESTOPTS&lt;/code&gt; with the correct value.&lt;/p&gt;

&lt;p&gt;To pull this off, you can just put the following in &lt;code&gt;lib/tasks/test_name.rake&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namespace :test do
  task :populate_testopts do
    if ENV['TESTNAME'].present?
      ENV['TESTOPTS']  = ENV['TESTOPTS'] ? "#{ENV['TESTOPTS']} " : ''
      ENV['TESTOPTS'] += "--name=#{ENV['TESTNAME'].inspect}"
    end    
  end
end

%w(test:units test:functionals test:integration).each do |task_name|
  Rake::Task[task_name].prerequisites &amp;lt;&amp;lt; 'test:populate_testopts'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can find the gist &lt;a href="http://gist.github.com/276854"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The only thing tricky about this code is that we go and stick an entry in the &lt;code&gt;prerequisites&lt;/code&gt; array that each &lt;code&gt;Rake::Task&lt;/code&gt; has to make sure that it runs our environment filter code before it runs the task itself.&lt;/p&gt;

&lt;p&gt;Once we&amp;#8217;ve done that, we can run the tests we want with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rake test:units TEST=test/unit/user_test.rb TESTNAME='/create_user/'
&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/bitmonkey/~4/zcHCpITsLY8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/bitmonkey/~3/zcHCpITsLY8/336453151</link><guid isPermaLink="false">http://bitmonkey.net/post/336453151</guid><pubDate>Fri, 15 Jan 2010 15:48:10 -0800</pubDate><feedburner:origLink>http://bitmonkey.net/post/336453151</feedburner:origLink></item><item><title>Quick tip for up-to-date Scout graphs</title><description>&lt;p&gt;One of the things that&amp;#8217;s always made me sad when using &lt;a href="http://scoutapp.com/"&gt;Scout&lt;/a&gt; has been having to refresh the page to reload the graphs.&lt;/p&gt;

&lt;p&gt;Fortunately &lt;a href="http://amcharts.com/"&gt;amcharts&lt;/a&gt;, the charting engine used by Scout, has the ability to do refreshing.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s a nice little bookmarklet to make the Scout graphs refresh every 60 seconds.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Drag this link:&lt;/em&gt; &lt;strong&gt;&lt;a href="javascript:(function()%7B%24('#amstock').get(0).setSettings('&amp;lt;settings&amp;gt;&amp;lt;data_reloading&amp;gt;&amp;lt;interval&amp;gt;60&amp;lt;/interval&amp;gt;&amp;lt;show_preloader&amp;gt;false&amp;lt;/show_preloader&amp;gt;&amp;lt;reset_period&amp;gt;true&amp;lt;/reset_period&amp;gt;&amp;lt;/data_reloading&amp;gt;&amp;lt;/settings&amp;gt;');%7D)()"&gt;Scout Reload&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To install the bookmarklet, drag the &amp;#8220;Scout Reload&amp;#8221; link to your bookmark bar.&lt;/p&gt;

&lt;p&gt;To use it, click on the bookmarklet when you are on a Scout graph page.&lt;/p&gt;

&lt;p&gt;For more hints on how to install bookmarklets, you can see how to install the Delicious bookmarklet &lt;a href="http://delicious.com/help/bookmarklets"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;What is it doing?&lt;/h3&gt;

&lt;p&gt;Amcharts provides all sorts of &lt;a href="http://www.amcharts.com/docs/v.1/stock/settings/settings_reference"&gt;great functionality&lt;/a&gt;, including a simple refresh mechanism.&lt;/p&gt;

&lt;p&gt;What we do is update the XML configuration via javascript with this chunk:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;settings&amp;gt;
  &amp;lt;data_reloading&amp;gt;
    &amp;lt;interval&amp;gt;60&amp;lt;/interval&amp;gt;
    &amp;lt;show_preloader&amp;gt;false&amp;lt;/show_preloader&amp;gt;
    &amp;lt;reset_period&amp;gt;true&amp;lt;/reset_period&amp;gt;
  &amp;lt;/data_reloading&amp;gt;
&amp;lt;/settings&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To send that chunk of XML to the chart is very strait forward. We just get a reference to the DOM object that is the chart and call &lt;code&gt;setSettings&lt;/code&gt; on it, passing it the XML we want:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;$("#amstock").get(0).setSettings(xml_settings_string);
&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/bitmonkey/~4/PFg7Wl8dwTs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/bitmonkey/~3/PFg7Wl8dwTs/322345897</link><guid isPermaLink="false">http://bitmonkey.net/post/322345897</guid><pubDate>Thu, 07 Jan 2010 16:34:00 -0800</pubDate><feedburner:origLink>http://bitmonkey.net/post/322345897</feedburner:origLink></item><item><title>Abusing HTTParty for a Tender client</title><description>&lt;p&gt;We all know how great &lt;a href="http://tenderapp.com/"&gt;Tender&lt;/a&gt; is and had a chance to play with their great &lt;a href="https://help.tenderapp.com/faqs/api/introduction"&gt;API&lt;/a&gt; while writing a &lt;a href="http://github.com/eric/tender_summary/"&gt;tool to send out an email every morning&lt;/a&gt; with any pending issues.&lt;/p&gt;

&lt;p&gt;They&amp;#8217;ve done some really great stuff with it, especially with their use of &lt;a href="http://bitworking.org/projects/URI-Templates/"&gt;URI Templates&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you haven&amp;#8217;t played with URI Templates before, an example of their JSON with a template in it looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{"site_href": "http://api.tenderapp.com/{site_permalink}"}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;which, with the &lt;a href="http://github.com/sporkmonger/addressable"&gt;Addressable&lt;/a&gt; gem would allow us to say:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; require 'addressable/template'
&amp;gt;&amp;gt; tmpl = Addressable::Template.new('http://api.tenderapp.com/{site_permalink}')
&amp;gt;&amp;gt; tmpl.expand('site_permalink' =&amp;gt; 'help').to_s
=&amp;gt; &lt;a href="http://api.tenderapp.com/help"&gt;http://api.tenderapp.com/help&lt;/a&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To make things nice and strait forward, Tender follows the convention of using &lt;code&gt;_href&lt;/code&gt; as the suffix for any key that contains a template. I was able to use this along with a little magic I snuck into Hash to make my code that much prettier.&lt;/p&gt;

&lt;p&gt;All that was required to expand the templates was a little module:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module JsonHelpers
  def href(key, opts = {})
    Addressable::Template.new(self["#{key}_href"]).expand(opts).to_s
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;which I was able to mix in to any &lt;code&gt;Hash&lt;/code&gt; that was returned:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Make the JSON a litte bit more fun to work with
def self.add_json_helpers(data)
  case data
  when Hash
    data.send(:extend, TenderSummary::JsonHelpers)
    data.each { |_, value| add_json_helpers(value) }
  when Array
    data.each { |elem| add_json_helpers(elem) }
  end
  data
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and then tell &lt;code&gt;HTTParty&lt;/code&gt; to use it by specifying a custom &lt;code&gt;parser&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module TenderSummary
  class TenderApi
    include HTTParty

    headers  'Accept' =&amp;gt; 'application/vnd.tender-v1+json'
    format   :json
    parser   Proc.new { |b| add_json_helpers(Crack::JSON.parse(b)) }

    # ...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With all this done, it made it very simple to generate the URLs to the resources I wanted access to.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# assuming `site` holds the JSON returned from
# 'http://api.tenderapp.com/{site_permalink}'
discussion_url = site.href(:discussions, :state =&amp;gt; :pending)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can see the entire class of &lt;a href="http://github.com/eric/tender_summary/blob/master/lib/tender_summary/tender_api.rb"&gt;&lt;code&gt;TenderApi&lt;/code&gt;&lt;/a&gt; on GitHub.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bitmonkey/~4/oht2O9k_11w" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/bitmonkey/~3/oht2O9k_11w/321024158</link><guid isPermaLink="false">http://bitmonkey.net/post/321024158</guid><pubDate>Wed, 06 Jan 2010 21:22:05 -0800</pubDate><feedburner:origLink>http://bitmonkey.net/post/321024158</feedburner:origLink></item><item><title>Tracking initial memory usage by file in Ruby</title><description>&lt;p&gt;I&amp;#8217;ve found that as a project progresses, the initial memory usage of a Rails application seems to grow more and more.&lt;/p&gt;

&lt;p&gt;The more time I spend trying to track down memory leaks (or just pieces of code that use more memory than they should) the more I realize that it&amp;#8217;s a fairly imprecise science. I&amp;#8217;ve had the best luck using tools to give me a good idea of where to start poking around. From there it&amp;#8217;s just a matter of looking at the code and finding what silly things people are doing.&lt;/p&gt;

&lt;p&gt;If I wanted to see what was contributing to the large memory footprint of an application on startup, tracking how much memory was allocated during each &lt;code&gt;require&lt;/code&gt; would give me a good place to start.&lt;/p&gt;

&lt;p&gt;The code to do this is amazingly strait forward:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module RequireTracking
  def require(*args)
    start_size = GC.allocated_size
    super
  ensure
    $require_stats[args.first] += (GC.allocated_size - start_size)
  end
end

Object.send(:include, RequireTracking)
Kernel.send(:include, RequireTracking)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;The entire implementation is available &lt;a href="http://gist.github.com/264496"&gt;as a gist&lt;/a&gt; on GitHub.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;GC.allocated_size&lt;/code&gt; method is included in the &lt;a href="http://railsbench.rubyforge.org/svn/trunk/railsbench/GCPATCH"&gt;RailsBench GC patch&lt;/a&gt; which is part of the &lt;a href="http://www.rubyenterpriseedition.com/"&gt;Ruby Enterprise Edition&lt;/a&gt; interpreter.&lt;/p&gt;

&lt;p&gt;One thing to understand is this is only tracking how much memory was allocated but not how much was freed. This will cause these statistics to include memory that was temporarily allocated and then no longer referenced. This can be useful because even temporarily using lots of memory can negatively impact startup time.&lt;/p&gt;

&lt;p&gt;Another aspect to understand is the numbers we are tracking are what are normally called &amp;#8220;self + children&amp;#8221; in profilers. This means that all memory allocated by a file as well as anything allocated by files that are required from it are included in the statistics. This results in the same memory being counted multiple times, but is useful in understanding the total memory implications of requiring a file.&lt;/p&gt;

&lt;p&gt;Running this on one of the projects I was working on found this little gem:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Webster
  DICTIONARY = File.open(File.join(File.dirname(__FILE__), 'words')) do |file|
    file.readlines.collect {|each| each.chomp}
  end

  def random_word
    DICTIONARY[rand(DICTIONARY.size)]
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;You can find the source on GitHub &lt;a href="http://github.com/dancroak/webster/blob/09087e5d10ee950513018794f81f36ccd875eba9/lib/webster.rb"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This would be a prime candidate for refactoring if you are worried about your memory usage.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bitmonkey/~4/lVf5ASTJBsM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/bitmonkey/~3/lVf5ASTJBsM/308322913</link><guid isPermaLink="false">http://bitmonkey.net/post/308322913</guid><pubDate>Wed, 30 Dec 2009 11:21:00 -0800</pubDate><feedburner:origLink>http://bitmonkey.net/post/308322913</feedburner:origLink></item><item><title>Add NewRelic instrumentation for ThinkingSphinx</title><description>&lt;p&gt;&lt;a href="http://newrelic.com/"&gt;NewRelic&lt;/a&gt; provides a really great mechanism in their plugin to instrument just about anything.&lt;/p&gt;

&lt;p&gt;One of the things I found when analyzing actions in NewRelic was that all of the time that was being spent in the ThinkingSphinx methods were being attributed to the template instead of the model. As we all know, mis-attribution of time spent can make tracking down trouble spots in your code much more difficult.&lt;/p&gt;

&lt;p&gt;It ends up that all that is required to start tracking the time you are searching in ThinkingSphinx is a couple calls to &lt;code&gt;add_method_tracer&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  add_method_tracer :search, 'ActiveRecord/#{self.name}/search'
  add_method_tracer :search, 'ActiveRecord/search', :push_scope =&amp;gt; false
  add_method_tracer :search, 'ActiveRecord/all', :push_scope =&amp;gt; false
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;You can see the full code &lt;a href="http://gist.github.com/219071"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Once you&amp;#8217;ve required the code, you&amp;#8217;ll start to see the &lt;code&gt;#search&lt;/code&gt; and &lt;code&gt;#search_count&lt;/code&gt; methods show up in your Performance Breakdowns:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://img.skitch.com/20091229-ctihwdbs71jtwq5jibxyp4yygs.png" alt="Performance Breakdown"/&gt;&lt;/p&gt;

&lt;p&gt;Isn&amp;#8217;t that sweet?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; NewRelic has some great documentation for &lt;a href="http://support.newrelic.com/faqs/docs/custom-metric-collection"&gt;Custom Metric Collection&lt;/a&gt; if you want to do more.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bitmonkey/~4/Nx1Y7-WSzTw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/bitmonkey/~3/Nx1Y7-WSzTw/307053799</link><guid isPermaLink="false">http://bitmonkey.net/post/307053799</guid><pubDate>Tue, 29 Dec 2009 17:11:00 -0800</pubDate><feedburner:origLink>http://bitmonkey.net/post/307053799</feedburner:origLink></item></channel></rss>

