Project

brainzlab

0.0
No release in over 3 years
Official Ruby SDK for BrainzLab observability platform. Includes Recall (structured logging), Reflex (error tracking), and Pulse (APM with distributed tracing). Auto-instruments Rails, Sidekiq, GraphQL, Redis, and more.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 13.0
~> 3.0
~> 3.0

Runtime

 Project Readme

BrainzLab Ruby SDK

Gem Version CI CodeQL codecov Docs License: OSAaSy

Official Ruby SDK for BrainzLab - the complete observability platform.

  • Recall - Structured logging
  • Reflex - Error tracking
  • Pulse - APM & distributed tracing

Installation

From RubyGems (recommended)

Add to your Gemfile:

gem 'brainzlab'

Then run:

bundle install

From GitHub Packages

Add the GitHub Packages source to your Gemfile:

source "https://rubygems.pkg.github.com/brainz-lab" do
  gem 'brainzlab'
end

Configure Bundler with your GitHub token:

bundle config set --global rubygems.pkg.github.com USERNAME:TOKEN

Quick Start

Get Your API Key

  1. Sign up at platform.brainzlab.ai
  2. Create or select a project
  3. Copy your API key (sk_live_xxx or sk_test_xxx)
  4. Set it as BRAINZLAB_SECRET_KEY environment variable

One key, all products: Your Platform API key works across Recall, Reflex, Pulse, and all BrainzLab products. No separate keys needed.

Configuration

# config/initializers/brainzlab.rb
BrainzLab.configure do |config|
  # Authentication (required) - Your Platform API key
  config.secret_key = ENV['BRAINZLAB_SECRET_KEY']

  # Environment
  config.environment = Rails.env
  config.service = 'my-app'

  # Enable/disable products
  config.recall_enabled = true   # Logging
  config.reflex_enabled = true   # Error tracking
  config.pulse_enabled = true    # APM

  # Auto-provisioning (creates projects automatically)
  config.recall_auto_provision = true
  config.reflex_auto_provision = true
  config.pulse_auto_provision = true
end

Recall - Structured Logging

# Log levels
BrainzLab::Recall.debug("Debug message", details: "...")
BrainzLab::Recall.info("User signed up", user_id: user.id)
BrainzLab::Recall.warn("Rate limit approaching", current: 95, limit: 100)
BrainzLab::Recall.error("Payment failed", error: e.message, amount: 99.99)
BrainzLab::Recall.fatal("Database connection lost")

# With context
BrainzLab::Recall.info("Order created",
  order_id: order.id,
  user_id: user.id,
  total: order.total,
  items: order.items.count
)

Configuration Options

config.recall_min_level = :info        # Minimum log level (:debug, :info, :warn, :error, :fatal)
config.recall_buffer_size = 50         # Batch size before flush
config.recall_flush_interval = 5       # Seconds between flushes

Reflex - Error Tracking

# Capture exceptions
begin
  risky_operation
rescue => e
  BrainzLab::Reflex.capture(e,
    user_id: current_user.id,
    order_id: order.id
  )
end

# Add breadcrumbs for context
BrainzLab::Reflex.add_breadcrumb("User clicked checkout",
  category: "ui.click",
  data: { button: "checkout" }
)

# Set user context
BrainzLab::Reflex.set_user(
  id: user.id,
  email: user.email,
  plan: user.plan
)

# Add tags
BrainzLab::Reflex.set_tags(
  environment: "production",
  region: "us-east-1"
)

Configuration Options

config.reflex_excluded_exceptions = ['ActiveRecord::RecordNotFound']
config.reflex_sample_rate = 1.0        # 1.0 = 100%, 0.5 = 50%
config.reflex_before_send = ->(event) {
  # Modify or filter events
  event[:tags][:custom] = 'value'
  event  # Return nil to drop the event
}

Pulse - APM & Distributed Tracing

Pulse automatically instruments your application to track performance.

Automatic Instrumentation

The SDK automatically instruments:

Library Description
Rails/Rack Request tracing with breakdown
Active Record SQL queries with timing
Net::HTTP Outbound HTTP calls
Faraday HTTP client requests
HTTParty HTTP client requests
Redis Redis commands
Sidekiq Background job processing
Delayed::Job Background job processing
GraphQL Query and field resolution
Grape API endpoint tracing
MongoDB Database operations
Elasticsearch Search operations
ActionMailer Email delivery

Configuration Options

