Get on the Right Track with Our Rails Integration!
Tags: rails, observability, o11y, instrumentation
Published: 2020-10-21 17:42:20

Thanks to awesome contributions from the community and the hard work of our integrations team, the Honeycomb Rails integration comes with lots of great features out of the box. We’ve written about Rails-specific features of the Ruby Beeline before on the Honeycomb blog:
<ul>
 	<li><a href="https://www.honeycomb.io/blog/new-features-for-ruby-and-rails-applications-with-a-new-version-of-the-honeycomb-beeline-for-ruby/">New features for Ruby and Rails applications with a new version of the Honeycomb Beeline for Ruby</a></li>
 	<li><a href="https://www.honeycomb.io/blog/honeybyte-beeline-dev-molly-struve/">HoneyByte: Make a Beeline Toward Observability Just Like DEV’s Molly Struve</a></li>
 	<li><a href="https://www.honeycomb.io/blog/honeybyte-incremental-instrumentation-beyond-the-beeline/">HoneyByte: Incremental Instrumentation Beyond the Beeline</a></li>
</ul>
This post is an end-to-end tutorial to show you exactly the steps involved, from creating a new Honeycomb team to getting your data in and observing your app in production.

Whether you’re starting a new Rails project and want to build observability in from the start, or you’re investing in better observability for your existing Rails service, this tutorial will help you get the most out of Honeycomb right away.
<h2>Create a free Honeycomb account</h2>
Go to <a href="http://ui.honeycomb.io/signup" target="_blank" rel="noopener noreferrer">ui.honeycomb.io/signup</a> to create your account. We support SSO with Google, which means no new passwords to create or remember.

<img class="alignnone size-full wp-image-7482" src="https://www.honeycomb.io/wp-content/uploads/2020/08/image-10.png" alt="Screenshot of Honeycomb sign up screen " width="383" height="243" />

Provide your organization’s name when prompted. This is a unique ID, so you can either use your company's name, or if it's a large company you might go with <code>company-team</code>, e.g. <code>huuli-research</code>.

If you're prompted to name your first dataset, call it <code>rails-app</code> or give it the same name as your app. (If you change your mind about the name later, you can just create a new dataset.) Select the Ruby integration and click <b>Create</b>.

Once you’ve created your team, you’ll automatically receive an email inviting you to the Honeycomb Pollinators Slack community. <a href="https://www.honeycomb.io/blog/spread-the-love-appreciating-our-pollinators-community/" target="_blank" rel="noopener noreferrer">This blog post</a> from Customer Advocate Jenni Boyer details why you should join, definitely check it out when you get the chance!
<h2>Get your API key</h2>
The next page will give you your Honeycomb API key (also called the write key). If you chose the Ruby integration, this page will also list out instructions for setting up the Ruby Beeline, including Rails-specific instructions. Don’t worry about them, though—I‘ll break down each step for you here.

Copy your API key now, we’ll be using it in the next steps. (If you lose track of your API key, you can always copy it again from your Team Settings.)
<h2>Configure the Ruby Beeline SDK</h2>
Now you can open up your terminal and set up the Rails integration for your app. The Ruby Beeline SDK comes in the form of a gem, so we’ll add it to our Gemfile using Bundler:
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="beyond" data-enlighter-linenumbers="false">$ bundle add honeycomb-beeline
</pre>
Now we’re ready to generate the Honeycomb configuration. The Beeline has a Rails generator built-in, so we can use that with the API key you copied earlier (denoted <code>abc123</code> here) along with your dataset’s name, <code>rails-app</code>:
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="beyond" data-enlighter-linenumbers="false">$ rails generate honeycomb abc123 --dataset rails-app</pre>
This will create a new file: <code>config/initializers/honeycomb.rb</code>. The generator hard-codes your API key to start, but we’ll update this file later to store your key more safely.
<h2>Generate Your First Events</h2>
You’re ready to start sending data to Honeycomb! Start the Rails server and then navigate to <code>localhost:3000</code> in your browser, or run <code>curl localhost:3000</code> in your terminal if you prefer. This will hit the root path and send your first event to Honeycomb. Let’s return to <a href="http://ui.honeycomb.io" target="_blank" rel="noopener noreferrer">ui.honeycomb.io</a> to watch it arrive!

