bugwatch-ruby

Official Ruby/Rails SDK for BugWatch — open-source error monitoring.

Installation

# Gemfile
gem "bugwatch-ruby"
bundle install

Configuration

# config/initializers/bugwatch.rb
Bugwatch.configure do |c|
  c.api_key               = ENV["BUGWATCH_API_KEY"]
  c.endpoint              = ENV["BUGWATCH_ENDPOINT"]   # e.g. "https://your-app.herokuapp.com"
  c.release_stage         = Rails.env.to_s
  c.notify_release_stages = ["production", "staging"]
  c.ignore_classes        = ["ActionController::RoutingError"]
  c.app_version           = ENV["GIT_REV"]             # optional git SHA
end

User context

# app/controllers/application_controller.rb
before_action :set_bugwatch_user

private

def set_bugwatch_user
  return unless current_user
  Bugwatch.set_user(
    id:    current_user.id,
    email: current_user.email,
    name:  current_user.name
  )
end
Bugwatch.leave_breadcrumb("User clicked checkout", type: "ui", metadata: { cart_id: 42 })

Manual notification

begin
  risky_operation
rescue => e
  Bugwatch.notify(e)
  raise
end

Deploy tracking

Track deploys so BugWatch can correlate new errors with releases.

Bugwatch.track_deploy(
  version:     "abc1234",
  environment: "production",       # defaults to config.release_stage
  description: "Deployed abc1234",
  deployed_by: "ci"
)

Heroku

On Heroku, SOURCE_VERSION (the git SHA) is available during the build phase but not during the release phase. The recommended approach is to bake the SHA into a REVISION file at build time, then read it at release time.

1. Create a Rake task in lib/tasks/bugwatch.rake:

namespace :bugwatch do
  task write_revision: :environment do
    revision = ENV["SOURCE_VERSION"] || `git rev-parse HEAD 2>/dev/null`.strip
    if revision.present?
      File.write(Rails.root.join("REVISION"), revision)
      puts "Bugwatch: wrote REVISION #{revision[0..6]}"
    end
  end

  task track_deploy: :environment do
    revision_file = Rails.root.join("REVISION")
    version = ENV["SOURCE_VERSION"] \
      || (File.read(revision_file).strip if File.exist?(revision_file)).presence \
      || Time.now.utc.strftime("%Y%m%d%H%M%S")

    thread = Bugwatch.track_deploy(
      version: version,
      description: "Deployed #{version[0..6]}",
      deployed_by: ENV["BUGWATCH_DEPLOYED_BY"] || "heroku"
    )
    thread&.join(5)
    puts "Bugwatch: tracked deploy #{version[0..6]}"
  end
end

# Bake the SHA into the slug during assets:precompile
if Rake::Task.task_defined?("assets:precompile")
  Rake::Task["assets:precompile"].enhance(["bugwatch:write_revision"])
end

2. Add the deploy task to your Procfile release phase:

release: bundle exec rails db:migrate && bundle exec rails bugwatch:track_deploy

The build will write the commit SHA to REVISION, and the release phase will read it back and report the deploy to BugWatch.

User Feedback Widget

Drop a feedback form into any view so users can report issues directly from your app. The form submits to BugWatch's feedback API — no controller code needed.

<%%= bugwatch_feedback_widget %>

The helper renders a plain, unstyled HTML form with CSS classes you can target:

Class Element
.bugwatch-feedback-form The <form> wrapper
.bugwatch-feedback-field Each field's <div>
.bugwatch-feedback-label <label> elements
.bugwatch-feedback-input Text/email <input>
.bugwatch-feedback-textarea The message <textarea>
.bugwatch-feedback-submit Submit <button>
.bugwatch-feedback-success Success message (hidden by default)
.bugwatch-feedback-error Error message (hidden by default)

Options

<%%= bugwatch_feedback_widget(
  user_email: current_user&.email,
  user_name:  current_user&.name,
  placeholder: "Describe the issue...",
  submit_text: "Report Issue",
  success_message: "We got it — thanks!",
  issue_id: @issue_id,        # optional: link to a specific BugWatch issue
  metadata: { page: "checkout" }
) %>

Styling example (Tailwind)

.bugwatch-feedback-form { @apply space-y-4 max-w-md; }
.bugwatch-feedback-label { @apply block text-sm font-medium text-gray-700; }
.bugwatch-feedback-input,
.bugwatch-feedback-textarea { @apply w-full border rounded-lg px-3 py-2 text-sm; }
.bugwatch-feedback-submit { @apply bg-blue-600 text-white px-4 py-2 rounded-lg text-sm; }
.bugwatch-feedback-success { @apply text-green-600 text-sm; }
.bugwatch-feedback-error { @apply text-red-600 text-sm; }

Server-side feedback

You can also send feedback from Ruby (e.g. from a controller that handles your own form):

Bugwatch.send_feedback(
  params[:message],
  email: current_user.email,
  name:  current_user.name,
  url:   request.original_url
)

How it works

  1. Bugwatch::Middleware wraps your entire Rack stack.
  2. When an unhandled exception propagates out of a request, the middleware:
    • Captures the exception, full backtrace (with 3 lines of source context per in-app frame), request details, user context, and breadcrumbs.
    • POSTs the payload to your BugWatch instance in a background thread (fire-and-forget, 3s timeout).
    • Re-raises the exception so Rails error handling fires normally.
  3. Thread-local user context and breadcrumbs are cleared automatically after each request by the Rails around_action hook.

What gets sent

Field Description
exception.error_class Exception class name
exception.message Exception message
exception.backtrace Array of frames with file, line, method, in_app, source_context
request.* Method, URL, params (filtered), headers (filtered), IP
app.* Rails env, Ruby version, Rails version, git SHA, hostname
user.* ID, email, name, any custom fields
breadcrumbs Last 50 breadcrumbs with timestamp, type, message, metadata
duration_ms Request duration in milliseconds

Sensitive params (password, token, secret, key, auth, credit, card, cvv, ssn) are automatically filtered from request params and never sent.

Publishing

cd /home/max/bugwatch-ruby
gem build bugwatch-ruby.gemspec
gem signin
gem push bugwatch-ruby-0.1.0.gem