# Enable/disable specific instrumentations
config.instrument_http = true           # Net::HTTP, Faraday, HTTParty
config.instrument_active_record = true  # SQL queries
config.instrument_redis = true          # Redis commands
config.instrument_sidekiq = true        # Sidekiq jobs
config.instrument_graphql = true        # GraphQL queries
config.instrument_mongodb = true        # MongoDB operations
config.instrument_elasticsearch = true  # Elasticsearch queries
config.instrument_action_mailer = true  # Email delivery
config.instrument_delayed_job = true    # Delayed::Job
config.instrument_grape = true          # Grape API

# Filtering
config.http_ignore_hosts = ['localhost', '127.0.0.1']
config.redis_ignore_commands = ['ping', 'info']
config.pulse_excluded_paths = ['/health', '/ping', '/up', '/assets']
config.pulse_sample_rate = 1.0          # 1.0 = 100%

Distributed Tracing

Pulse supports distributed tracing across services using W3C Trace Context and B3 propagation.

# Extracting trace context from incoming requests (automatic in Rails)
context = BrainzLab::Pulse.extract!(request.headers)

# Injecting trace context into outgoing requests (automatic with instrumentation)
BrainzLab::Pulse.inject!(headers)

Custom Spans

BrainzLab::Pulse.trace("process_payment", kind: "payment") do |span|
  span[:data] = { amount: 99.99, currency: "USD" }
  process_payment(order)
end

Rails Integration

The SDK automatically integrates with Rails when loaded:

  • Request context (request_id, path, method, params)
  • Exception reporting to Reflex
  • Performance tracing with Pulse
  • User context from current_user

Setting User Context

class ApplicationController < ActionController::Base
  before_action :set_brainzlab_context

  private

  def set_brainzlab_context
    if current_user
      BrainzLab.set_user(
        id: current_user.id,
        email: current_user.email,
        name: current_user.name
      )
    end
  end
end

Sidekiq Integration

For Sidekiq, the SDK automatically:

  • Traces job execution with queue wait time
  • Propagates trace context between web and worker
  • Captures job failures to Reflex
# config/initializers/sidekiq.rb
# Instrumentation is automatic, but you can configure:

BrainzLab.configure do |config|
  config.instrument_sidekiq = true
end

Grape API Integration

For Grape APIs, you can use the middleware:

class API < Grape::API
  use BrainzLab::Instrumentation::GrapeInstrumentation::Middleware

  # Your API endpoints...
end

GraphQL Integration

For GraphQL-Ruby 2.0+, add the tracer:

class MySchema < GraphQL::Schema
  trace_with BrainzLab::Instrumentation::GraphQLInstrumentation::Tracer

  # Your schema...
end

Environment Variables

Variable Description
BRAINZLAB_SECRET_KEY API key for authentication
BRAINZLAB_ENVIRONMENT Environment name (default: auto-detect)
BRAINZLAB_SERVICE Service name
BRAINZLAB_APP_NAME App name for auto-provisioning
BRAINZLAB_DEBUG Enable debug logging (true/false)
BRAINZLAB_MODE SDK mode: production (default) or development (offline)
BRAINZLAB_DEV_DB_PATH SQLite database path for development mode
RECALL_URL Custom Recall endpoint
REFLEX_URL Custom Reflex endpoint
PULSE_URL Custom Pulse endpoint

Scrubbing Sensitive Data

The SDK automatically scrubs sensitive fields:

config.scrub_fields = [:password, :password_confirmation, :token, :api_key, :secret]

Debug Mode

Debug mode provides detailed visibility into SDK operations, including all API requests and responses with timing information. This is invaluable for troubleshooting integration issues.

Enabling Debug Mode

# In your initializer
BrainzLab.configure do |config|
  config.debug = true
end

# Or via environment variable
# BRAINZLAB_DEBUG=true

Debug Output Format

When debug mode is enabled, you'll see colorized output in your terminal:

[BrainzLab] 12:34:56 -> Recall POST /api/v1/logs (count: 5)
[BrainzLab] 12:34:56 <- Recall 200 OK (45ms)

[BrainzLab] 12:34:57 -> Reflex POST /api/v1/errors (exception: RuntimeError)
[BrainzLab] 12:34:57 <- Reflex 201 Created (23ms)

[BrainzLab] 12:34:58 -> Pulse POST /api/v1/traces (name: GET /users)
[BrainzLab] 12:34:58 <- Pulse 200 OK (18ms)

The output includes:

  • Timestamp for each operation
  • Service name (Recall, Reflex, Pulse, etc.)
  • Request method and path
  • Payload summary (log count, exception type, etc.)
  • Response status code and message
  • Request duration with color coding (green < 100ms, yellow < 1s, red > 1s)

Custom Logger

You can provide your own logger to capture debug output:

