💎 Ruby Integration Guide

Learn how to instrument your Ruby applications with OpenTelemetry to send distributed traces to TraceKit.

90% Automatic Tracing!

With the right gems, most of your application will be traced automatically with minimal setup. No need to manually instrument every controller or method.

📋

Prerequisites

  • • Ruby 2.7 or higher (Ruby 3.0+ recommended)
  • • An active TraceKit account
  • • A generated API key from the API Keys page

🔍 What Gets Traced Automatically?

With proper setup, these operations are traced automatically with zero manual instrumentation:

ComponentSetupAuto-Traced?
HTTP EndpointsRails/Sinatra/Rack instrumentation✓ Yes
ActiveRecord QueriesActiveRecord instrumentation✓ Yes
HTTP Client CallsNet::HTTP/Faraday instrumentation✓ Yes
Redis OperationsRedis instrumentation✓ Yes
Sidekiq JobsSidekiq instrumentation✓ Yes
Custom Business LogicManual spans (optional)Manual

📦 Installation

Add the required OpenTelemetry gems to your Gemfile:

# Gemfile
gem 'opentelemetry-sdk'
gem 'opentelemetry-exporter-otlp'
gem 'opentelemetry-instrumentation-rails'  # For Rails
gem 'opentelemetry-instrumentation-sinatra' # For Sinatra

# Then run:
bundle install

⚙️ Basic Setup

Create a tracing initialization file:

Create config/initializers/opentelemetry.rb

# config/initializers/opentelemetry.rb
require 'opentelemetry/sdk'
require 'opentelemetry/exporter/otlp'
require 'opentelemetry/instrumentation/all'

OpenTelemetry::SDK.configure do |c|
  c.service_name = ENV.fetch('SERVICE_NAME', 'my-rails-app')
  c.service_version = '1.0.0'

  # Use all available instrumentation
  c.use_all

  # Configure OTLP exporter
  c.add_span_processor(
    OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
      OpenTelemetry::Exporter::OTLP::Exporter.new(
        endpoint: "#{ENV.fetch('TRACEKIT_ENDPOINT', '{ appURL }')}/v1/traces",
        headers: { 'X-API-Key' => ENV.fetch('TRACEKIT_API_KEY') }
      )
    )
  )
end

🚀 Framework Integration

TraceKit works seamlessly with popular Ruby frameworks through OpenTelemetry instrumentation.

Ruby on Rails

# config/initializers/opentelemetry.rb already configured above

# Your controllers are automatically traced!
class UsersController < ApplicationController
  def index
    # This action is automatically traced!
    @users = User.all
    render json: @users
  end

  def create
    # This action is also automatically traced!
    @user = User.create!(user_params)
    render json: @user, status: :created
  end

  private

  def user_params
    params.require(:user).permit(:name, :email)
  end
end

Sinatra

# app.rb
require 'sinatra'
require 'opentelemetry/sdk'
require 'opentelemetry/exporter/otlp'
require 'opentelemetry/instrumentation/sinatra'

# Initialize OpenTelemetry
OpenTelemetry::SDK.configure do |c|
  c.service_name = 'my-sinatra-app'
  c.use 'OpenTelemetry::Instrumentation::Sinatra'

  c.add_span_processor(
    OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
      OpenTelemetry::Exporter::OTLP::Exporter.new(
        endpoint: "#{ENV['TRACEKIT_ENDPOINT']}/v1/traces",
        headers: { 'X-API-Key' => ENV['TRACEKIT_API_KEY'] }
      )
    )
  )
end

# Routes are automatically traced!
get '/api/users' do
  content_type :json
  User.all.to_json
end

Automatic Instrumentation Libraries

These libraries automatically create child spans for common operations. Set them up once, and every call is traced automatically.

ActiveRecord Queries

Automatically trace all database operations:

# ActiveRecord is automatically instrumented when you use c.use_all

# All queries are automatically traced!
User.all                    # Traced!
User.find(1)               # Traced!
User.where(active: true)   # Traced!
User.create(name: 'Alice') # Traced!