<a href="https://www.honeycomb.io/wp-content/uploads/2020/08/Image-2020-08-23-at-10.11.58-PM.png"><img class="alignnone wp-image-7487 size-full" src="https://www.honeycomb.io/wp-content/uploads/2020/08/Image-2020-08-23-at-10.11.58-PM.png" alt="Image of event sent to Honeycomb IU" width="3580" height="2164" /></a>

The home page shows us a single data point on the <b>Total Requests</b> graph and a single trace under <b>Recent Traces</b>. Success!

With just this one request sent from dev, there’s not enough data to make the home page very interesting. But we can still poke around a bit. Click the button on your trace under <b>Recent Traces</b>.

<img class="alignnone wp-image-7488 size-full" src="https://www.honeycomb.io/wp-content/uploads/2020/08/Image-2020-08-23-at-10.14.28-PM.png" alt="Screenshot of recent traces tab" width="638" height="362" />

This takes us into the trace view for the request we just made:

<a href="https://www.honeycomb.io/wp-content/uploads/2020/08/Image-2020-08-23-at-10.25.21-PM.png"><img class="alignnone wp-image-7490 size-full" src="https://www.honeycomb.io/wp-content/uploads/2020/08/Image-2020-08-23-at-10.25.21-PM.png" alt="Trace view of request" width="3580" height="2154" /></a>

The tracing we see here comes built in with the Ruby Beeline! Not only do we automatically get spans wrapped around top-level HTTP requests, ActiveRecord calls, controller actions, and view rendering, we also get relevant context fields attached to all of those spans. Select the root span <code>http_request</code> and scroll through the <b>Fields</b> list in the right-hand sidebar to see what fields are attached to that span. Then choose another span, like <code>process_action.action_controller</code>, to see the fields that come included with that one.

You may already be thinking of additional context fields to instrument various parts of your app to send to Honeycomb, but this is a good stopping point. What are the next steps to get this MVP version into production?
<h2>Get Ready to Ship</h2>
Your app is now instrumented for Honeycomb! Let’s update a couple things so you can open a PR, push your new instrumentation to prod, and start unlocking more insights.

Earlier, you called the <code>rails generate</code> command with your API key directly, creating the <code>config/initializers/honeycomb.rb</code> file. Now’s the time to remove the hard-coded API key there and store it safely according to how your team manages secrets.

For example, if you’re using the Rails <code>config/secrets.yml</code> file to manage your secrets, you can add your API key there.
<pre class="EnlighterJSRAW" data-enlighter-language="yaml" data-enlighter-theme="beyond" data-enlighter-linenumbers="false" data-enlighter-title="config/secrets.yaml" data-enlighter-group="config/secrets.yaml">development:
  honeycomb_write_key: 'abc123'
production:
  honeycomb_write_key: 'abc123'</pre>
