Ruby
Article

Know What Your Users Know with Raygun

By Ilya Bodrov-Krukowski

springtimesoft_raygun_1_raygun_1

This article was peer reviewed by Thom Parkin. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!

Not sure about you, but I don’t like errors. Actually, when I see one I usually do something like this.

However, if you know about an error, you can fix it. It’s far worse when you don’t know about problems users are experiencing while browsing using your application. Some studies show that, in most cases, users are not willing to perform some action again once it has resulted in an error. Therefore, knowing about errors and responding to them as soon as possible is critical. In that vein, today’s guest is Raygun – a convenient and easy to setup error tracking service.

In this article, I am going to show you how to integrate Raygun into your Rails application and start to track errors in just ten minutes. We will also setup a special “Pulse” service allowing us to view how many users are currently browsing the web site, where are they are from, how satisfied they are and more!

The source code is available on GitHub.

Raygun and Its Services

Raygun was launched in early 2013. Initially the company was called Mindscape – it was crafting tools for .NET developers (like LightSpeed ORM and Web Workbench). The idea for creating a new service had been bouncing around the team for a few years as they were looking for a better way of dealing with bugs in production. Therefore, a decision was made to fix this problem by developing their own solution. Currently, Raygun’s team includes about twenty people, but it’s gradually growing, as the company is expanding into the US.

Raygun provides two major services: Crash Reporting and Pulse.

Crash Reporting provides integrations for various platforms from Rails and .NET to Android and Windows Phone (the team is working on adding support for even more platforms). It comes with a nice and easy-to-use dashboard where you can browse captured errors, see detailed information, set errors’ statuses, etc. What’s more, Crash Reporting can be integrated with team chat platforms (Hipchat or Slack), project management tools (JIRA and friends), and issue trackers (GitHub, Bitbucket, and others).

Another service, Pulse for user monitoring, was launched about a week ago after a year of development. It provides detailed information about performance (with a nice timeline that really helps to find bottlenecks), software that is used, user’s location, and device.

Note that both services are paid, however you can try them for free on a one-month trail. Pricing for Crash Reporting is available here. Pricing for Pulse can be found here. The company is considering adding more pricing plans (for individual developers, for example).

Preparations

Our preparations will be really quick. Create a new Rails app without the default testing suite:

$ rails new Raygunner -T

I am going to use Rails 4 for this demo, but you can stick with Rails 3. The Raygun adapter does not support Rails 2.

Now just create a controller and a simple view:

pages_controller.rb

class PagesController < ApplicationController
end

views/pages/index.html.erb

Hi!

Now we want to set up the root route for the app:

config/routes.rb

[...]
root to: 'pages#index'
[...]

That’s it! We are ready to start integrating Raygun!

Integrating Raygun

Start by adding the following gem into your Gemfile:

Gemfile

[...]
gem 'raygun4ruby'
[...]

Run

$ bundle install

raygun4ruby is a simple to use adapter that supports Rails, Sinatra, and plain Ruby.

You will need an account on Raygun. Grab your free 30 days trial here by providing name, e-mail and a password. Next, navigate to app.raygun.io/s/createapp to create a new app. When you are done, open the application’s setting page and find the API key field. This key will be used to transmit data to Raygun.

Use the following command to generate Raygun’s initializer file:

$ rails g raygun:install YOUR_APP_KEY_HERE

A new raygun.rb file inside initializers directory will be created. It contains some very basic configuration that we are going to change to suit our needs. By default, no data is sent to Raygun servers in development mode, however we want this to happen for the purposes of this demo. Therefore set config.enable_reporting to true.

config/initializers/raygun.rb

[...]
config.enable_reporting = true
[...]

Now run

$ rake raygun:test

to generate an exception for testing purposes. Wait a couple of seconds and open your application’s dashboard for crash reporting – you should see something like “Woohoo! Your Raygun<->Ruby connection is set up correctly” in the errors list.

By the way, any error in the Dashboard has one of the following statuses:

  • Active
  • Resolved
  • Resolved in version
  • Ignored
  • Permanently Ignored

For example, if you receive a notification about an error, you fire the person in charge, ask developers to fix it, and then set its status to “Resolved”. To do that, open that error and click on the drop-down list in the top right corner.

Great, now Raygun tirelessly watches our application!

Raising Errors

Okay, I am in a really destructive mood and want to call a non-existent method from my controller’s action:

pages_controller.rb

[...]
def index
    destroy_everything
end
[...]

Reload the main page of the web site and indeed an error page will be rendered. But, what’s more, in the console you will see:

[Raygun] Tracking Exception...

This basically means that teh error was caught and sent to Raygun. Currently, the product does not have a standalone version. The company is thinking about releasing one, which would allow you to store data on your own servers.

Okay, navigate to the Dashboard and wait for the error to appear (it may take some time). Note that each error has a pretty thorough set of information: stack trace, server’s name, and HTTP data.

You may worried about sensitive data. For example, what if don’t want to send like passwords to Raygun servers? By default, Raygun’s adapter won’t send any parameters listed in Rails.application.config.filter_parameters, but you can also change that in the initializer file:

config/initializers/raygun.rb

config.filter_parameters = [ :password, :cvv ]

Custom Data and Tagging

If you want to provide some custom data when tracking an error, that’s totally possible. Suppose that we like to perform division by zero:

pages_controller.rb