HTTP Client Calls

Automatically trace all outgoing HTTP requests:

# Net::HTTP is automatically instrumented when you use c.use_all

require 'net/http'

# All HTTP requests are automatically traced!
uri = URI('https://api.example.com/users')
response = Net::HTTP.get_response(uri)  # Traced!

Redis Operations

Trace Redis commands automatically:

# Add the Redis instrumentation gem
# gem 'opentelemetry-instrumentation-redis'

# Redis operations are automatically traced
redis = Redis.new(host: 'localhost', port: 6379)

redis.set('key', 'value')  # Traced!
redis.get('key')           # Traced!

🔧 Manual Instrumentation (Optional)

For custom business logic that isn't covered by auto-instrumentation libraries, you can manually create spans. This is optional and only needed for specific operations you want to measure.

def process_order(order_id)
  tracer = OpenTelemetry.tracer_provider.tracer('order-service')

  # Start a parent span
  tracer.in_span('process_order', attributes: { 'order.id' => order_id }) do |span|
    # Child spans automatically link to parent
    tracer.in_span('validate_order', attributes: { 'order.id' => order_id }) do
      # Validation logic here
    end

    tracer.in_span('charge_payment', attributes: { 'order.id' => order_id }) do
      # Payment logic here
    end

    span.set_attribute('order.status', 'completed')
  end
end

🔐 Environment Variables

Best practice: Store sensitive configuration in environment variables:

# .env
TRACEKIT_API_KEY=ctxio_your_generated_api_key_here
TRACEKIT_ENDPOINT={ appURL }
SERVICE_NAME=my-rails-app

🏭 Production Configuration

⚠️

Production Checklist

  • • Use HTTPS/TLS for the OTLP endpoint
  • • Store API keys in a secrets manager (AWS Secrets Manager, HashiCorp Vault)
  • • Set appropriate service names and versions
  • • Configure resource attributes (deployment.environment, host.name, etc.)
  • • Adjust sampling rates if needed for high-traffic services

🔧 Troubleshooting

Traces Not Appearing?

  1. Verify your API key is correct and not revoked
  2. Check the endpoint URL matches your TraceKit instance
  3. Ensure all required gems are installed
  4. Check application logs for OpenTelemetry errors
  5. Verify TraceKit is running and accessible

Complete Example

Here's a complete working Rails example:

# Complete Rails example

# config/initializers/opentelemetry.rb
require 'opentelemetry/sdk'
require 'opentelemetry/exporter/otlp'
require 'opentelemetry/instrumentation/all'

OpenTelemetry::SDK.configure do |c|
  c.service_name = ENV.fetch('SERVICE_NAME', 'rails-api')
  c.use_all  # Auto-instrument everything!

  c.add_span_processor(
    OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
      OpenTelemetry::Exporter::OTLP::Exporter.new(
        endpoint: "#{ENV.fetch('TRACEKIT_ENDPOINT', '{ appURL }')}/v1/traces",
        headers: { 'X-API-Key' => ENV.fetch('TRACEKIT_API_KEY') }
      )
    )
  )
end

# app/controllers/users_controller.rb
class UsersController < ApplicationController
  def index
    # Automatically traced - no code changes needed!
    @users = User.all
    render json: @users
  end

  def show
    # Automatically traced - no code changes needed!
    @user = User.find(params[:id])
    render json: @user
  end
end

# That's it! Your Rails app is fully traced.
🎉

You're all set!

Your Ruby application is now sending traces to TraceKit. Visit the Dashboard to see your traces.

🚀 Next Steps

  • Add auto-instrumentation libraries for components you use (Redis, Sidekiq, MongoDB, etc.)
  • Explore your traces on the Traces page to identify performance bottlenecks
  • Optionally add custom spans for specific business logic you want to measure
  • Configure sampling for high-traffic services to reduce overhead
  • Set up alert rules to get notified when issues occur