Follow the Journey
3 min read

The Rails SDK

One gem, full observability

I hate complex integrations.

"Add this initializer. Configure this middleware. Wrap your controllers. Instrument your models. Don't forget the background job adapter."

By the time you're done, you've touched 15 files and you're not sure it's working.

The Brainz Lab Rails SDK is different.

One gem

# Gemfile
gem 'brainzlab'

That's it. One gem.

One initializer

# config/initializers/brainzlab.rb
BrainzLab.configure do |config|
  config.api_key = ENV["BRAINZLAB_API_KEY"]
end

That's it. One file.

Everything works

Logs flow to Recall. Automatic. Your existing Rails.logger calls just work.

Errors flow to Reflex. Automatic. Unhandled exceptions get captured with full context.

Traces flow to Pulse. Automatic. Every request, every query, every external call.

Metrics flow to Flux. Automatic. Request counts, response times, queue depths.

Zero code changes to your application.

How it works

The SDK hooks into Rails' instrumentation system. ActiveSupport::Notifications already fires events for everything:

  • process_action.action_controller — Request handling
  • sql.active_record — Database queries
  • render_template.action_view — View rendering
  • perform.active_job — Background jobs

We subscribe to these events. Package the data. Send it to the right product.

Your code doesn't change. The observability just appears.

What gets captured

Every request:
- Controller and action
- Parameters (filtered for security)
- Response status
- Total duration
- Database time
- View rendering time

Every query:
- SQL text
- Execution time
- Rows returned
- Call location

Every error:
- Exception class and message
- Full backtrace
- Request context
- User context (if configured)

Every background job:
- Job class
- Queue name
- Arguments
- Duration
- Success/failure

Custom tracking

Need more than automatic instrumentation?

# Track custom events
BrainzLab.track("user_signed_up", user_id: user.id, plan: "pro")

# Track custom metrics
BrainzLab.gauge("active_connections", pool.size)

# Add context to errors
BrainzLab.set_user(id: user.id, email: user.email)

# Create custom spans
BrainzLab.span("external_api_call") do
  ExternalService.fetch(params)
end

Simple methods. Obvious behavior.

Performance

The SDK is designed for production:

Async sending — Data ships in background threads. Your requests don't wait.

Batching — Events batch together. Fewer HTTP calls.

Sampling — High-volume apps can sample traces. Keep costs down.

Circuit breaker — If Brainz Lab is down, your app isn't affected.

Overhead is negligible. We've measured it.

The developer experience

Install the gem. Set the API key. Deploy.

Open Recall—your logs are there.
Open Reflex—your errors are there.
Open Pulse—your traces are there.

No "is it working?" uncertainty. Immediate visibility.

Try it

# Gemfile
gem 'brainzlab'

# .env
BRAINZLAB_API_KEY=sk_live_your_key

# That's it
bundle install
rails server

Make a request. Watch the data flow.

This is what observability should feel like.

— Andres

All posts Follow along

Want to follow the journey?

Get Updates