Rails Exception Notification and Logging
Photo by Randen Pederson, used under CC BY-SA 2.0, cropped from original.
Exception handling is an important component of any Rails application that is intended to be deployed in a production environment.
If you have ever felt your heart sink because you received a screenshot of your Rails application with this dreaded “something went wrong” message from a customer or client, you know what I’m talking about:
Though developers strive to deploy projects that are free of bugs and never throw an exception, the reality is that people using your Rails applications do sometimes encounter errors. When that happens it’s better to have your application automatically notify you of the event, rather than finding out about it for the first time when someone calls or emails you.
Exception Notification
The Exception Notification gem is a stalwart of the Ruby/Rails ecosystem and the standard solution for configuring your Rails project to notify you when errors occur. I typically use the gem to deliver notifications to a development/hosting team via email, but it has a variety of built-in notifiers that can output to just about any location you would want: Slack, IRC, Amazon SNS, etc., plus an option to write custom webhooks for other services that are not supported by default.
Exception Notification is simple to install and configure, particularly for Rails applications where it can be installed as a Rails engine and configured via an initializer. The default config/initializers/exception_notification.rb
initializer generated by the gem comes with an example of an email notifier:
# Email notifier sends notifications by email.
config.add_notifier :email, {
email_prefix: '[ERROR] ',
sender_address: %{"Notifier" <notifier@example.com>},
exception_recipients: %w{exceptions@example.com}
}
along with examples of other configuration options for conditions to determine which errors should generate notifications and some examples of other notification providers.
Starting with just an email notifier might be enough for your needs, but it’s worth reading through the Exception Notification documentation to find out what other capabilities it has, including options for rate-limiting to prevent your inbox from being inundated by recurring errors.
ExceptionTrack
A related Rails-specific gem called ExceptionTrack adds another layer of exception tracking on top of Exception Notifier; it provides a mechanism for storing exceptions in your Rails application’s database, and provides a web interface (mounted as an engine inside your application) for reviewing them.
I tend to use a combination of ExceptionTrack and Exception Notifier in my projects, using ExceptionTrack and Exception Notifier in production environments but not configuring any Exception Notifier deliveries in development. It is easy to configure the gems differently in development and production thanks to Rails’ separate environment config files.
Generating database migration and config files with rails g exception_track:install
will create the following initializer:
# config/initializers/exception-track.rb
# require 'exception_notification/sidekiq'
ExceptionTrack.configure do
# environments for store Exception log in to database.
# default: [:development, :production]
# self.environments = %i(development production)
end
# ExceptionNotification.configure do |config|
# config.ignored_exceptions += %w(ActionView::TemplateError
# ActionController::InvalidAuthenticityToken
# ActionController::BadRequest
# ActionView::MissingTemplate
# ActionController::UrlGenerationError
# ActionController::UnknownFormat)
# end
ExceptionTrack’s configuration options are limited to mostly specifying which environments you want it to store exceptions for; by default it is enabled for both development and production.
After that it’s just a matter of running the database migration to create a table for storing ExceptionTrack’s data and then adding a new route to mount the web interface in your application, with something like:
# config/routes.rb
# ...
mount ExceptionTrack::Engine => '/exceptions' if Rails.env.development?
# ...
If you want to make ExceptionTrack’s web interface available in production, it is advisable to protect the route behind authentication so that only users with admin-level access can view it. The Sidekiq gem’s documentation has some examples for protecting access to routes based on different authentication systems that can be easily adapted to work with ExceptionTrack’s routing.
Conclusion
Access to easily-installable tools for tracking and logging exceptions is a nice benefit for Rails developers, and Exception Notification / ExceptionTrack make a powerful combination for anyone interested in a self-serve solution that includes logging and the ability to send notifications to a wide variety of services.
Larger organizations and projects may benefit from a hosted service like Airbrake for error monitoring, but the solutions provided here can work well for many Ruby/Rails projects without the added expense of a managed third-party service.
Comments