Ruby Integration Guide
Add TraceKit to your Ruby applications for automatic distributed tracing. Debug production Ruby services with live breakpoints and Rails/Sinatra support.
Learn how to instrument your Ruby applications with the TraceKit Ruby SDK for distributed tracing, metrics, and code monitoring.
Let AI set up TraceKit for you -- AI assistants can guide you through the entire setup process. Try AI Setup
Prerequisites
- Ruby 2.7 or higher (Ruby 3.0+ recommended)
- A TraceKit account (create one free)
- 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:
| Component | Span Type | Captured Attributes | Auto-Traced? |
|---|---|---|---|
| HTTP Endpoints | SERVER | method, route, status_code, duration, client_ip | Yes |
| ActiveRecord Queries | DB | db.system, db.statement, db.name, duration | Yes |
| HTTP Client Calls | CLIENT | method, url, status_code, duration, peer.service | Yes |
| Redis Operations | DB | db.system (redis), db.statement, duration | Yes |
| Sidekiq Jobs | Custom | job.class, job.id, queue, duration | Yes |
| Custom Business Logic | Custom | user-defined attributes | Manual |
Installation
Add the TraceKit Ruby SDK to your Gemfile:
# Gemfile
gem 'tracekit'
# Then run:
bundle installBasic Setup
Rails Applications (Auto-Configuration via .env)
For Rails applications, TraceKit automatically configures itself using environment variables:
# .env file
TRACEKIT_API_KEY=ctxio_abc123...
TRACEKIT_ENDPOINT=https://app.tracekit.dev
TRACEKIT_SERVICE_NAME=my-rails-app
TRACEKIT_ENVIRONMENT=production
TRACEKIT_CODE_MONITORING=true
# That's it! The TraceKit Railtie automatically:
# - Loads configuration from ENV variables
# - Initializes OpenTelemetry with OTLP exporters
# - Adds Rack middleware for request instrumentation
# - Sets up graceful shutdownNon-Rails Applications (Manual Configuration)
For non-Rails applications, configure the SDK manually:
require 'tracekit'
# Configure the SDK
Tracekit.configure do |config|
config.api_key = ENV['TRACEKIT_API_KEY']
config.service_name = 'my-service'
config.endpoint = 'https://app.tracekit.dev'
config.environment = 'production'
config.enable_code_monitoring = true
end
# For Rack applications, add middleware
use Tracekit::Middleware
# At application shutdown
at_exit { Tracekit.shutdown }Verify It Works -- Start your application and make a few requests. Then open the Traces page in your TraceKit dashboard. You should see:
- SERVER spans for each incoming request to Rails routes
- CLIENT spans for outgoing HTTP calls (if using Net::HTTP/Faraday instrumentation)
- DB spans for ActiveRecord queries (if instrumented)
Traces typically appear within 30 seconds. If you don't see them, check the Troubleshooting section.
Framework Integration
TraceKit SDK provides first-class support for popular Ruby frameworks with automatic instrumentation.
Ruby on Rails
# Your controllers are automatically traced!
class UsersController < ApplicationController
def index
# This action is automatically traced!
@users = User.all
render json: @users
end
def create
sdk = Tracekit.sdk
# Track metrics
sdk.counter("user.created").add(1)
# Capture snapshot with context
sdk.capture_snapshot("user-create", {
email: params[:email],
name: params[:name]
})
@user = User.create!(user_params)
render json: @user, status: :created
end
private
def user_params
params.require(:user).permit(:name, :email)
end
endSinatra
# app.rb
require 'sinatra'
require 'tracekit'
# Configure TraceKit
Tracekit.configure do |config|
config.api_key = ENV['TRACEKIT_API_KEY']
config.service_name = 'my-sinatra-app'
config.endpoint = 'https://app.tracekit.dev'
end
# Add TraceKit middleware
use Tracekit::Middleware
# Routes are automatically traced!
get '/api/users' do
sdk = Tracekit.sdk
# Track metrics
sdk.counter("api.users.requests").add(1)
content_type :json
User.all.to_json
endAutomatic 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 by TraceKit
# 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 by TraceKit
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:
# Redis operations are automatically traced by TraceKit
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)
sdk = Tracekit.sdk
# Capture snapshot at key moments
sdk.capture_snapshot("order-processing-start", {
orderId: order_id,
status: "processing"
})
# Track metrics
sdk.counter("orders.processed").add(1)
sdk.gauge("orders.active").inc
# Validation logic here...
# Track duration
start_time = Time.now
result = charge_payment(order_id)
duration_ms = ((Time.now - start_time) * 1000).round(2)
sdk.histogram("order.payment.duration").record(duration_ms)
# Capture completion snapshot
sdk.capture_snapshot("order-processing-complete", {
orderId: order_id,
status: "completed",
duration: duration_ms
})
sdk.gauge("orders.active").dec
endSDK.current API
Access the configured SDK singleton from anywhere in your application:
| Method | Parameters | Returns | Description |
|---|---|---|---|
SDK.current | none | SDK | Returns the current SDK singleton instance. Use after SDK.configure(). |
SDK.current Example
# After configuration:
Tracekit::SDK.configure(config)
# Access anywhere in your application:
sdk = Tracekit::SDK.current
sdk.capture_snapshot("checkout", { order_id: order.id, total: total })
sdk.counter("orders.processed").incSupporting Types
Internal and advanced types used by the SDK (not intended for direct use):
| Symbol | Type | Description |
|---|---|---|
EndpointResolver | Class (Internal) | Resolves API endpoint URLs. Handles protocol selection and path construction. |
LocalUI::Detector | Class (Internal) | Detects when TraceKit Local UI is running on the configured port. |
Security::Detector | Class (Advanced) | Detects PII and credentials in snapshot variables. Automatically applied during capture. |
Snapshots::Client | Class (Internal) | Used for breakpoint polling and snapshot transmission. Use capture_snapshot() instead. |
Code Monitoring (Live Debugging)
Production-Safe Live Debugging -- Capture variable state, stack traces, and request context at any point in your code without redeployment. Perfect for debugging production issues! Full Code Monitoring Documentation
Enable Code Monitoring
Enable code monitoring when initializing TraceKit:
# config/initializers/tracekit.rb
Tracekit::SDK.configure do |c|
c.api_key = ENV['TRACEKIT_API_KEY']
c.service_name = "my-rails-app"
c.enable_code_monitoring = true # defaults to true in Ruby SDK
endCode monitoring defaults to true in the Ruby SDK. The snippet above is shown for clarity -- you can omit enable_code_monitoring and it will be enabled automatically.
Capture Snapshots
Use capture_snapshot to capture variable state at specific points:
# In a Rails controller
class OrdersController < ApplicationController
def create
order = Order.new(order_params)
user = current_user
# Instance method -- capture via the SDK singleton
sdk = Tracekit::SDK.current
sdk.capture_snapshot('order-create', {
order_id: order.id,
total: order.total,
user_id: user.id,
items: order.line_items.count
})
# Module convenience method -- same result, shorter syntax
Tracekit.capture_snapshot('order-validate', {
valid: order.valid?,
errors: order.errors.full_messages
})
if order.save
redirect_to order_path(order)
else
render :new
end
end
endFeatures
- Auto-Registration -- Breakpoints automatically created on first
capture_snapshotcall - Variable Capture -- Deep inspection of hashes, arrays, and Ruby objects
- Stack Traces -- Full call stack with file and line numbers via
caller_locations - Request Context -- HTTP method, route, headers, and query params from Rack env
Production Safety
The Ruby SDK v6.0 includes multiple layers of production safety built into code monitoring:
- PII Scrubbing -- 13 built-in patterns via
Security::Patterns. Enabled by default with typed[REDACTED:type]markers for auditability. - Crash Isolation --
begin/rescueon all entry points. Snapshot failures never propagate to application code. - Circuit Breaker -- 3 failures in 60s triggers a 5-minute cooldown.
Mutex-based thread safety for concurrent environments. - Remote Kill Switch -- Dashboard toggle to disable code monitoring instantly. Propagates to all SDK instances via SSE (
Net::HTTPstreaming in daemon thread).
Real-Time Updates -- The Ruby SDK receives configuration changes (kill switch, breakpoint updates) in real time via Server-Sent Events (SSE). The SSE connection uses Net::HTTP streaming in a daemon thread, so it does not block your application and is automatically cleaned up when the process exits.
Code Monitoring API
| Method | Parameters | Returns | Description |
|---|---|---|---|
sdk.capture_snapshot(label, vars) | label: String, vars: Hash | nil | Capture variable state at this point. Only fires when a breakpoint is active. |
Tracekit.capture_snapshot(label, vars) | label: String, vars: Hash | nil | Module-level convenience method. Delegates to SDK.current.capture_snapshot. |
capture_depth | Integer | Default: 3 | Maximum depth for nested object inspection. |
max_payload | Integer (bytes) | Default: 65536 | Maximum size of a single snapshot payload. |
capture_timeout | Float (seconds) | Default: 5.0 | Timeout for snapshot capture and transmission. |
pii_scrubbing | Boolean | Default: true | Enable PII scrubbing via Security::Patterns. |
circuit_breaker | Hash | Default: { threshold: 3, window: 60, cooldown: 300 } | Circuit breaker configuration. |
End-to-End Workflow
- Enable Code Monitoring -- Defaults to enabled in the Ruby SDK. Explicitly set for clarity or use
TRACEKIT_CODE_MONITORING=true. - Add Capture Points -- Place
capture_snapshotcalls at code paths you want to debug. - Deploy and Verify Traces -- Deploy and check the Traces dashboard.
- Navigate to Code Monitoring -- Go to /snapshots and click "Browse Code".
- Set Breakpoints -- Auto-registered on first
capture_snapshotcall, or manually via the UI. - Trigger a Capture -- Make a request that hits a code path with
capture_snapshot. - View Snapshot -- Inspect variables, call stack, request context, security flags, and trace link.
LLM Instrumentation
TraceKit automatically instruments OpenAI and Anthropic API calls when detected. LLM calls appear as spans with OTel GenAI semantic convention attributes.
Zero-config auto-instrumentation -- If the openai or anthropic gem is installed, TraceKit patches them automatically via Module#prepend at init. No code changes required.
Captured Attributes
| Attribute | Description |
|---|---|
gen_ai.system | Provider name (openai, anthropic) |
gen_ai.request.model | Model name (gpt-4o, claude-sonnet-4-20250514, etc.) |
gen_ai.usage.input_tokens | Prompt token count |
gen_ai.usage.output_tokens | Completion token count |
gen_ai.response.finish_reasons | Finish reason (stop, end_turn, tool_calls) |
Configuration
Tracekit.configure do |c|
c.api_key = ENV['TRACEKIT_API_KEY']
c.service_name = 'my-ruby-service'
c.llm.enabled = true # Master toggle
c.llm.openai = true # OpenAI instrumentation
c.llm.anthropic = true # Anthropic instrumentation
c.llm.capture_content = false # Capture prompts/completions (off by default)
endEnvironment Variable Override
Use TRACEKIT_LLM_CAPTURE_CONTENT=true to enable prompt/completion capture without code changes. Useful for enabling in staging but not production.
Streaming Support
Streaming responses produce a single span that covers the entire stream. Token counts are accumulated from the final chunk. No special configuration needed.
LLM Dashboard
View LLM cost, token usage, and latency metrics on the dedicated LLM Observability dashboard at /ai/llm in your TraceKit instance.
Environment Variables
Best practice: Store sensitive configuration in environment variables:
# .env
TRACEKIT_API_KEY=ctxio_your_generated_api_key_here
TRACEKIT_ENDPOINT=https://app.tracekit.dev
TRACEKIT_SERVICE_NAME=my-rails-app
TRACEKIT_ENVIRONMENT=production
TRACEKIT_CODE_MONITORING=trueConfig Fields Reference
| Field | Type | Default | Description |
|---|---|---|---|
api_key | String | required | Your TraceKit API key for authentication |
service_name | String | "ruby-app" | Name of your service in the trace dashboard |
endpoint | String | "app.tracekit.dev" | TraceKit collector endpoint URL |
enabled | Boolean | true | Enable or disable tracing globally |
sample_rate | Float | 1.0 | Trace sampling rate (0.0 to 1.0) |
enable_code_monitoring | Boolean | false | Enable live code debugging / snapshot capture |
These fields are set via Config.build { |c| c.api_key = '...' } block syntax or through the Tracekit.configure block.
Environment Variable Reference
| Option | Type | Default | Env Variable | Description |
|---|---|---|---|---|
api_key | String | required | TRACEKIT_API_KEY | Your TraceKit API key for authentication |
service_name | String | required | TRACEKIT_SERVICE_NAME | Name of your service in the trace dashboard |
endpoint | String | "app.tracekit.dev" | TRACEKIT_ENDPOINT | TraceKit collector endpoint URL |
use_ssl | Boolean | true | TRACEKIT_USE_SSL | Enable TLS for the exporter connection |
environment | String | "production" | TRACEKIT_ENVIRONMENT | Deployment environment |
service_version | String | "1.0.0" | TRACEKIT_SERVICE_VERSION | Version of your service |
enable_code_monitoring | Boolean | true | TRACEKIT_CODE_MONITORING_ENABLED | Enable live code debugging |
code_monitoring_poll_interval | Integer | 30 | TRACEKIT_CODE_MONITORING_POLL_INTERVAL | How often to poll for active breakpoints (seconds) |
local_ui_port | Integer | 9999 | TRACEKIT_LOCAL_UI_PORT | Port for the local development UI |
sampling_rate | Float | 1.0 | TRACEKIT_SAMPLE_RATE | Trace sampling rate (0.0 to 1.0) |
The Ruby SDK does not auto-read environment variables. Read them with ENV['TRACEKIT_*'] and pass to the builder.
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?
Cause: The SDK is not initialized or required gems are missing.
Fix:
- Verify
Tracekit.configureblock is called at application startup (in an initializer for Rails) - Check that api_key is set
- Look for errors in application logs
- Confirm
sampling_rateis not 0
Missing gem errors?
Cause: Ruby OTel gems must be explicitly listed in the Gemfile.
Fix:
- Add all required gems:
gem 'tracekit',gem 'opentelemetry-api',gem 'opentelemetry-sdk', and any instrumentation gems - Run
bundle install - Verify with
bundle list | grep opentelemetry
Code monitoring not working?
Cause: The capture_snapshot method is not being called or permissions are insufficient.
Fix:
- Code monitoring defaults to
truein the Ruby SDK - Add
Tracekit.capture_snapshot('label')calls in your code - Reduce
code_monitoring_poll_intervalto 5 for testing - Verify API key permissions in the dashboard
Authentication errors (401/403)?
Cause: API key is missing, empty, or invalid.
Fix:
- Verify with
puts ENV['TRACEKIT_API_KEY']in Rails console - Ensure no extra whitespace:
api_key: ENV['TRACEKIT_API_KEY']&.strip - Regenerate key in dashboard if expired
Connection refused errors?
Cause: The TraceKit endpoint is unreachable or SSL configuration is wrong.
Fix:
- Test with
curl -X POST https://app.tracekit.dev/v1/traces(expect 401) - Verify
use_ssl: true(default) for production - For local development without TLS, set
use_ssl: false - Check that
endpointdoes not include the protocol prefix ifuse_sslis being used
Complete Example
Here's a complete working Rails example:
# Complete Rails example with TraceKit SDK
# Gemfile
gem 'tracekit'
# .env
TRACEKIT_API_KEY=ctxio_your_generated_api_key_here
TRACEKIT_ENDPOINT=https://app.tracekit.dev
TRACEKIT_SERVICE_NAME=rails-api
TRACEKIT_ENVIRONMENT=production
TRACEKIT_CODE_MONITORING=true
# 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
def create
sdk = Tracekit.sdk
# Track metrics
sdk.counter("users.created").add(1)
# Capture snapshot for debugging
sdk.capture_snapshot("user-creation", {
email: params[:email],
name: params[:name]
})
@user = User.create!(user_params)
render json: @user, status: :created
end
private
def user_params
params.require(:user).permit(:name, :email)
end
end
# That's it! Your Rails app now has:
# - Distributed tracing with automatic span creation
# - Metrics collection (counters, gauges, histograms)
# - Code monitoring with non-breaking snapshotsYou're all set! Your Ruby application is now sending traces to TraceKit. Visit the Dashboard to see your traces.
Custom Metrics
The TraceKit Ruby SDK includes a lightweight metrics API for tracking counters, gauges, and histograms.
Counter
Track monotonically increasing values (requests, events):
sdk = Tracekit.sdk
# Create a counter with tags
counter = sdk.counter("http.requests.total", {
service: "api",
endpoint: "/users"
})
# Increment the counter
counter.add(1)
counter.add(5) # Add specific valueGauge
Track values that can go up or down (queue size, connections):
sdk = Tracekit.sdk
# Create a gauge
gauge = sdk.gauge("memory.usage.bytes")
# Set absolute value
gauge.set(1024 * 1024 * 512) # 512 MB
# Increment/decrement
gauge.inc # +1
gauge.inc(10) # +10
gauge.dec # -1
gauge.dec(5) # -5Histogram
Track value distributions (latencies, sizes):
sdk = Tracekit.sdk
# Create a histogram with tags
histogram = sdk.histogram("http.request.duration", {
unit: "ms"
})
# Record values
histogram.record(123.45)
histogram.record(67.89)Metrics are automatically buffered and exported via OTLP. View them in the Metrics Explorer.
Migrating from OpenTelemetry
TraceKit wraps OpenTelemetry internally, so you get the same standards-based trace data with significantly less setup code.
Before vs After
Before: Raw OpenTelemetry (~15 lines):
require 'opentelemetry/sdk'
require 'opentelemetry-exporter-otlp'
OpenTelemetry::SDK.configure do |c|
c.service_name = 'my-service'
c.add_span_processor(
OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
OpenTelemetry::Exporter::OTLP::Exporter.new(
endpoint: 'https://api.tracekit.io/v1/traces',
headers: { 'Authorization' => "Bearer #{api_key}" }
)
)
)
c.use_all # auto-instrumentation
endAfter: TraceKit SDK (4 lines):
# Rails: just set .env vars (auto-configured via Railtie)
# TRACEKIT_API_KEY=your-api-key
# TRACEKIT_SERVICE_NAME=my-service
# Non-Rails:
Tracekit.configure do |c|
c.api_key = ENV['TRACEKIT_API_KEY']
c.service_name = 'my-service'
endMigration Steps
- Add the gem:
bundle add tracekit - Replace init code: Remove the
OpenTelemetry::SDK.configureblock and replace withTracekit.configure - For Rails: Set
TRACEKIT_API_KEYandTRACEKIT_SERVICE_NAMEin.env-- auto-configured via Railtie - Remove OTel gems:
bundle remove opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp - Verify: Start your app and check the Traces page for incoming data
Key Migration Benefits:
- 15 lines to 4 lines -- no more boilerplate for exporters, processors, resources
- No OTel dependency management -- TraceKit handles version pinning internally
- Built-in code monitoring -- not available with raw OpenTelemetry
- Built-in security scanning -- automatic variable redaction on snapshots
- Rails auto-configuration -- Railtie handles setup from .env vars automatically
Performance Overhead
TraceKit is built on OpenTelemetry's efficient batch processing pipeline. The SDK adds minimal overhead to your Ruby application.
| Metric | Impact | Details |
|---|---|---|
| Request Tracing | < 2ms per request | Spans are batched and exported asynchronously |
| Code Monitoring (Idle) | Zero overhead | No performance impact when no active breakpoints |
| Code Monitoring (Capture) | < 5ms per snapshot | Includes variable serialization and security scanning |
| Memory Footprint | ~15-25 MB | SDK runtime and span buffer |
| SDK Initialization | < 300ms one-time | Includes OpenTelemetry provider setup and auto-instrumentation |
Performance characteristics are typical for production workloads and may vary with application complexity, request volume, and number of instrumented libraries. Use sampling configuration to reduce overhead in high-traffic services.
Best Practices
DO:
- For Rails, rely on Railtie auto-init -- just add the gem and configure via environment variables
- For non-Rails apps (Sinatra), init in
config.rubeforerun - Use environment variables for API keys -- store in
TRACEKIT_API_KEYrather than hardcoding - Enable code monitoring in staging first before production
- Use sampling in high-traffic services -- set
TRACEKIT_SAMPLING_RATEbelow 1.0 - Set meaningful service names for easy identification in the trace viewer
DON'T:
- Call
Tracekit.configurein Rails apps -- the Railtie handles initialization automatically - Create spans for every function -- trace boundaries like HTTP handlers, DB calls, and external services
- Add high-cardinality attributes -- avoid user IDs, request IDs, or session tokens as span attributes
- Disable TLS in production -- the
TRACEKIT_INSECUREflag is for local development only
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
Java Integration Guide
Add TraceKit to Java applications for distributed tracing and live debugging. Monitor Spring Boot, Micronaut, and Java microservices with production-safe breakpoints.
.NET / C# Integration Guide
Learn how to integrate TraceKit with .NET and ASP.NET Core. Automatic distributed tracing with OpenTelemetry for debugging production C# applications.