We use cookies to offer you a better browsing experience, analyze site traffic, and serve targeted advertisements. If you continue to use this site, you consent to our use of cookies.
Accept

Ruby on Rails Sentry logger installation and configuration

Wiktor Plaga
Published: 
December 9, 2019

This is the step by step guide to install and configure Sentry Raven logger in the Ruby on Rails project in 2020.

Table of contents

Let's learn all about configuring Sentry for Ruby on Rails monitoring...

Sentry monitoring setup for Ruby on Rails

...or have it done

Yes, Hix does this - so you don't have to.

#What is Sentry?

Sentry is a realtime application monitoring and error tracking software which one can visit anytime via a web browser.

Applications can communicate with Sentry via the HTTP protocol, sending data about their crashes and exceptions.

Developers subscribe to Sentry's notifications and can almost instantly react to production problems by easily pinpointing them via sophisticated UI, which provides a complete set of data necessary for the job.

#Why use Sentry Raven with Ruby on Rails?

  1. It is free to use up to 5000 API requests per month.
  2. It gathers more data than the default Ruby on Rails logger.
  3. It provides an intuitive UI, which is more comfortable to work with than primitive log files.

Ruby on Rails is provided with a basic logger that writes to the selected file, or files. Reading a single file with the constantly appended massive stack traces is a primitive way to monitor the application.

Sentry collects and aggregates Ruby on Rails application crashes and exceptions data, with an additional context, such as a suspected release that started to cause the problem.

Via a sophisticated Sentry web UI developer can browse errors by the latest, most occurrent and multiple additional pieces of information provided.

I cannot stress enough how crucial it is that your Ruby on Rails application is hooked up with an advanced logging and monitoring system such as Sentry from its day one on production.

#Sentry account and project setup

Follow the instructions below to create your Sentry account and set up the Ruby on Rails project for further monitoring.

  1. Sign up on the official Sentry website.Sentry sign up form
    Sign up form on the Sentry official website
  2. In the second onboarding step, select "Rails" platform.Select Sentry project platfrom
    Select "Rails" platform in the Sentry setup
  3. From the third onboarding step copy your Sentry DSNSentry DSN
    Copy Sentry DSN

The DSN abbreviation stands for Data Source Name and is autogenerated for every project that you are going to hook into your Sentry account.

It allows you to keep all the logs in one place, which comes very handy especially for multiple services monitored daily.

#Sentry Raven installation in Ruby on Rails project

If you use Hix on Rails, your job is done here, all you gonna do is paste your Sentry DSN into the second step of the Hix on Rails project initialization wizard.

Otherwise, if you sadly did not automate that part of your life yet, follow steps below for Ruby on Rails Sentry configuration.

  1. Open your projects Gemfile and paste the gem 'sentry-raven' so it's available for every environment.
  2. In a command-line navigate to the project's directory, enter bundle install and while it runs go to the next step.
  3. Create the config/initializers/sentry.rb file and paste the minimal configuration required, replacing the value with previously copied Sentry DSN.

config/initializers/sentry.rb

# frozen_string_literal: true

Raven.configure do |config|
  config.dsn = 'YOUR_SENTRY_DSN_GOES_HERE'
end

This is a minimal setup required to hook up your Ruby on Rails application with your newly created Sentry account, via the dedicated sentry-raven gem.

It is overall a better idea to not store credentials in your project repository and use dedicated environmental management instead. For example, if you use a dotenv-rails gem, it is a better idea to provide your DSN via the .env file.

.env

SENTRY_DSN=YOUR_SENTRY_DSN_GOES_HERE

config/initializers/sentry.rb

# frozen_string_literal: true

Raven.configure do |config|
  config.dsn = ENV['SENTRY_DSN']
end

Let's see what other configuration options are worth tweaking while monitoring Ruby on Rails project with Sentry.

#Ruby on Rails Sentry configuration

With the minimalistic setup, we started to report Ruby on Rails application exceptions to the Sentry.

Raven default configuration with the DSN passed at this point is:

