Integration Guide
This guide will teach you how to integrate your gem, framework, or other Ruby project with the honeybadger Ruby gem.
Who Is This Guide For?
This guide is for anyone who is interested in extending the capability of the Honeybadger gem in order to share their integration with the Honeybadger community. In addition to covering how to create your integration, you'll learn two ways to package and distribute it:
- Submit a pull-request (PR) to the official Honeybadger gem
- Publish your integration as a new gem that you maintain
What Can I Build?
Honeybadger's plugin system integrates with popular gems (and even Ruby itself) in order to report exceptions with rich contextual information. Here are some examples of plugins which have been created so far:
- Report exceptions in Sidekiq jobs, including the job parameters and configuration data
- Automatically associate errors with users for any application which uses a Warden-based authentication system (such as Devise)
- Hook into Ruby's exception system in order to report Local Variables for all Ruby exceptions
Getting Started
The Honeybadger gem has a plugin system which allows you to step into our initialization process. From there, you can use the full power of Ruby to integrate with Honeybadger in interesting ways.
Honeybadger's plugin API is simple—there are only a few methods you need to learn. To give you an idea of what this looks like, let's build a simple plugin.
Building Your Plugin
Imagine you're using a framework which provides the following API for handling exceptions:
MyFramework.on_exception do |exception|
# Exception handling code (report the exception, log it, etc.)
end
This is a fairly common pattern; for instance, SuckerPunch has a similar API.
Here's a Honeybadger plugin which checks to see if MyFramework
is available.
If it is, it installs an exception handler which reports all exceptions to
Honeybadger:
require 'honeybadger/plugin'
require 'honeybadger/ruby'
module Honeybadger
module Plugins
# Register your plugin with an optional name. If the name (such as
# "my_framework") is not provided, Honeybadger will try to infer the name
# from the current file.
Plugin.register 'my_framework' do
requirement do
# Check to see if the thing you're integrating with is loaded. Return true
# if it is, or false if it isn't. An exception in this block is equivalent
# to returning false. Multiple requirement blocks are supported.
defined?(MyFramework)
end
execution do
# Write your integration. This code will be executed only if all requirement
# blocks return true. An exception in this block will disable the plugin.
# Multiple execution blocks are supported.
MyFramework.on_exception do |exception|
Honeybadger.notify(exception)
end
end
end
end
end
There are three steps which Honeybadger performs when loading your plugin:
-
Honeybadger::Plugin.register
registers the plugin with Honeybadger. - When initializing an application, Honeybadger will attempt to load your
plugin, executing every
requirement
block you gave it. - If all
requirement
blocks returnedtrue
, then Honeybadger executes eachexecution
block in turn.
A Simple Sidekiq Plugin
Sidekiq is a good example of a framework which integrates nicely with Honeybadger, providing a lot of rich contextual data with each exception.
Note: Keep in mind that we already support Sidekiq natively, so don't try to actually run this example in a Honeybadger project, or you may get multiple exception reports. :)
# lib/honeybadger/plugins/sidekiq.rb
require 'honeybadger/plugin'
require 'honeybadger/ruby'
module Honeybadger
module Plugins
# It's best practice to create your own Honeybadger::Plugins::YourFramework
# namespace, if you need to create additional classes to use when executing
# your plugin.
module Sidekiq
class Middleware
def call(worker, msg, queue)
Honeybadger.context.clear!
yield
end
end
Plugin.register do
requirement { defined?(::Sidekiq) }
execution do
::Sidekiq.configure_server do |sidekiq|
sidekiq.server_middleware do |chain|
chain.prepend Middleware
end
sidekiq.error_handlers << lambda {|ex, params|
job = params[:job]
Honeybadger.notify(ex, {
parameters: params,
component: job['wrapped'] || job['class']
})
}
end
end
end
end
end
end
Sharing Your Plugin
Once you've built your plugin, it's time to share it with other 'badgers like you, for fame and glory (or at least a high-five). There are two good ways to share a plugin:
- Submit a PR to the Honeybadger gem
- Publish your own Ruby gem, such as "honeybadger-plugins-sidekiq"
We'd love to help you decide which of these is the best way to go. We're very open to including a wide variety of plugins in the official Honeybadger gem, so that everyone can enjoy them by default. Head over to GitHub and tell us about your plugin by creating a new issue.
Here's an example issue (this is just how I'd write it—you don't need to include a link to your plugin if you haven't finished it yet, or it isn't on GitHub).
Hey 'badgers!
I use Sidekiq a lot in my daily work, and since there is no existing Honeybadger integration, I decided to make one. Would you be interested in including Sidekiq as a default plugin?
Here's a link to Sidekiq:
https://github.com/mperham/sidekiq
Here's a link to my plugin:
https://github.com/joshuap/honeybadger-plugins-sidekiq
Thanks!
We'll get back to you as soon as possible. If we decide that your plugin is something that would benefit everyone, we'll ask you to submit a PR (if you aren't sure how to do this, don't worry—read on for instructions, and feel free to ask us for help!
If we decided against a PR for some reason, you can publish your plugin as a gem, which is another great way to share it with the community.
Submitting a PR
To submit a PR, you'll need a few things:
- A GitHub account
- Git and a supported Ruby version installed on your computer
- A fork of the honeybadger gem repository
After creating a fork (go to the honeybadger-ruby repository and use the Fork button, top-right of the page), run the following commands to set up your local copy of the gem:
git clone https://github.com/your-username/honeybadger-ruby.git
cd honeybadger-ruby
bundle install
To make sure everything is set up correctly, try running the unit tests:
bundle exec rake spec:units
You should see something like this:
All examples were filtered out; ignoring {:focus=>true}
Randomized with seed 14664
................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Finished in 0.97639 seconds (files took 0.57739 seconds to load)
512 examples, 0 failures
Assuming the tests ran, you should be ready to add your plugin code.
Create a file in lib/honeybadger/plugins/. The file name should use snake_case, and have a Ruby (
.rb
) file extension. If your plugin integrates with "MyFramework", then the file path should be lib/honeybadger/plugins/my_framework.rb.Add your plugin code to the file you created.
A good PR should include tests. We use RSpec for our test suite. For an example of a simple RSpec plugin test, check out the tests for the SuckerPunch plugin.
Use bundle exec rake spec:units
to run the tests while developing your
plugin. After adding some tests and/or verifying that your plugin doesn't cause
issues with Honeybadger, you're ready to submit your plugin:
-
Add an entry to CHANGELOG.md:
md## [Unreleased] ### Added - Added a plugin for MyFramework
See Keep a Changelog for more info on the format of the changelog.
-
Commit your changes:
shgit add . git commit --message "Add a MyFramework plugin."
-
Push your changes:
shgit push origin master
Now that your fork has the changes you want to add, create a pull request to the honeybadger-io/honeybadger-ruby repository on GitHub. If you're not sure how to create a pull request, check out GitHub's guide, and feel free to ask us for help!
Publishing Your Own Gem
Before publishing your own gem, read through the official RubyGems guide. Here are some basic steps to create a gem and publish it to RubyGems.org. If you get stuck, feel free to ask us for help!
Fun fact: did you know that Ruby Central uses Honeybadger to monitor RubyGems.org for exceptions?
Creating the Gem
Bundler has a handy tool that will create a simple gem for you.
-
Make sure you have the
bundler
gem installed:shgem install bundler
-
Create a new gem using the
bundle gem
command. You should name your gem "honeybadger-plugins-[name of your plugin]". For example, if your plugin integrates with MyFramework, name your project: "honeybadger-my_framework":shbundle gem honeybadger-plugins-my_framework
Follow the prompts to add tests (we use RSpec), create a license (we like MIT), and add a code of conduct for your gem.
-
Once your gem is created, check out the directory structure, and read the README:
shcd honeybadger-my_framework ls -l cat README.md
-
Lastly, run the
bundle install
command:shbundle install
It will fail the first time, asking you to edit the honeybadger-plugins-my_framework.gemspec file. Make the requested edits and then re-run
bundle install
until it completes successfully.
Note: If you added a test framework, run the new test suite with bundle exec rake
.
Adding Your Code
Add your plugin code to lib/honeybadger/plugins/my_framework.rb, which should have been created by the
bundle gem
command.If you chose to add a test framework when creating your gem, add some tests.
-
After you verify that your plugin works, commit your changes:
shgit add . git commit --message "Add a MyFramework plugin."
Pushing To RubyGems.org
To publish your first version (0.1.0) to RubyGems.org:
gem build honeybadger-plugins-my_framework.gemspec
gem push honeybadger-plugins-my_framework-0.1.0.gem
You can view your new gem at the following URL:
https://rubygems.org/gems/honeybadger-plugins-my_framework