[...]
def index   
  begin
    1 / 0   
  rescue Exception => e
    Raygun.track_exception(e, custom_data: {my: 'I tried to do some zero division. How cool is that?'})
  end
end
[...]

As you can see, Raygun has a track_exception method that accepts an exception and a hash with custom data. You can provide the version of your application when tracking errors. This is done by setting config.version in the initializer file:

config/initializers/raygun.rb

config.version = "1.0.0.4"

Setting tags is also very easy. Simply use config.tags in your initializer:

config/initializers/raygun.rb

config.tags = ['heroku']

If you are sending error reports when in development mode, for example, the development tag will be set automatically.

Ignoring Errors

Ignorance is bliss. Sometimes. If you don’t want to be notified about specific exceptions, modify the initializer file like this:

config/initializers/raygun.rb

[...]
config.ignore << ['ZeroDivisionError']
[...]

Now, if you reload the server and navigate to the root page once again, you won’t see

[Raygun] Tracking Exception...

in the console, so the error won’t be tracked.

Keep in mind that, by default, Raygun ignores the following exceptions:

  • ActiveRecord::RecordNotFound
  • ActionController::RoutingError
  • ActionController::InvalidAuthenticityToken
  • ActionDispatch::ParamsParser::ParseError
  • CGI::Session::CookieStore::TamperedWithCookie
  • ActionController::UnknownAction
  • AbstractController::ActionNotFound
  • Mongoid::Errors::DocumentNotFound

If, for some reason, you do want to track them, simply remove the corresponding item from the hash:

config/initializers/raygun.rb

config.ignore.delete('ActionController::InvalidAuthenticityToken')

Affected Users

How many users were affected by an error? Raygun can inform you about that as well! All you have to do is provide a current_user method in your controller (and, as you know, solutions like Devise or Sorcery supply those by default) that returns an object responding to either id, email or username method.

If your method has some other name, just override config.affected_user_method accordingly:

config/initializers/raygun.rb

config.affected_user_method = :my_current_user

Also, if the returned object does not respond to the methods mentioned above, you can add your method name easily:

config/initializers/raygun.rb

config.affected_user_identifier_methods << :login

Want your users to stay anonymous? Create a method like this:

def raygun_user
  cookies.permanent[:raygun_user_identifier] ||= SecureRandom.uuid
end

in the ApplicationController and tweak config.affected_user_method.

You will then be able to observe affected users in the Users section of the Dashboard (it may take some time before data will be displayed). You will also be able to see the user’s device, Gravatar image, and Facebook profile (if the provided e-mail is linked to any, of course).

Raygun Pulse

Let’s setup Raygun Pulse really quickly to monitor our users. Currently, it only supports JavaScript, so drop the following code into the app’s layout file:

views/layouts/application.html.erb

<script>
!function(n,e,a,t,r,s,c){n.RaygunObject=r,n[r]=n[r]||function(){(n[r].o=n[r].o
                ||[]).push(arguments)},s=e.createElement(a),c=e.getElementsByTagName(a)[0],
        s.async=1,s.src=t,c.parentNode.insertBefore(s,c)}(window,document,"script",
        "//cdn.raygun.io/raygun4js/raygun.min.js","rg4js");

rg4js('apiKey', 'YOU_KEY_HERE');
rg4js('enablePulse', true);
rg4js('enableCrashReporting', false);
</script>

Als,o make sure to include the following code on your pages:

<script>
  rg4js('setUser', {
    identifier: 'USERS_ID_OR_EMAIL',
    isAnonymous: false,
    email: 'USERS_EMAIL',
    firstName: 'Name',
    fullName: 'Name Surname'
  });
</script>

In the Pulse section of your Dashboard, you will be able to observe beautiful data about users (including real-time monitoring showing how many users are browsing your website and where are they from).

That was fast, wasn’t it?

Integrating with GitHub

As a small bonus, I am going to instruct you how to integrate Raygun’s app with a GitHub repo.

First of all, open your app’s settings on the Raygun site. Navigate to Integrations – you will see a list of all integrations that Raygun currently supports. Click on GitHub and switch to the Setup page. Now you will have to login to GitHub and grant some permissions for Raygun to continue.

Once you are done, select one of your repos from the drop-down list. New issues will be created for this repo (or you will be able to link to existing ones). Place a check mark next to “Enabled” and click “Save”. You can also check “Mark linked errors as resolved when closed in GitHub” if you wish – that’s a neat feature as well.

Now navigate to Crash reporting dashboard and choose any active error. Here click on the Integrations drop-down and choose GitHub from the list. You can either create a new issue or link to an existing one. Now observe GitHub issues for the selected repo to see changes. Really convenient!

Conclusion

In this article we had a quick look at Raygun – a great monitoring service for vast a range of platforms. Of course, there is much more to it, so I really recommend browsing its documentation and playing with the Dashboard more. I found this service powerful, but at the same time easy to use, so its definitely worth giving it a try.

Which monitoring solution do you prefer? Would you consider using Raygun in the future? Share your experience in the comments and don’t hesitate to send me your questions. See you!

This article was written in co-authorship with Sergey Gusnin, Associate Professor, Ph.D. in engineering science.

  • http://github.com/harrykiselev Игорь

    Hello, Ilya!
    In your first listing of code (pages_controller.rb) you are missed index action of the controller. :)

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in Ruby, once a week, for free.