<?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>Sean's Obsessions</title>
	<atom:link href="http://ertw.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://ertw.com/blog</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Thu, 17 May 2012 09:25:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Controlling HipChat status through AppleScript</title>
		<link>http://ertw.com/blog/2012/05/02/controlling-hipchat-status-through-applescript/</link>
		<comments>http://ertw.com/blog/2012/05/02/controlling-hipchat-status-through-applescript/#comments</comments>
		<pubDate>Wed, 02 May 2012 20:47:25 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=428</guid>
		<description><![CDATA[&#1080;&#1082;&#1086;&#1085;&#1072; &#1079;&#1072; &#1087;&#1086;&#1076;&#1072;&#1088;&#1098;&#1082;At my awesome job we use HipChat for team collaboration. I also use the Pomodoro app to try and manage my time. One problem is that I often get interrupted while working. Long story short, the Pomodoro app lets you run AppleScript when various events happen, so I wrote some stuff to change [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://xn--h1aafme.net/%E8%EA%EE%ED%E0-%E7%E0-%EF%EE%E4%E0%F0%FA%EA">&#1080;&#1082;&#1086;&#1085;&#1072; &#1079;&#1072; &#1087;&#1086;&#1076;&#1072;&#1088;&#1098;&#1082;</a></font>At my awesome <a href="http://waveaccounting.com">job</a> we use <a href="http://hipchat.com/r/2zvuo">HipChat</a> for team collaboration. I also use the <a href="http://itunes.apple.com/us/app/pomodoro/id417574133?mt=12">Pomodoro app</a> to try and manage my time. One problem is that I often get interrupted while working. </p>
<p>Long story short, the Pomodoro app lets you run AppleScript when various events happen, so I wrote some stuff to change my HipChat status to DND when I&#8217;m in the middle of a work cycle. Here&#8217;s the code:</p>
<pre><code>tell application "System Events" to tell UI element "HipChat" of list 1 of process "Dock"
	perform action "AXShowMenu"
	delay 0.5
	click menu item "Status" of menu 1
	click menu item "DND" of menu 1 of menu item "Status" of menu 1
 end tell</code></pre>
<p>All that remains is to insert that into the Pomodoro app through Preferences -> Scripts:</p>
<p><a href="http://ertw.com/blog/wp-content/uploads/2012/05/Screen-Shot-2012-05-02-at-3.45.33-PM.png"><img src="http://ertw.com/blog/wp-content/uploads/2012/05/Screen-Shot-2012-05-02-at-3.45.33-PM.png" alt="" title="Pomodoro scripts" width="661" height="573" class="alignnone size-full wp-image-430" /></a></p>
<p>Just note that you have to change &#8220;DND&#8221; to &#8220;Available&#8221; for some of the events.</p>
<p>This was my first foray into AppleScript, so it&#8217;s possible I&#8217;m sending my banking details off to Nigeria, but it seems to work so far.</p>
<p><b>Edit</b> you need to enable access for assistive devices from System Preferences -> Universal Access:</p>
<p><a href="http://ertw.com/blog/wp-content/uploads/2012/05/universal_access.jpg"><img src="http://ertw.com/blog/wp-content/uploads/2012/05/universal_access.jpg" alt="" title="universal_access" width="666" height="578" class="alignnone size-full wp-image-435" /></a></p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2012/05/02/controlling-hipchat-status-through-applescript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making New Relic Awesome</title>
		<link>http://ertw.com/blog/2012/01/21/making-new-relic-awesome/</link>
		<comments>http://ertw.com/blog/2012/01/21/making-new-relic-awesome/#comments</comments>
		<pubDate>Sat, 21 Jan 2012 17:39:41 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=411</guid>
		<description><![CDATA[&#1061;&#1091;&#1076;&#1086;&#1078;&#1085;&#1080;&#1082;&#1041;&#1086;&#1075;&#1086;&#1088;&#1086;&#1076;&#1080;&#1094;&#1072;Update &#8211; if you sign up through this link, New Relic will send you an RC helicopter for trying out New Relic. Like many Rails people, I use New Relic to monitor my Rails app. At Wave Accounting we even pay for it. It&#8217;s well worth the money, as you get a lot of extra [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://ikoni.eu/">&#1061;&#1091;&#1076;&#1086;&#1078;&#1085;&#1080;&#1082;</a></font><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://xn--h1aafme.net/%E8%EA%EE%ED%EE%EF%E8%F1">&#1041;&#1086;&#1075;&#1086;&#1088;&#1086;&#1076;&#1080;&#1094;&#1072;</a></font><b>Update</b> &#8211; if you sign up through <a href='http://newrelic.extole.com/a/clk/5RMk1n'>this link</a>, New Relic will send you an RC helicopter for trying out New Relic.</p>
<p>Like many Rails people, I use <a href="http://newrelic.extole.com/a/clk/5RMk1n">New Relic</a> to monitor my Rails app. At <a href="http://waveaccounting.com">Wave Accounting</a> we even pay for it. It&#8217;s well worth the money, as you get a lot of extra visibility into your app.</p>
<p>At the standard level, New Relic is pretty good, but sometimes it seems like I&#8217;m missing out on something. RPM will show me that a controller is running slowly but most of the time is spent in the controller itself, not really saying what&#8217;s happening. I&#8217;ve recently discovered a few tweaks that have made a huge difference.</p>
<h2>Turn on garbage collection</h2>
<p>It&#8217;s pretty embarrassing, but this isn&#8217;t on by default. It&#8217;s so simple to figure out how much of your time is spent in GC, the only caveat is that you have to be running REE or 1.9.x. <a href="http://newrelic.com/docs/ruby/ruby-gc-instrumentation">This doc</a> explains how, but all you have to do is turn on the stats and New Relic does the rest.</p>
<pre><code># For REE
GC.enable_stats
# For 1.9.2
# GC::Profiler.enable</code></pre>
<p>Put that in an initializer, and you get GC activity in almost all your graphs:</p>
<p><img src="http://ertw.com/blog/wp-content/uploads/2012/01/Screen-Shot-2012-01-21-at-11.16.33-AM.png" alt="" title="Graphing Ruby GC activity in New Relic" width="816" height="102" class="alignnone size-full wp-image-413" /></p>
<h2>Local development mode</h2>
<p>If you go to http://localhost:3000/newrelic you will get some in depth information about what&#8217;s going on in your app when in dev mode. If you&#8217;re using <a href="http://pow.cx">pow</a> then add the following to ~/.powconfig:</p>
<pre><code>export NEWRELIC_DISPATCHER=pow
export POW_WORKERS=1</code></pre>
<p>There&#8217;s a wealth of information here.</p>
<h2>Trace specific sections of your code</h2>
<p>Your controller does a bunch of stuff but New Relic reports it as one big block. <a href="http://newrelic.com/docs/docs/custom-metric-collection">block tracing to the rescue</a>!</p>
<pre><code>respond_to do |format|
  format.html do
    self.class.trace_execution_scoped(['Custom/MyController#show/render_html']) do
      do_it_in_html
    end
  end
  format.pdf do
    self.class.trace_execution_scoped(['Custom/MyController#show/render_pdf']) do
      do_it_in_pdf
    end
  end
end
</code></pre>
<p>Then, these blocks will be counted separately.</p>
<h2>Trace methods in your code, or other people&#8217;s code</h2>
<p>Want to do the same thing as before on someone else&#8217;s code, or at a method level? Add a method tracer in your initializer:</p>
<pre><code>require 'new_relic/agent/method_tracer'
CalculationEngine.class_eval do
    include NewRelic::Agent::MethodTracer
    add_method_tracer :calculate_taxes
    add_method_tracer :calculate_totals
    add_method_tracer :send_invoice
end</code></pre>
<p>Poof, all those are now traced and broken out separately:</p>
<p><img src="http://ertw.com/blog/wp-content/uploads/2012/01/Screen-Shot-2012-01-21-at-11.35.29-AM.png" alt="" title="Extra info in new relic" width="803" height="38" class="alignnone size-full wp-image-415" /></p>
<h2>Other things</h2>
<p>You can also trace custom metrics, such as user signups or report views. I&#8217;m still working on that, along with monitoring background jobs.</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2012/01/21/making-new-relic-awesome/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Twilio Client Quickstart &#8211; In Ruby</title>
		<link>http://ertw.com/blog/2011/10/25/twilio-client-quickstart-in-ruby/</link>
		<comments>http://ertw.com/blog/2011/10/25/twilio-client-quickstart-in-ruby/#comments</comments>
		<pubDate>Wed, 26 Oct 2011 03:38:47 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Telephony]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=377</guid>
		<description><![CDATA[&#1080;&#1082;&#1086;&#1085;&#1080; &#1094;&#1077;&#1085;&#1080; I&#8217;ve wanted to play with the Twilio client for a while. They have this great quick start but it&#8217;s written in PHP. Now I don&#8217;t mind PHP, but I prefer Ruby. If I&#8217;m going to write anything using the client, it&#8217;s going to be in Ruby, so I don&#8217;t see the point in [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://xn--h1aafme.net/">&#1080;&#1082;&#1086;&#1085;&#1080; &#1094;&#1077;&#1085;&#1080;</a></font>
<p>I&#8217;ve wanted to play with the Twilio client for a while. They have this great <a href="http://www.twilio.com/docs/quickstart/client/">quick start</a> but it&#8217;s written in PHP. Now I don&#8217;t mind PHP, but I prefer Ruby. If I&#8217;m going to write anything <i>using</i> the client, it&#8217;s going to be in Ruby, so I don&#8217;t see the point in learning it on PHP.</p>
<p>So, here is the meat of the quickstart done up as a Rails 3.1 application.</p>
<p>First, generate the application.</p>
<pre><code>$ rails new twilio
      create
      create  README
      create  Rakefile
      create  config.ru
      create  .gitignore
      create  Gemfile
      create  app
      ...
</code></pre>
<p>This creates a new Rails 3.1 app in the current directory called <b>twilio</b>. Change to this directory, and add a line to your <b>Gemfile</b>:</p>
<pre><code>gem 'twilio-ruby'</code></pre>
<p>Run <b>bundle install</b> to add the official Twilio gem to your bundle.</p>
<p>Next, head on over to your Twilio account and get your SID and auth token. Those can go in an initializer, <b>config/initializers/twilio.rb</b>:</p>
<pre><code>TwilioAccountSID="AC........"
TwilioAuthToken="......."</code></pre>
<p>Those are the magic tokens that let you authenticate yourself to the Twilio API, and more importantly for them, let them bill you.</p>
<p>Next, head on over to <b>app/helpers/application_helper.rb</b>:</p>
<pre><code>module ApplicationHelper
  def twilio_javascript_include_tag
    javascript_include_tag "http://static.twilio.com/libs/twiliojs/1.0/twilio.min.js"
  end
end
</code></pre>
<p>Then in <b>app/views/layouts/application.html.erb</b> add that helper in the head:</p>
<pre><code>
  <%= stylesheet_link_tag    "application" %>
  <%= javascript_include_tag "application" %>
 <b> <%= twilio_javascript_include_tag  %></b>
  <%= csrf_meta_tags %>
</code></pre>
<p>Yea, you could have put the code right in the layout, but I like sparse layout files.</p>
<p>Next up, create a controller:</p>
<pre><code>$ rails generate controller client index
      create  app/controllers/client_controller.rb
       route  get "client/index"
      invoke  erb
      create    app/views/client
      create    app/views/client/index.html.erb
      invoke  test_unit
      create    test/functional/client_controller_test.rb
      invoke  helper
      create    app/helpers/client_helper.rb
      invoke    test_unit
      create      test/unit/helpers/client_helper_test.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/client.js.coffee
      invoke    scss
      create      app/assets/stylesheets/client.css.scss
</code></pre>
<p>Then add <b>root :to => &#8216;client#index&#8217;</b> to <b>config/routes.rb</b> so that your new view is displayed in the root url.</p>
<p>Run <b>rails server</b> or whatever you do to start your dev instance and browse to it. You should get the usual &#8220;find me in app/views/client/index.html.erb&#8221; message. Check the headers to make sure the library is being installed. The rest of the examples then deal with <b>app/views/client/index.html.erb</b> and <b>app/helpers/client_helper.rb</b>.</p>
<p>For the <a href="http://www.twilio.com/docs/quickstart/client/hello-monkey">first example</a> you want:</p>
<p><b>Helper:</b></p>
<pre><code>module ClientHelper

  def twilio_token
    capability = Twilio::Util::Capability.new TwilioAccountSID, TwilioAuthToken
    capability.allow_client_outgoing "APabe7650f654fc34655fc81ae71caa3ff"
    capability.generate
  end
end</code></pre>
<p><b>View:</b></p>
<pre><code>
<%= javascript_tag do %>
function call() {
  Twilio.Device.connect();
}

function hangup() {
  Twilio.Device.disconnectAll();
}

$(function() {
  Twilio.Device.setup("<%= twilio_token %>");

  Twilio.Device.ready(function (device) {
    $("#log").text("Ready");
  });

  Twilio.Device.error(function (error) {
    $("#log").text("Error: " + error.message);
  });

  Twilio.Device.connect(function (conn) {
    $("#log").text("Successfully established call");
  });
});
<% end %>
&lt;button class="call" onclick="call();">
  Call
&lt;/button>
</code></pre>
<p>For the <a href="http://www.twilio.com/docs/quickstart/client/hangup">second example</a>, you just change the view.</p>
<pre><code>
<%= javascript_tag do %>
function call() {
  Twilio.Device.connect();
}

function hangup() {
  Twilio.Device.disconnectAll();
}

$(function() {
  Twilio.Device.setup("<%= twilio_token %>");

  Twilio.Device.ready(function (device) {
    $("#log").text("Ready");
  });

  Twilio.Device.error(function (error) {
    $("#log").text("Error: " + error.message);
  });

  Twilio.Device.disconnect(function (conn) {
    $("#log").text("Call ended");
  });

  Twilio.Device.connect(function (conn) {
    $("#log").text("Successfully established call");
  });
});
<% end %>
&lt;button class="call" onclick="call();">
  Call
&lt;/button>

&lt;button class="hangup" onclick="hangup();">
  Hangup
&lt;/button>

&lt;div id="log">Loading pigeons...&lt;/div>
</code></pre>
<p>For the <a href="http://www.twilio.com/docs/quickstart/client/incoming-calls">third example</a> we&#8217;ll have to change the helper and the view accordingly:</p>
<p><b>app/helpers/client_helper.rb</b> (note I&#8217;m using my own sandbox id. You get your own inside the Twilio account page!)</p>
<pre><code>
module ClientHelper
  def twilio_token
    capability = Twilio::Util::Capability.new TwilioAccountSID, TwilioAuthToken
    capability.allow_client_outgoing "AP..."
    capability.allow_client_incoming 'jenny'
    capability.generate
  end
end
</code></pre>
<p>app/views/client/index.html.erb</p>
<pre><code>
%= javascript_tag do %>
function call() {
  Twilio.Device.connect();
}

function hangup() {
  Twilio.Device.disconnectAll();
}

$(function() {
  Twilio.Device.setup("<%= twilio_token %>");

  Twilio.Device.ready(function (device) {
    $("#log").text("Ready");
  });

  Twilio.Device.error(function (error) {
    $("#log").text("Error: " + error.message);
  });

  Twilio.Device.disconnect(function (conn) {
    $("#log").text("Call ended");
  });

  Twilio.Device.connect(function (conn) {
    $("#log").text("Successfully established call");
  });

  Twilio.Device.incoming(function (conn) {
    $("#log").text("Incoming connection from " + conn.parameters.From);
    // accept the incoming connection and start two-way audio
    conn.accept();
  });

});
<% end %>
&lt;button class="call" onclick="call();">
  Call
&lt;/button>

&lt;button class="hangup" onclick="hangup();">
  Hangup
&lt;/button>

&lt;div id="log">Loading pigeons...&lt;/div>
</code></pre>
<p>Now, hook up a new action in the client controller to redirect the call from Twilio to the app inside <b>app/controllers/client_controller.rb</b></p>
<pre><code>
def incoming
  response = Twilio::TwiML::Response.new do |r|
    r.Dial  do |d|
      d.Client 'jenny'
    end
  end

  render :text => response.text
end
</code></pre>
<p>Don&#8217;t forget to add <b>post &#8220;client/incoming&#8221;</b> to <b>config/routes.rb</b>. Then point your sandbox URL to your dev box, such as http://yourhome.com:3000/client/incoming.xml.</p>
<p>As a bonus, here&#8217;s a rake task to log in to a remote host and set up an ssh tunnel on remote port 3000 to local port 3000:</p>
<pre><code>
namespace :tunnel do
  desc "Start a ssh tunnel"
  task :start => :environment do

    public_host_username = "sean"
    public_host = "home.ertw.com"
    public_port = 3000

    local_port = 3000

    puts "Starting tunnel #{public_host}:#{public_port} \
          to 127.0.0.1:#{local_port}"

    exec "ssh -nNT -g -R *:#{public_port}:127.0.0.1:#{local_port} \
                           #{public_host_username}@#{public_host}"
  end
end</code></pre>
<p>There are two more examples in the quickstart, but as they are more of the same, I&#8217;ll leave them for another post. I&#8217;d also like to try rewriting the Javascript in Coffeescript.</p>
<p>Update &#8211; Code is at https://github.com/swalberg/twilio-client-ruby</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2011/10/25/twilio-client-quickstart-in-ruby/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Practical Packet Analysis, 2ed</title>
		<link>http://ertw.com/blog/2011/10/10/practical-packet-analysis-2ed/</link>
		<comments>http://ertw.com/blog/2011/10/10/practical-packet-analysis-2ed/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 21:21:02 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Books]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=366</guid>
		<description><![CDATA[No Starch Press sent me Practical Packet Analysis, 2ed a little while back. At about 250 pages it&#8217;s a lot smaller than Chappell&#8217;s &#8220;Wireshark Network Analysis&#8221;, and more appropriate for someone who wants to get up and running quickly rather than going for a certification. The book assumes no knowledge of Wireshark, and a basic [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p><img src="http://nostarch.com/sites/default/files/imagecache/product_main_page/packet2.png" alt="" /></p>
<p>No Starch Press sent me <a href="http://nostarch.com/packet2.htm">Practical Packet Analysis, 2ed</a> a little while back. At about 250 pages it&#8217;s a lot smaller than Chappell&#8217;s &#8220;Wireshark Network Analysis&#8221;, and more appropriate for someone who wants to get up and running quickly rather than going for a certification.</p>
<p>The book assumes no knowledge of Wireshark, and a basic understanding of networking. More than half the book is devoted to teaching the Wireshark interface and how the popular protocols work. So, if you don&#8217;t know anything about DNS recursion, you&#8217;ll get a taste of it here along with what it looks like in Wireshark. The first half covers everything from filtering inside Wireshark to how different protocols work.</p>
<p>The second half of the book follows fairly typical examples, such as decoding HTTP streams and troubleshooting the causes of network congestion. Of special interest is Chapter 10, which is about using wireshark for security analysis. This chapter is merely an introduction to a huge topic, but the author has chosen some interesting examples such as an ARP poisoning attack and analysis of a trojan horse.</p>
<p>One theme the author continually comes back to is appropriate placement of the analysis tool. The early chapters discuss the matter in theory, and every example in the second half has some text that analyzes the options for where to use Wireshark and where the best spot is.</p>
<p>Some of the highlights of the book:</p>
<ul>
<li>A great discussion of TCP congestion and analysis of a congestion scenario</li>
<li>A good tradeoff between depth and breadth. This is a &#8220;getting started&#8221; guide/</li>
<li>Uses many of the features of Wireshark in a practical context</li>
<li>A good, though basic, chapter about wireless sniffing</li>
</ul>
<p>Some of the downsides:</p>
<ul>
<li>No IPv6 (other than a brief mention of a host filter)</li>
<li>Would have liked to see more use about IO graphs and TCP stream graphs especially when talking about congestion.</li>
</ul>
<p>On the whole, a great book for the IT administrator who wants to quickly get started using Wireshark. Cover price is $49.95 US, Amazon.com is showing it for $30 which is a bargain.</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2011/10/10/practical-packet-analysis-2ed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nagios paging using Twilio</title>
		<link>http://ertw.com/blog/2011/09/07/nagios-paging-using-twilio/</link>
		<comments>http://ertw.com/blog/2011/09/07/nagios-paging-using-twilio/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 19:48:45 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Linux/Unix/OpenSource]]></category>
		<category><![CDATA[Telephony]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=355</guid>
		<description><![CDATA[&#1080;&#1082;&#1086;&#1085;&#1086;&#1087;&#1080;&#1089;I use Nagios to monitor the health of a few servers, and would like to be paged if something goes wrong. When I set it up a couple of years ago, I used SMS Gateway which was $10 for 100 SMSes. I was able to page with a simple curl command. However I&#8217;d get the [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://ikoni.eu/">&#1080;&#1082;&#1086;&#1085;&#1086;&#1087;&#1080;&#1089;</a></font>I use Nagios to monitor the health of a few servers, and would like to be paged if something goes wrong.</p>
<p>When I set it up a couple of years ago, I used <a href="http://smsgateway.ca/">SMS Gateway</a> which was $10 for 100 SMSes. I was able to page with a simple curl command. However I&#8217;d get the odd page that wouldn&#8217;t go through, and despite being very responsive, the support wasn&#8217;t very reassuring.</p>
<p>Now that I&#8217;ve depleted my 100 pages, I figured I&#8217;d move over to <a href="http://twilio.com">Twilio</a> because they&#8217;re pretty slick, and the reliability has to be better.</p>
<p>Some Nagios code, first:</p>
<pre><code>
define contactgroup{
        contactgroup_name       important
        alias                   Sean Buzz
        members                 sean, page
}
define contact{
        contact_name                    page
        alias                           page
        service_notification_commands   notify-by-page
        host_notification_commands      host-notify-by-page
        service_notification_period 24x7
        host_notification_period 24x7
        service_notification_options w,u,c,r
        host_notification_options d,u,r
        pager                           nobody@localhost
}
define service{
        use                             local-service         ; Name of service template to use
        host_name                       localhost
        service_description             smallpayroll.ca
        contact_groups                  important
        check_command                   check_http_string!smallpayroll.ca!Easy to use
        }
</code></pre>
<p>The first stanza creates a contact group called &#8220;important&#8221; that emails sean, and pages. The second stanza implements the &#8220;host-notify-by-page&#8221; and &#8220;notify-by-page&#8221; which do the actual paging.  The final stanza is an example of a service that would get paged on. If the <b>check_http_string</b> check fails, the &#8220;important&#8221; contact group is notified.</p>
<p>The code to page is as follows:</p>
<pre><code>
define command {
        command_name    notify-by-page
        command_line    curl --data-urlencode "From=YOURTWILIONUMBER" --data-urlencode "To=YOURCELL" --data-urlencode "Body=[Nagios] $NOTIFICATIONTYPE$ $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$" https://SID:TOKEN@api.twilio.com/2010-04-01/Accounts/SID/SMS/Messages >> /tmp/sms
}
define command {
        command_name    host-notify-by-page
        command_line    curl --data-urlencode "From=YOURTWILIONUMBER" --data-urlencode "To=YOURCELL" --data-urlencode "Body=[Nagios] $HOSTSTATE$ alert for $HOSTNAME$" https://SID:TOKEN@api.twilio.com/2010-04-01/Accounts/SID/SMS/Messages >> /tmp/sms
}
</code></pre>
<p>To get the SID and TOKEN (note there are two instances of the SID, the second is in the URL right after accounts) go to your dashboard and look at the top:</p>
<p><a href="http://ertw.com/blog/wp-content/uploads/2011/09/twilio-sid-token.png"><img src="http://ertw.com/blog/wp-content/uploads/2011/09/twilio-sid-token-300x37.png" alt="" title="twilio-sid-token" width="300" height="37" class="alignnone size-medium wp-image-358" /></a></p>
<p>To get a number click on <b>Numbers</b> then <b>Buy a Number</b>:</p>
<p><a href="http://ertw.com/blog/wp-content/uploads/2011/09/twilio-buy-a-number.png"><img src="http://ertw.com/blog/wp-content/uploads/2011/09/twilio-buy-a-number-300x67.png" alt="" title="twilio-buy-a-number" width="300" height="67" class="alignnone size-medium wp-image-357" /></a></p>
<p>Then search for a number. It should be in the USA, as it looks like Canadian numbers don&#8217;t support SMS. You can verify this by clicking on &#8220;Buy&#8221;:<br />
<a href="http://ertw.com/blog/wp-content/uploads/2011/09/twilio-sms-enabled.png"><img src="http://ertw.com/blog/wp-content/uploads/2011/09/twilio-sms-enabled.png" alt="" title="twilio-sms-enabled" width="678" height="397" class="alignnone size-full wp-image-359" /></a></p>
<p>Buy the number for $1/month. You don&#8217;t have to set up any URLs with it if you&#8217;re doing outbound only.</p>
<p>YOURCELL should be obvious <img src='http://ertw.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  It could also be templated within Nagios.</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2011/09/07/nagios-paging-using-twilio/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Good for now does not mean good forever</title>
		<link>http://ertw.com/blog/2011/07/25/good-for-now-does-not-mean-good-forever/</link>
		<comments>http://ertw.com/blog/2011/07/25/good-for-now-does-not-mean-good-forever/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 21:12:48 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=345</guid>
		<description><![CDATA[&#1050;&#1072;&#1088;&#1090;&#1080;&#1085;&#1080;SmallPayroll.ca was my first big Rails project, and looking back at some of the code, it shows. One of the first things I did was the timesheet. The form has 21 input fields per employee, then it has to go through the database and figure out if days have changed or deleted. So it&#8217;s doing [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://ikoni.eu/">&#1050;&#1072;&#1088;&#1090;&#1080;&#1085;&#1080;</a></font><a href="http://smallpayroll.ca">SmallPayroll.ca</a> was my first big Rails project, and looking back at some of the code, it shows. One of the first things I did was the timesheet. The form has 21 input fields per employee, then it has to go through the database and figure out if days have changed or deleted. So it&#8217;s doing a lot, and at the time I was trying to figure out how both Ruby and Rails worked, and the code ended up being a mess.</p>
<p>But I was OK with that. If I was to get anywhere with SmallPayroll, people had to submit a timesheet. They didn&#8217;t care if the server side code was efficient as long as it worked. And, as I was to find out, they didn&#8217;t seem to care if it was slow. In order to build the rest of the app I had to have a timesheet. So I left my ugly inefficient code in, along with the tests that exercised it, and got to building the rest of the application.</p>
<p>Between <a href="http://rails-analyzer.rubyforge.org/">Rails Analyzer</a> and <a href="http://newrelic.com">New Relic</a> I kept an eye on things. The timesheet did get worse as time passed. Now that SmallPayroll has become more successful and I can spend more time on it, I&#8217;ve come back to look at fixing this. But before I know if I&#8217;m doing a better job, I have to know how I&#8217;m doing now.<br />
<br />
I found <a href="http://www.scribd.com/doc/15336193/Advanced-Performance-Optimization-of-Rails-Applications">Advanced Performance Optimization of Rails Applications</a> that had a neat trick to capture the queries generated by a test.</p>
<p>Put this in test_helper.rb:</p>
<pre><code>
module ActiveSupport
  class BufferedLogger
    attr_reader :tracked_queries
    def tracking=(val)
      @tracked_queries = []
      @tracking = val
    end

    def debug_with_tracking(message)
      @tracked_queries << $1 if @tracking &#038;&#038; message =~ /3[56]\;1m(.* (Load|Create|Update|Destroy)) \(/
      debug_without_tracking(message)
    end
    alias_method_chain :debug, :tracking
  end
end
class ActiveSupport::TestCase
  def track_queries(&#038;block)
    RAILS_DEFAULT_LOGGER.tracking = true
    # Had to add this to get queries to be logged
    Rails.logger.level = ActiveSupport::BufferedLogger::DEBUG
    yield
    result = RAILS_DEFAULT_LOGGER.tracked_queries
    RAILS_DEFAULT_LOGGER.tracking = false
    Rails.logger.level = ActiveSupport::BufferedLogger::INFO
    result
  end
end
</code></pre>
<p>Then wrap your test inside a test_queries block:</p>
<pre><code>
def test_submit_timesheet
    visit "/timesheet?date=2011-07-10"
    10.upto(16) do |day|
      fill_in /.*_shift_REG_2011-07-#{day}_hours/, :with => 8
    end

    queries = track_queries do
      click_button "Update"
    end
    puts queries.inspect
  end
</code></pre>
<p>After that it was a matter of making a performance test, copying over some of my functional tests that represented a case I was trying to optimize, then doing some before/after.</p>
<pre>
Before
------

TimesheetTest#test_submit_timesheet (283 ms warmup)
        process_time: 707 ms
        memory: 18915.89 KB
        objects: 232124
Queries: ["User Load", "User Update", "Employer Load", "Employee Load", "Shift Load", "Shift Create", "Shift Load", "Shift Create",
 "Shift Load", "Shift Create", "Shift Load", "Shift Create", "Shift Load", "Shift Create", "Shift Load", "Shift Create", "Shift Load",
 "Shift Create", "Shift Load", "Shift Create", "Shift Load", "Shift Create", "Shift Load", "Shift Create", "Shift Load", "Shift Create",
 "Shift Load", "Shift Create", "Shift Load", "Shift Create", "Shift Load", "Shift Create", "Shift Load", "Shift Create", "Shift Load",
 "Shift Create", "Shift Load", "Shift Create", "Shift Load", "Shift Create", "Shift Load", "Shift Create", "Shift Load", "Shift Create",
 "Shift Load", "Shift Create", "Employee Load", "Shift Load", "Property Load"]

After
-----

TimesheetTest#test_submit_timesheet (243 ms warmup)
        process_time: 578 ms
              memory: 14788.10 KB
             objects: 204551

Queries: ["User Load", "User Update", "Employer Load", "Employee Load", "Shift Load", "Shift Create", "Shift Create", "Shift Create",
"Shift Create", "Shift Create", "Shift Create", "Shift Create", "Employee Load", "Shift Load", "Property Load"]
</pre>
<p>So it would seem I've been able to knock off some time and memory consumption, along with lots of queries, by optimizing my code. Since I had already written test cases I was able to show that it worked the same as before.</p>
<p>But I think the better point to make here is that I could have spent a lot of time trying to build these optimizations in from day 1 and detracted from building a good product. Instead, I deferred the hard work until the time that it mattered. And now that I have more Ruby and Rails experience, doing the optimization was much easier. Something that might have taken several evenings over the course of a couple of weeks was done in less than a day. And while I don't follow TDD, having existing tests to start from made a huge difference.</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2011/07/25/good-for-now-does-not-mean-good-forever/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linode Review</title>
		<link>http://ertw.com/blog/2011/06/30/linode-review/</link>
		<comments>http://ertw.com/blog/2011/06/30/linode-review/#comments</comments>
		<pubDate>Thu, 30 Jun 2011 15:45:25 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=335</guid>
		<description><![CDATA[This site is hosted on a Linode 768 VPS, and has been for a couple of years now, along with some other domains. I have hosted it at home, and also on a GoDaddy VPS which didn&#8217;t end up being all that good, but am now very happy with Linode. I host a combination of [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>This site is hosted on a <a href="/linode.php">Linode 768 VPS</a>, and has been for a couple of years now, along with some other domains. I have hosted it at home, and also on a GoDaddy VPS which didn&#8217;t end up being all that good, but am now very happy with Linode. I host a combination of PHP (mostly WordPress) and Ruby on Rails applications.</p>
<p>Over the years Linode has kept the price the same ($30/month for my plan) but have increased the disk and memory of their plans every year. When I started out my plan had 18G of disk space and around 512MB of RAM, now it has 30G of disk and 768MB of RAM. So the value for money keeps on getting better.</p>
<p>I&#8217;ve also set up <a href="/linode.php">Linode VPSes</a> for a few people, including <a href="http://twitip.com">TwiTip.com</a> and <a href="http://topmmanews.com">TopMMANews.com</a> and continue to assist in their management. Both of them are fairly heavy sites and also run on a Linode 768. TwiTip hit 11mbps of traffic when it was tweeted by Ashton Kutcher, and TopMMANews has a fairly active site.</p>
<p>I&#8217;ve found the service to be very reliable. At one point one of their data centres was having problems but they were fixed reasonably quickly and the company kept the customers updated.</p>
<p>You get a control panel that lets you see your cpu/disk/io status, along with how much disk and network you&#8217;ve used. The screenshot below shows my system (you can see that I haven&#8217;t yet taken advantage of the 6GB of disk space they added to my account)</p>
<p><a href="http://ertw.com/blog/wp-content/uploads/2011/06/linode-control-panel.png"><img src="http://ertw.com/blog/wp-content/uploads/2011/06/linode-control-panel-tn.jpg" alt="" title="linode-control-panel" width="1680" height="935" class="alignnone size-full wp-image-339" /></a></p>
<p>One feature I really like about the service is that you get free DNS hosting, and the interface is very simple (I mean &#8220;simple&#8221; as &#8220;does not get in your way&#8221;, not as in &#8220;stripped of features&#8221;). You can do AAAA, TXT, and SRV records, or control the whole thing through an API. </p>
<p>I can&#8217;t speak highly enough about <a href="/linode.php">Linode VPSes</a>. If you&#8217;re looking for a VPS service they offer great value for money and a high service level. If you&#8217;re wondering about which size to buy, I&#8217;ve found the 768 to be a real workhorse. You can also upgrade/downgrade your plan with minimal downtime and no loss of data, so there&#8217;s little risk in picking the wrong plan.</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2011/06/30/linode-review/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Freshbooks/Heroku and Twilio APIs</title>
		<link>http://ertw.com/blog/2011/06/16/freshbooksheroku-and-twilio-apis/</link>
		<comments>http://ertw.com/blog/2011/06/16/freshbooksheroku-and-twilio-apis/#comments</comments>
		<pubDate>Thu, 16 Jun 2011 12:45:49 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=321</guid>
		<description><![CDATA[I have been playing with the Freshbooks API and the Twilio API as part of a contest that Twilio is running. It&#8217;s a great excuse to try something I&#8217;ve been meaning to do for a while. I ran into a few problems. The freshbooks gem doesn&#8217;t work under 1.9.2, which I found out after trying [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>I have been playing with the <a href="http://developers.freshbooks.com/">Freshbooks API</a> and the <a href="http://twilio.com">Twilio API</a> as part of a contest that Twilio is running. It&#8217;s a great excuse to try something I&#8217;ve been meaning to do for a while. </p>
<div style="float:right"></div>
<p>I ran into a few problems.</p>
<p>The <a href="http://freshbooks.rubyforge.org/">freshbooks gem</a> doesn&#8217;t work under 1.9.2, which I found out after trying to deploy to Heroku and then trying locally under RVM. The error was:</p>
<pre><code>NoMethodError in OutstandingController#index

undefined method `gsub!' for :invoice_id:Symbol
</code></pre>
<p>Someone made a compatible gem on <a href="https://github.com/bcurren/freshbooks.rb">Github</a> that you can use by using the following in your Gemfile instead of gem &#8220;freshbooks&#8221;:</p>
<pre><code>gem 'bcurren-freshbooks.rb',
 :require => 'freshbooks',
  :git => 'git://github.com/bcurren/freshbooks.rb'</code></pre>
<p>There were a couple of differences I found:</p>
<ul>
<li>Instead of using FreshBooks.setup to enter your credentials, use FreshBooks::Base.establish_connection</li>
<li>The original gem let you do FreshBooks::Invoice.send_by_email(id), the bcurren one makes it an instance method&#8230; FreshBooks::Invoice.get(id).send_by_email</li>
</ul>
<p>Those were the only two changes I had to make.</p>
<p>The second problem was with the <a href="https://github.com/webficient/twilio">Twilio gem</a>. I got SSL errors if I had to make calls to Twilio (as opposed to incoming requests from the Twilio API). </p>
<pre><code>OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed):
  app/controllers/phone_controller.rb:8:in `call'
</code></pre>
<p>The reason for this problem is that the OpenSSL library is making a call to an HTTPS resource, but it has no way to verify the certificate. There are two ways to fix this problem:</p>
<ol>
<li>Tell OpenSSL not to verify the certificate</li>
<li>Give OpenSSL the proper Certification Authority (CA) certificates to verify the certificate</li>
</ol>
<p>I&#8217;ll confess that my normal approach here is #1, but this time I felt like doing it properly&#8230; Since the Twilio module <a href="https://github.com/webficient/twilio/blob/master/lib/twilio.rb#L41">includes HTTPParty</a> you can call methods right on the Twilio module. So add an intializer inside config/initializers, such as twilio.rb:</p>
<pre><code>Twilio::ssl_ca_file File.join(Rails.root, "config/cacert.pem")</code></pre>
<p>Then, all you have to do is grab cacert.pem from somewhere else. Many other gems include it so if you look for the file on your hard drive you should find it. FWIW, the NewRelic one doesn&#8217;t work, it only includes the certificates they need. I ended up finding mine in ActiveMerchant.</p>
<p>*edit* I forked the twilio gem to try and bundle the cacerts.pem file, and as I was going through the code I saw that they look for the certs in /etc/ssl/certs unless you use the method above. </p>
<p>After that, things just worked!</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2011/06/16/freshbooksheroku-and-twilio-apis/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Showing git commits in a Rails view</title>
		<link>http://ertw.com/blog/2011/06/10/showing-git-commits-in-a-rails-vie/</link>
		<comments>http://ertw.com/blog/2011/06/10/showing-git-commits-in-a-rails-vie/#comments</comments>
		<pubDate>Fri, 10 Jun 2011 14:24:00 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=314</guid>
		<description><![CDATA[I have an administration panel for my Rails application that shows various information. I&#8217;ve found it helpful to show the last few commits along with a link to the repository. Here&#8217;s the code: Controller: @commits = Array.new git = `git log -15 --abbrev-commit --pretty=format:"%H - %cr - %s - %d"` git.split(/\n/).each do &#124;commit&#124; elements = [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>I have an administration panel for my Rails application that shows various information. I&#8217;ve found it helpful to show the last few commits along with a link to the repository. Here&#8217;s the code:</p>
<p>Controller:</p>
<pre><code>
    @commits = Array.new
    git = `git log -15 --abbrev-commit --pretty=format:"%H - %cr - %s - %d"`
    git.split(/\n/).each do |commit|
      elements = commit.split(/ - /)
      @commits << {
        :hash => elements[0],
        :time => elements[1],
        :subject => elements[2],
        :refs => (elements[3] || "").match(/deploy_[^,]*/)
      }
    end
</code></pre>
<p>The :refs never got used, I had thought that I&#8217;d tag all my deploys and be able to highlight them later, but it never ended up working out.</p>
<p>View: (It&#8217;s in HAML)</p>
<pre><code> - @commits.each do |commit|
      %li
        = link_to truncate(commit[:subject], :length => 80), "http://git.example.com/git/myapp.git/commit/#{commit[:hash]}"
        = "(#{commit[:time]})"
        %b= commit[:refs]
</code></pre>
<p>It&#8217;s pretty simple, it just parses the output of git log and spits it out as a list, showing the description and how long ago it was checked in. If you have gitweb or something similar installed, you get a link to the repo.</p>
<p>It&#8217;s helped me to find production bugs, and also when I deploy without pushing my code to the git repo, and end up forgetting some changes!</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2011/06/10/showing-git-commits-in-a-rails-vie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&quot;cd&quot; tricks to increase your efficiency</title>
		<link>http://ertw.com/blog/2011/03/04/quotcdquot-tricks-to-increase-your-efficiency/</link>
		<comments>http://ertw.com/blog/2011/03/04/quotcdquot-tricks-to-increase-your-efficiency/#comments</comments>
		<pubDate>Fri, 04 Mar 2011 20:33:12 +0000</pubDate>
		<dc:creator>sean</dc:creator>
				<category><![CDATA[Linux/Unix/OpenSource]]></category>

		<guid isPermaLink="false">http://ertw.com/blog/?p=303</guid>
		<description><![CDATA[&#1055;&#1086;&#1076;&#1072;&#1088;&#1098;&#1094;&#1080;&#1074;&#1080;&#1082;I was doing some work that involved moving between several directories. Remembering about pushd and popd, I googled around to try and find out how to use them properly. I found this article which was helpful, but what was even better was one of the comments talking about &#8220;cd -&#8221;. [root@host tmp]# pwd /tmp [root@host [...]<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://ikoni.eu/">&#1055;&#1086;&#1076;&#1072;&#1088;&#1098;&#1094;&#1080;</a></font><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://vikuslugi-ovi.com/">&#1074;&#1080;&#1082;</a></font>I was doing some work that involved moving between several directories. Remembering about pushd and popd, I googled around to try and find out how to use them properly. I found <a href="http://eriwen.com/bash/pushd-and-popd/">this article</a> which was helpful, but what was even better was one of the comments talking about &#8220;cd -&#8221;.</p>
<pre><code>
[root@host tmp]# pwd
/tmp
[root@host tmp]# cd -
/auto/tmp/sean
[root@host sean]# pwd
/auto/tmp/sean
[root@host sean]# cd -
/tmp
[root@host tmp]# pwd
/tmp
</code></pre>
<p>What it does is cycle you between your last two directories. It also operates outside of the pushd/popd stack:</p>
<pre><code>
[root@host tmp]# dirs
/tmp
</code></pre>
<p>So you should still be able to use those!</p>
<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://ertw.com/blog/2011/03/04/quotcdquot-tricks-to-increase-your-efficiency/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