BrainzLab.configure do |config|
  config.debug = true
  config.logger = Rails.logger
  # Or any Logger-compatible object
  config.logger = Logger.new('log/brainzlab.log')
end

Debug Callbacks

For advanced debugging and monitoring, you can hook into SDK operations:

BrainzLab.configure do |config|
  # Called before each API request
  config.on_send = ->(service, method, path, payload) {
    Rails.logger.debug "[BrainzLab] Sending to #{service}: #{method} #{path}"

    # You can use this to:
    # - Log all outgoing requests
    # - Send metrics to your monitoring system
    # - Add custom tracing
  }

  # Called when an SDK error occurs
  config.on_error = ->(error, context) {
    Rails.logger.error "[BrainzLab] Error in #{context[:service]}: #{error.message}"

    # You can use this to:
    # - Alert on SDK failures
    # - Track error rates
    # - Fallback to alternative logging

    # Note: This is for SDK errors, not application errors
    # Application errors are sent to Reflex as normal
  }
end

Programmatic Debug Logging

You can also use the Debug module directly:

# Log a debug message (only outputs when debug=true)
BrainzLab::Debug.log("Custom message", level: :info)
BrainzLab::Debug.log("Something went wrong", level: :error, error_code: 500)

# Measure operation timing
BrainzLab::Debug.measure(:custom, "expensive_operation") do
  # Your code here
end

# Check if debug mode is enabled
if BrainzLab::Debug.enabled?
  # Perform additional debug operations
end

Debug Output Levels

Debug messages are color-coded by level:

  • DEBUG (gray) - Verbose internal operations
  • INFO (cyan) - Normal operations
  • WARN (yellow) - Potential issues
  • ERROR (red) - Failed operations

Development Mode

Development mode allows you to use the SDK without a BrainzLab server connection. Events are logged to stdout in a readable format and stored locally in a SQLite database.

Configuration

# config/initializers/brainzlab.rb
BrainzLab.configure do |config|
  # Enable development mode (works offline)
  config.mode = :development

  # Optional: customize the SQLite database path (default: tmp/brainzlab.sqlite3)
  config.development_db_path = 'tmp/brainzlab_dev.sqlite3'

  # Other settings still apply
  config.environment = Rails.env
  config.service = 'my-app'
end

Or use the environment variable:

export BRAINZLAB_MODE=development

Features

In development mode:

  • No server connection required - Works completely offline
  • Stdout logging - All events are pretty-printed to the console with colors
  • Local storage - Events are stored in SQLite at tmp/brainzlab.sqlite3
  • Queryable - Use BrainzLab.development_events to query stored events

Querying Events

# Get all events
events = BrainzLab.development_events

# Filter by service
logs = BrainzLab.development_events(service: :recall)
errors = BrainzLab.development_events(service: :reflex)
traces = BrainzLab.development_events(service: :pulse)

# Filter by event type
BrainzLab.development_events(event_type: 'log')
BrainzLab.development_events(event_type: 'error')
BrainzLab.development_events(event_type: 'trace')

# Filter by time
BrainzLab.development_events(since: 1.hour.ago)

# Limit results
BrainzLab.development_events(limit: 10)

# Combine filters
BrainzLab.development_events(
  service: :recall,
  since: 30.minutes.ago,
  limit: 50
)

# Get stats by service
BrainzLab.development_stats
# => { recall: 42, reflex: 3, pulse: 15 }

# Clear all stored events
BrainzLab.clear_development_events!

Console Output

In development mode, events are pretty-printed to stdout:

[14:32:15.123] [RECALL] log [INFO] User signed up
  user_id: 123
  data: {email: "user@example.com"}

[14:32:16.456] [REFLEX] error RuntimeError: Something went wrong
  error_class: "RuntimeError"
  environment: "development"
  request_id: "abc-123"

[14:32:17.789] [PULSE] trace GET /users (45.2ms)
  request_method: "GET"
  request_path: "/users"
  status: 200
  db_ms: 12.3

Use Cases

Development mode is useful for:

  • Local development without setting up a BrainzLab account
  • Testing SDK integration in CI/CD pipelines
  • Debugging to inspect exactly what events would be sent
  • Offline development when working without internet access

Self-Hosted

For self-hosted BrainzLab installations:

BrainzLab.configure do |config|
  config.recall_url = 'https://recall.your-domain.com'
  config.reflex_url = 'https://reflex.your-domain.com'
  config.pulse_url = 'https://pulse.your-domain.com'
end

Documentation

Full documentation: docs.brainzlab.ai

Related

Contributors

Thanks to all our contributors! See all-contributors for how to add yourself.

License

OSAaSy License - see LICENSE for details.