Skip to main content

Pulse - APM & Distributed Tracing

Pulse automatically instruments your Rails application to track performance and provide distributed tracing.

Automatic Instrumentation

Pulse automatically instruments these libraries when detected:
LibraryWhat’s Tracked
Rails/RackRequest duration, status, breakdown
Active RecordSQL queries, duration, query count
Net::HTTPOutbound HTTP requests
FaradayHTTP client requests
HTTPartyHTTP client requests
RedisRedis commands
SidekiqJob processing, queue wait time
Delayed::JobJob processing
GraphQLQuery execution, field resolution
GrapeAPI endpoint performance
MongoDBDatabase operations
ElasticsearchSearch operations
ActionMailerEmail delivery time

Configuration

config/initializers/brainzlab.rb
BrainzLab.configure do |config|
  config.secret_key = ENV['BRAINZLAB_SECRET_KEY']

  # Enable Pulse
  config.pulse_enabled = true

  # Sample rate (1.0 = 100%, 0.5 = 50%)
  config.pulse_sample_rate = 1.0

  # Exclude paths from tracing
  config.pulse_excluded_paths = ['/health', '/ping', '/up', '/assets']
end

Controlling Instrumentation

Enable or disable specific instrumentations:
BrainzLab.configure do |config|
  # Disable Redis instrumentation
  config.instrument_redis = false

  # Disable Sidekiq instrumentation
  config.instrument_sidekiq = false

  # Ignore specific hosts for HTTP
  config.http_ignore_hosts = ['localhost', '127.0.0.1', 'internal-api.local']

  # Ignore specific Redis commands
  config.redis_ignore_commands = ['ping', 'info', 'select']
end

Distributed Tracing

Pulse automatically propagates trace context across services using W3C Trace Context and B3 headers.

Extracting Context (Incoming)

Context is automatically extracted from incoming requests in Rails. For custom extraction:
# Extract from headers
context = BrainzLab::Pulse.extract!(request.headers)

if context.valid?
  puts "Parent trace: #{context.trace_id}"
  puts "Parent span: #{context.span_id}"
end

Injecting Context (Outgoing)

Context is automatically injected into outgoing HTTP requests. For custom injection:
headers = {}
BrainzLab::Pulse.inject!(headers)

# headers now contains:
# - traceparent (W3C)
# - X-B3-TraceId, X-B3-SpanId (B3)

Custom Spans

Add custom spans for operations you want to track:
BrainzLab::Pulse.trace("process_payment", kind: "payment") do |span|
  span[:data] = {
    amount: order.total,
    currency: "USD",
    gateway: "stripe"
  }

  process_payment(order)
end

Nested Spans

BrainzLab::Pulse.trace("checkout") do
  BrainzLab::Pulse.trace("validate_cart") do
    validate_cart(cart)
  end

  BrainzLab::Pulse.trace("process_payment") do
    charge_card(cart.total)
  end

  BrainzLab::Pulse.trace("send_confirmation") do
    OrderMailer.confirmation(order).deliver_later
  end
end

Sidekiq Integration

Sidekiq jobs are automatically traced with:
  • Job execution time
  • Queue wait time (time spent in queue)
  • Error tracking
  • Distributed trace context propagation
class ProcessOrderJob
  include Sidekiq::Job

  def perform(order_id)
    # Automatically traced
    order = Order.find(order_id)
    order.process!
  end
end
Trace context flows from web request → Sidekiq job automatically.

GraphQL Integration

For GraphQL-Ruby 2.0+, add the tracer to your schema:
class MySchema < GraphQL::Schema
  trace_with BrainzLab::Instrumentation::GraphQLInstrumentation::Tracer

  query QueryType
  mutation MutationType
end
This tracks:
  • Query execution time
  • Individual field resolution (fields taking >10ms)
  • Query complexity

Grape API Integration

For Grape APIs, use the middleware:
class API < Grape::API
  use BrainzLab::Instrumentation::GrapeInstrumentation::Middleware

  resource :users do
    get do
      User.all
    end
  end
end

Viewing Traces

View traces in the Pulse dashboard:
  • Request waterfall view
  • Span breakdown by type
  • Slow query detection
  • Error correlation

Sampling

For high-traffic applications, use sampling:
config.pulse_sample_rate = 0.1  # Sample 10% of requests
Errors are always captured regardless of sample rate.

Environment Variables

VariableDescription
PULSE_URLCustom Pulse endpoint (self-hosting)
BRAINZLAB_DEBUGEnable debug logging