Raven.configure do |config|
  config.dsn = ENV['SENTRY_DSN']
  config.async = false
  config.context_lines = 3
  config.current_environment = current_environment_from_env
  config.encoding = 'gzip'
  config.environments = []
  config.exclude_loggers = []
  config.excluded_exceptions = IGNORE_DEFAULT.dup
  config.inspect_exception_causes_for_exclusion = false
  config.linecache = ::Raven::LineCache.new
  config.logger = ::Raven::Logger.new(STDOUT)
  config.open_timeout = 1
  config.processors = DEFAULT_PROCESSORS.dup
  config.project_root = detect_project_root
  config.rails_activesupport_breadcrumbs = false
  config.rails_report_rescued_exceptions = true
  config.release = detect_release
  config.sample_rate = 1.0
  config.sanitize_credit_cards = true
  config.sanitize_fields = []
  config.sanitize_fields_excluded = []
  config.sanitize_http_headers = []
  config.send_modules = true
  config.server = ENV['SENTRY_DSN']
  config.server_name = server_name_from_env
  config.should_capture = false
  config.ssl_verification = true
  config.tags = {}
  config.timeout = 2
  config.transport_failure_callback = false
  config.before_send = false
end

#Environments setup

By default, whenever provided a valid DSN, Sentry Raven will work automatically in every Ruby on Rails environment, where the defaults are test, development, and production.

That's overkill for the development environment, so my advice is to further configure it after checking if it works.

Raven.configure do |config|
  config.environments = %[production]
end

This way an automated test suite and development of new features won't eat up your quota.

Another closely related option that is wisely deduced by Raven is current environment detection.

  1. First, Sentry tries to get ENV['RAILS_ENV']
  2. Next, if first is absent, it tries ENV['RACK_ENV']

You can customize it via the current environment configuration flag.

Raven.configure do |config|
  config.current_environment = 'staging'
end

Whatever you'll set here, will be visible in the Sentry environments dropdown.

Sentry filtering by environments
Sentry environments dropdown

#Asynchronous reporting

Error logging is not the primary task of most of the web applications, including Ruby on Rails. It is good to keep it asynchronous, and Sentry allows users to do so by exposing the asynchronous configuration flag.

Raven.configure do |config|
  config.async = lambda { |event| SentryJob.perform_later(event) }
end

app/jobs/sentry_job.rb

class SentryJob < ActiveJob::Base
  queue_as :sentry

  def perform(event)
    Raven.send_event(event)
  end
end

If the async callback raises an exception, Raven will attempt to send synchronously.

#Data sanitization

Sentry for Ruby on Rails provides two configuration options for data sanitization.

