Skip to main content

Advanced Usage

Advanced patterns and features for the Ruby SDK.

Custom Transport

Use a custom HTTP client:
BrainzLab.configure do |config|
  config.transport = MyCustomTransport.new
end

class MyCustomTransport
  def send(endpoint, payload)
    # Custom HTTP logic
  end
end

Async Processing

Configure async behavior:
BrainzLab.configure do |config|
  # Use a background thread for sending
  config.async = true

  # Or use Sidekiq
  config.async_handler = ->(payload) {
    BrainzLabDeliveryJob.perform_async(payload)
  }
end

Custom Fingerprinting

Control error grouping:
BrainzLab.configure do |config|
  config.reflex_fingerprint = ->(event) {
    case event.exception
    when Stripe::CardError
      ["payment_failure", event.exception.code]
    when Net::TimeoutError
      ["timeout", event.extra[:endpoint]]
    else
      nil  # Use default
    end
  }
end

Multi-Tenant Applications

Isolate data per tenant:
class ApplicationController < ActionController::Base
  before_action :set_tenant_context

  private

  def set_tenant_context
    BrainzLab.set_context(tenant_id: current_tenant.id)
    BrainzLab.set_tags(tenant: current_tenant.slug)
  end
end

HTTP Instrumentation

Automatically track outgoing HTTP requests:
BrainzLab.configure do |config|
  config.instrument_http = true  # Enable HTTP tracking

  # Hosts to ignore (default: localhost, 127.0.0.1)
  config.http_ignore_hosts = ["localhost", "127.0.0.1", "internal.mycompany.com"]
end
When enabled, all Net::HTTP requests are automatically tracked:
  • Reflex breadcrumbs: Added to error context for debugging
  • Recall logs: Debug-level logs for observability
Each tracked request captures:
  • HTTP method and URL
  • Status code
  • Duration in milliseconds
  • Error class (for failed requests)
# Example breadcrumb added to Reflex:
{
  category: "http",
  message: "GET https://api.stripe.com/v1/charges",
  level: "info",  # or "error" for 4xx/5xx
  data: {
    method: "GET",
    url: "https://api.stripe.com/v1/charges",
    status_code: 200,
    duration_ms: 145.32
  }
}

Distributed Tracing

Propagate trace context:
# Outgoing request
headers = BrainzLab.inject_headers({})
response = HTTP.headers(headers).get(url)

# Incoming request (in middleware)
BrainzLab.extract_context(request.headers)

Performance Monitoring

Track custom metrics:
BrainzLab::Recall.time("database_query") do
  User.complex_query
end

BrainzLab::Recall.gauge("queue_size", Sidekiq::Queue.new.size)
BrainzLab::Recall.increment("api_calls", tags: { endpoint: "/users" })

Graceful Shutdown

Ensure logs are flushed on shutdown:
at_exit do
  BrainzLab::Recall.flush
end
The SDK automatically registers an at_exit handler to flush buffered logs.

Debug Mode

Enable debug logging:
BrainzLab.configure do |config|
  config.debug = true  # Logs SDK activity to STDOUT
end

Proxy Configuration

Use an HTTP proxy:
BrainzLab.configure do |config|
  config.proxy = {
    host: "proxy.example.com",
    port: 8080,
    user: "user",
    password: "pass"
  }
end

Rate Limiting

Handle rate limits gracefully:
BrainzLab.configure do |config|
  config.on_rate_limit = ->(retry_after) {
    Rails.logger.warn("BrainzLab rate limited, retry after #{retry_after}s")
  }
end

Custom Serialization

Control how data is serialized:
BrainzLab.configure do |config|
  config.serializer = ->(object) {
    case object
    when ActiveRecord::Base
      object.as_json(only: [:id, :created_at])
    else
      object
    end
  }
end

Middleware Order

Control middleware placement:
# config/application.rb
config.middleware.insert_before(
  ActionDispatch::ShowExceptions,
  BrainzLab::Middleware::ErrorHandler
)

Health Checks

Check SDK status:
status = BrainzLab.health_check
# => { connected: true, queue_size: 5, last_flush: Time.now }

Disable Specific Features

BrainzLab.configure do |config|
  config.recall_enabled = true
  config.reflex_enabled = false  # Only logging, no errors

  # Auto-instrumentation (off by default)
  config.instrument_http = true   # Track outgoing HTTP requests
  config.instrument_active_record = false  # Disable SQL query tracing
end