Then, update the Honeycomb initializer to safely use the API key straight from the secrets file:
<pre class="EnlighterJSRAW" data-enlighter-language="diff" data-enlighter-theme="beyond" data-enlighter-linenumbers="false" data-enlighter-group="config/initializers/honeycomb.rb" data-enlighter-title="config/initializers/honeycomb.rb">- config.write_key = "abc123"
+ config.write_key = Rails.application.secrets.honeycomb_write_key</pre>
And you’re set! Open that PR 🚢 (and <a href="https://www.honeycomb.io/blog/spread-the-love-appreciating-our-pollinators-community/">check out the Pollinators blog post</a> I shared earlier while you're waiting for PR reviews 😉).
<h2>Observe Production Traffic</h2>
Why the rush? Honeycomb’s home page comes alive in production. We can see the Total requests, Latency, and Error rate using the Rails auto-instrumentation built into the Ruby Beeline.

<a href="https://www.honeycomb.io/wp-content/uploads/2020/08/Image-2020-08-23-at-10.53.27-PM.png"><img class="alignnone wp-image-7491 size-full" src="https://www.honeycomb.io/wp-content/uploads/2020/08/Image-2020-08-23-at-10.53.27-PM.png" alt="Image showing Total requests, Latency, and Error rate using the Rails auto-instrumentation built into the Ruby Beeline" width="3632" height="2296" /></a>

Clicking over to the <b>HTTP Status Code</b> tab, we can also see the breakdown of response codes as well as the distribution of latencies for each one.

<a href="https://www.honeycomb.io/wp-content/uploads/2020/08/Screen-Shot-2020-08-23-at-10.49.35-PM.png"><img class="alignnone wp-image-7492 size-full" src="https://www.honeycomb.io/wp-content/uploads/2020/08/Screen-Shot-2020-08-23-at-10.49.35-PM.png" alt="Image showing breakdown of response codes as well as the distribution of latencies for each one" width="3632" height="2296" /></a>

There’s a ton to explore here, just start clicking around. See how much you can learn from the auto-instrumentation by itself.
<h2>Add Custom Instrumentation</h2>
Now that you’ve explored Honeycomb with your app’s production traffic, it’s time to dig deeper. You have a handle on events and tracing for regular Rails HTTP requests, so let’s try adding custom spans and fields. What’s unique about your app that you’d like to learn more about?

You likely have some home-rolled <code>lib/</code> code that’s not covered by the Beeline’s auto-instrumentation. For example, imagine that your app uses the <a href="https://github.com/sferik/twitter" target="_blank" rel="noopener noreferrer">twitter</a> gem to get a user’s tweets in batches of 200 at a time:
<pre class="EnlighterJSRAW" data-enlighter-language="ruby" data-enlighter-theme="beyond" data-enlighter-linenumbers="false">def get_all_tweets(user)
  all = []
  options = { count: 200, include_rts: true }
  loop do
    tweets = client.user_timeline(user, options)
    return all if tweets.empty?
    all += tweets
    options[:max_id] = tweets.last.id - 1
  end
end</pre>
Here’s an updated version with some instrumentation:
<pre class="EnlighterJSRAW" data-enlighter-language="ruby" data-enlighter-theme="beyond" data-enlighter-highlight="2, 3, 7, 8" data-enlighter-linenumbers="false">def get_all_tweets(user)
  Honeycomb.start_span(name: 'get_all_tweets') do
    Honeycomb.add_field_to_trace('user', user)
    all = []
    options = { count: 200, include_rts: true }
    loop do
      Honeycomb.start_span(name: 'get_batch') do
        Honeycomb.add_field('options', options)
        tweets = client.user_timeline(user, options)
        return all if tweets.empty?
        all += tweets
        options[:max_id] = tweets.last.id - 1
      end
    end
  end
end</pre>
We start by wrapping the entire <code>get_all_tweets</code> method body in a span, and then we add the <code>user</code> field to the entire trace, since we’ll probably care about it across the entire request. We add a second span block around the body of the loop called <code>get_batch</code>, which creates a child span for each request where we get a 200-tweet batch. Inside of <code>get_batch</code>, we’re adding the request <code>options</code> as a field as well, so we can see the relevant arguments when hitting Twitter’s API.

(At this point I’d probably break out the loop body into a separate <code>get_batch</code> method, which is usually about the scope you want for a span.)

Our nested spans will be rendered as a trace in the Honeycomb UI:

<img class="alignnone size-full wp-image-7493" src="https://www.honeycomb.io/wp-content/uploads/2020/08/Image-2020-08-23-at-9.58.51-PM.png" alt="Screenshot of trace in the Honeycomb UI" width="2602" height="718" />

Each <code>get_batch</code> is making an API call to Twitter, so to get all of the tweets from this user we needed to make eight API calls.
<h2>Continue Your Journey!</h2>
The Ruby Beeline does a lot of the heavy lifting to get you sending rich data into Honeycomb quickly and without a lot of work. On top of that, it’s not a lot of code to start adding your own custom instrumentation beyond what the Beeline does automatically.

Now that you have data in, invite your team and see what insights you can learn together! <a href="https://www.honeycomb.io/blog/all-aboard-team-onboarding/">Check out this blog post</a> on helpful Honeycomb features for onboarding your teammates.