Raven.configure do |config|
  config.sanitize_fields = ["my_field", "foo(.*)?bar]
  config.sanitize_http_headers = %w[Referer User-Agent Server From]
end

The field sanitization accepts a raw string and regex-like strings for striping the data from the requests sent to Sentry.

The second one allows you to filter out HTTP headers from the payload. A full list of potentially sensitive HTTP headers can be found in the RFC 2616.

#Data processing

The default Sentry data processors are:

# Note the order - we have to remove circular references and bad characters
# before passing to other processors.
DEFAULT_PROCESSORS = [
  Raven::Processor::RemoveCircularReferences,
  Raven::Processor::UTF8Conversion,
  Raven::Processor::SanitizeData,
  Raven::Processor::Cookies,
  Raven::Processor::PostData,
  Raven::Processor::HTTPHeaders
].freeze

which we can modify via yet another configuration flag by adding new and removing existing processors from the array.

require 'raven/processor/removestacktrace'

Raven.configure do |config|
  config.processors << Raven::Processor::RemoveStacktrace
  config.processors -= [Raven::Processor::PostData]
  config.processors -= [Raven::Processor::Cookies]
end

You might want to remove cookies and post data processors via the configuration, as by default Sentry does not send POST data or cookies if present, and it may improve your further debugging experience.

A full list of the Raven processors belonging to the `Raven::Processor` module.

├── processor
│   ├── cookies.rb
│   ├── http_headers.rb
│   ├── post_data.rb
│   ├── removecircularreferences.rb
│   ├── removestacktrace.rb
│   ├── sanitizedata.rb
│   └── utf8conversion.rb

On top of all that, Sentry allows filtering out selected exceptions by appending them to the excluded exceptions array.

Raven.configure do |config|
  config.excluded_exceptions += ['ActionController::RoutingError']
end

On an even deeper level, Sentry allows you to prevent exceptions from being sent via providing your custom logic.

Raven.configure do |config|
  config.should_capture = Proc.new do |exception|
    exception.super != 'WillinglyUnreportedException'
  end
end

It is especially useful when you want to filter out a whole bunch of exceptions without always remembering to put them into the excluded exceptions array.

class WillinglyUnreportedException < StandardError; end
class DontCareTooMuchException < WillinglyUnreportedExceptions; end
class NevermindException < WillinglyUnreportedExceptions; end

Another option that might be especially useful for large applications is data sampling.

Raven.configure do |config|
  config.sample_rate = 0.5
end

A value of 0 will deny sending any events, and value of 1 will send every single event, which is the default behavior.

#Pinpoint guilty release

Sentry is clever in deducing which release causes an exception. It takes the following in the given order of precedence.

  1. Commit SHA of the last git commit
  2. Last line of the application root REVISION file
  3. For Heroku, dyno metadata enabled via Heroku Labs

It can be customized if you have some kind of custom release tracking system.

Raven.configure do |config|
  config.release = 'custom release string'
end

The default settings may be configured smoothly with popular git remote providers such as Github and Gitlab for convenient linking to the guilty git commits and tags via Sentry UI.

#Proxy and Secure Sockets Layer

Sentry gives its user an option to configure a proxy connection.

Raven.configure do |config|
  config.proxy = 'http://example.com'
end

It accepts a simple string representing the URL to your proxy server.

SSL verification might be disabled in the configuration file, as it's enabled by default.

Raven.configure do |config|
  config.ssl_verification = false
end

#Custom reports modifications

In your configuration file, you can use two options provided for globally customizing Sentry reports.

Raven.configure do |config|
  config.tags = { hostname: `hostname` }
  config.before_send = lambda do |event, hint|
    event.fingerprint = ['fingerprint']
    event
  end
end

A first of them, the tagging option, allows you to send an additional context with your events for further filtering. For example, if you have a load balancer set up in front of your Ruby on Rails application, you might want to send some info identifying a specific instance on which the exception occurred.

The second one helps you to modify every single occurrence on the fly, accessing it before is send. Be aware that if you won't return the event from this method, it will be dropped.

#Conclusion

Sentry is a powerful tool that helps you to keep the Ruby on Rails application well-maintained and is definitely worth using if you want to monitor every newly developed feature seriously.

With Hix on Rails, all you need to do in order to have a fully configured Sentry logger is creating your account and copy-pasting the Sentry DSN into the project initialization wizard.

You think you know Rails?

5 questions, 20 seconds each.

There's A LOT to know
about Ruby on Rails internals.

There is an award for 5/5 score.

Ready?

Does ActiveStorage require ActiveRecord?

Are files stored with ActiveStorage publicly available by default?

Which statements about ActiveStorage are false?

Which statements about ActiveStorage are true?

Initializing rails new allows skipping ActiveJob

Select ActionMailer authentication methods available by default

Which statements about ActionMailer are true?

Which statements about ActionCable are true?

Does config/application.rb file run before initializers?

Which migration table method creates Foreign Key?

Does automatic deletion of joined has_many records trigger callbacks?

Pick Rails-specific HTML head meta tags:

Which statements about ActiveRecord ORM are true?

Which ActiveRecord method is the most efficient one performance-wise?

Which ActiveRecord methods skip callbacks?

Your score is:

/5

There's a lot to learn ahead of you, but the good news is that you've made the first step!

You can follow our tutorials on creating quality projects or use Hix, which will take this score to 5/5.

The bell's ringing, but it's hard to tell where.

You can follow our tutorials on creating quality projects or use Hix, which will take this score to 5/5.

We're getting there!

You can follow our tutorials on creating quality projects or use Hix, which will take this score to 5/5.

Not great, not terrible.

You can follow our tutorials on creating quality projects or use Hix, which will take this score to 5/5.

Momma would've been proud!

To up your game a little, you can follow our tutorials on creating high-quality projects or use Hix, which will take this score to 5/5.

It doesn't get any better than that! Congrats, you got yourself an award!

five_on_five

Improve your workflow using Hix - use your coupon for a 10% discount.

Learn more

No, thanks

2
Leave a Reply

avatar
1 Comment threads
1 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
Wiktor PlagaTony Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Tony
Guest
Tony

Nice write up - would be handy to have a bit more detail on the release integration to pinpoint guilty commits. Setting that up with Heroku and Github