reevoolabs : open source technology

Exception Messaging

To keep track of any exceptions in our applications, we needed an easy way of being notified when an error occurred. We initially looked at the exception notifier plugin but whilst it did what it said on the tin, receiving an email for each exception was too noisy and distracting.

Instead, we decided to build upon our existing Beanstalkd queue setup and using our beanstalk messaging plugin we were able to put together a simple Rails plugin that forwards exceptions to a beanstalkd queue instance. This allowed us to decouple the collection of exceptions from processing them and deal with them in whichever way we liked.

Installing the plugin

This plugin requires the beanstalk messaging plugin. Once you’ve installed this, you can install the exception messaging plugin.

$ ./script/plugin install http://svn.reevoo.com/repos/plugins/exception_messaging/

Configuration

The plugin provides a class-level method that allows you to specify the queue that you want exceptions to be sent to. Assuming we have access to an instance of a Beanstalk::QueueManager, qm, we can tell our app to forward all exceptions to an “exceptions” queue by adding the following line to our application controller:

class ApplicationController < ActionController::Base
  notifies_exceptions_to qm.queue(:exceptions)
end

Ideas for processing exceptions

The simplest thing that you can do is write a small Ruby script that takes each exception and emails it, just like the exception notification plugin. If you would rather not send an email for each exception, you could batch email exceptions instead. The following example uses code from the beanstalk messaging plugin:

## exception_mailer.rb
class ExceptionMailer < ActionMailer::Base
  def batch_exception_notification(exceptions, recipient)
    recipients recipient
    from "sysadmin@yoursite.com"
    subject "Application exceptions"
    body :exceptions => exceptions
  end
end

## batch_exception_notification.erb
<% @exceptions.each do |exception| %>
<%= exception %>
<% end %>

## process_exceptions.rb
queue_manager = Beanstalk::QueueManager.new('path/to/my/beanstalk/config.yml')
queue_poller  = Beanstalk::QueuePoller.new(queue_manager)

# collect exceptions and email each 100 in a batch
queue_poller.poll_with_buffer(:exceptions, 100) do |messages|
  exceptions = messages.map(&:ybody)
  ExceptionMailer.deliver_batch_exception_notification(exceptions, 'sysadmin@yoursite.com')
  messages.each { |m| m.delete }
end

Alternatively, you could write a basic Rails/Merb exception reporting application and write a simple Rake task to grab the latest applications and insert them into the application database, which could be run periodically via a cron job.

Also see: Collecting exceptions asynchronously using Beanstalkd and Hoptoad.

Projects

Recent Articles