Tracelit Ruby SDK
Official Ruby SDK for Tracelit — drop-in OpenTelemetry instrumentation for Rails, Sinatra, and Rack apps. Sends traces, metrics, and logs to the Tracelit ingest API via OTLP/HTTP.
Requirements: Ruby >= 3.0
Set up with AI
Copy the prompt below and paste it into Cursor, Claude, ChatGPT, or any AI assistant. It contains everything the AI needs to fully integrate Tracelit into your app — gem, initializer, manual spans, custom metrics, and test guard.
You are integrating the Tracelit Ruby SDK into this codebase.
## What Tracelit does
Tracelit is a drop-in OpenTelemetry SDK that sends traces, metrics, and logs
to https://tracelit.io via OTLP/HTTP. It auto-instruments Rails, Sidekiq,
ActiveRecord, Redis, Faraday, Net::HTTP, and more with zero code changes.
## Steps
### 1. Add the gem
In Gemfile add:
gem "tracelit"
Then run: bundle install
### 2. Create the initializer
Create config/initializers/tracelit.rb with this content
(replace MY_SERVICE_NAME with the actual name of this service):
Tracelit.configure do |config|
config.api_key = ENV["TRACELIT_API_KEY"]
config.service_name = "MY_SERVICE_NAME"
config.environment = ENV.fetch("RAILS_ENV", "production")
config.sample_rate = 1.0
config.enabled = ENV["TRACELIT_ENABLED"] != "false"
end
For Sinatra/Rack apps also add Tracelit.start! after the configure block.
For Rails, the Railtie calls start! automatically — no extra line needed.
### 3. Disable in tests
In config/environments/test.rb (or .env.test) add:
TRACELIT_ENABLED=false
### 4. Add manual spans (optional)
Wrap any important operation with a custom span:
Tracelit.tracer.in_span("describe_the_operation") do |span|
span.set_attribute("relevant.attribute", value.to_s)
do_the_work
end
### 5. Add custom metrics (optional)
Use counters, histograms, or gauges for business-level signals:
# Counter — increment by 1 each time an event occurs
counter = Tracelit.metrics.counter("my.event.count",
description: "...", unit: "{events}")
counter.add(1, attributes: { "key" => "value" })
# Histogram — record a measured value (latency, size, etc.)
histogram = Tracelit.metrics.histogram("my.operation.duration",
description: "...", unit: "ms")
histogram.record(elapsed_ms, attributes: { "key" => "value" })
# Gauge — record a current level (queue depth, pool size, etc.)
gauge = Tracelit.metrics.gauge("my.queue.depth",
description: "...", unit: "{items}")
gauge.record(current_depth, attributes: { "queue" => "default" })
## What you get automatically (no code required)
- Traces for every HTTP request, SQL query, Redis call, Sidekiq job, etc.
- Metrics: http.server.request.count/duration, http.server.error.count,
db.query.duration, sidekiq.job.count/duration/error.count,
db.connection_pool.size/busy/idle/waiting, process.memory.rss
- Rails.logger lines forwarded to Tracelit logs, correlated to the active trace
- Error spans always exported even when the trace is outside the sample ratio
## Configuration reference
| Option | Env var | Default |
|--------------------|--------------------------|--------------------------------|
| api_key | TRACELIT_API_KEY | nil (required) |
| service_name | TRACELIT_SERVICE_NAME | Rails app name (required) |
| environment | TRACELIT_ENVIRONMENT | "production" |
| endpoint | TRACELIT_ENDPOINT | https://ingest.tracelit.app |
| sample_rate | TRACELIT_SAMPLE_RATE | 1.0 |
| enabled | TRACELIT_ENABLED | true |
| resource_attributes| — | {} (extra span/metric tags) |
Installation
Add to your Gemfile and run bundle install:
gem "tracelit"
Setup
Rails
Create config/initializers/tracelit.rb:
Tracelit.configure do |config|
config.api_key = ENV["TRACELIT_API_KEY"] # required
config.service_name = "payments-api" # required
config.environment = ENV["RAILS_ENV"]
config.sample_rate = 1.0
end
That is all. The Railtie picks up the configuration automatically and calls Tracelit.start! at boot — no further changes needed.
Sinatra / Rack
require "tracelit"
Tracelit.configure do |config|
config.api_key = ENV["TRACELIT_API_KEY"]
config.service_name = "my-sinatra-app"
config.environment = ENV["RACK_ENV"]
end
Tracelit.start! # must be called explicitly outside Rails
Configuration reference
All options can be set in the configure block or via environment variables.
| Option | Env variable | Default | Description |
|---|---|---|---|
api_key |
TRACELIT_API_KEY |
nil |
Required. Your Tracelit ingest API key. |
service_name |
TRACELIT_SERVICE_NAME |
Rails app name | Required. Name of this service as it appears in Tracelit. Falls back to the Rails application module name when inside Rails, or "unknown-service" otherwise. |
environment |
TRACELIT_ENVIRONMENT |
"production" |
Deployment environment tag — e.g. production, staging, development. |
endpoint |
TRACELIT_ENDPOINT |
https://ingest.tracelit.app |
Base URL of the Tracelit ingest API. Override only when self-hosting. |
sample_rate |
TRACELIT_SAMPLE_RATE |
1.0 |
Head-based trace sampling ratio between 0.0 and 1.0. 1.0 keeps every trace; 0.1 keeps 10%. Errors are always exported regardless of this setting. |
enabled |
TRACELIT_ENABLED |
true |
Set to false (or TRACELIT_ENABLED=false) to disable all telemetry without removing the gem — useful in test environments. |
resource_attributes |
— | {} |
Extra key/value pairs appended to every span, metric, and log record as resource attributes. |
Adding custom resource attributes
Tracelit.configure do |config|
config.api_key = ENV["TRACELIT_API_KEY"]
config.service_name = "orders-api"
config.resource_attributes = {
"deployment.region" => "us-east-1",
"team" => "platform",
}
end
Manual trace instrumentation
Use Tracelit.tracer to create custom spans around any block of work:
Tracelit.tracer.in_span("process_payment") do |span|
span.set_attribute("payment.id", payment.id.to_s)
span.set_attribute("payment.amount", amount)
span.set_attribute("payment.currency", currency)
result = process(payment)
span.set_attribute("payment.status", result.status)
result
end
The tracer is an OpenTelemetry::Trace::Tracer and supports the full OpenTelemetry Ruby API.
Manual metrics instrumentation
Access the metrics interface via Tracelit.metrics (an alias for Tracelit::Metrics):
Counter
Counts discrete events. Use for request counts, job completions, errors, etc.
counter = Tracelit.metrics.counter(
"orders.placed",
description: "Total orders placed",
unit: "{orders}"
)
counter.add(1, attributes: { "currency" => "USD", "channel" => "web" })
Histogram
Records distributions of values. Use for durations, payload sizes, queue depths, etc.
histogram = Tracelit.metrics.histogram(
"external.api.duration",
description: "External API call duration",
unit: "ms"
)
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
call_external_api
elapsed_ms = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - start) * 1000.0
histogram.record(elapsed_ms, attributes: { "service" => "stripe" })
Gauge
Records a point-in-time value. Use for pool sizes, queue lengths, cache hit rates, etc.
gauge = Tracelit.metrics.gauge(
"job_queue.depth",
description: "Number of pending background jobs",
unit: "{jobs}"
)
gauge.record(JobQueue.pending_count, attributes: { "queue" => "default" })
Automatic instrumentation
The SDK enables every instrumentation gem bundled in opentelemetry-instrumentation-all, including:
| Library | What is captured |
|---|---|
| Rails / Action Pack | HTTP request traces, controller and action attributes |
| Active Record | SQL query traces with sanitised statement text |
| Action View | Template render times |
| Rack | Low-level HTTP middleware spans |
| Net::HTTP | Outbound HTTP call traces |
| Faraday | Outbound HTTP call traces |
| Redis | Cache command traces |
| Sidekiq | Job enqueue and execute traces |
| Bunny | AMQP publish/subscribe traces |
| gRPC | Client and server RPC traces |
Additional libraries (Mongo, pg, mysql2, Kafka, etc.) are also instrumented when their gems are present.
Automatic metrics collection
Once Tracelit.start! has been called, the following metrics are collected with no additional configuration:
HTTP server metrics (Rails)
Emitted per request via ActiveSupport::Notifications:
| Metric | Type | Description |
|---|---|---|
http.server.request.count |
Counter | Total HTTP requests processed |
http.server.request.duration |
Histogram | Request duration in milliseconds |
http.server.error.count |
Counter | Total 5xx responses |
db.query.duration |
Histogram | ActiveRecord time per request in milliseconds |
Attributes on all HTTP metrics: http.method, http.route, http.status_code, controller, action.
Sidekiq job metrics
Emitted per job execution via server middleware:
| Metric | Type | Description |
|---|---|---|
sidekiq.job.count |
Counter | Total jobs processed |
sidekiq.job.duration |
Histogram | Job execution duration in milliseconds |
sidekiq.job.error.count |
Counter | Total jobs that raised an error |
Attributes: sidekiq.job.class, sidekiq.queue, sidekiq.status (success or error).
Database connection pool metrics (ActiveRecord)
Polled every 30 seconds on a background thread:
| Metric | Type | Description |
|---|---|---|
db.connection_pool.size |
Gauge | Maximum connections in the pool |
db.connection_pool.busy |
Gauge | Connections currently checked out |
db.connection_pool.idle |
Gauge | Connections available for checkout |
db.connection_pool.waiting |
Gauge | Threads waiting for a connection |
Process memory
Polled every 60 seconds:
| Metric | Type | Description |
|---|---|---|
process.memory.rss |
Gauge | Process RSS memory in megabytes |
Log forwarding (Rails)
When Rails is present, Tracelit.start! installs a broadcast target on Rails.logger. Every Rails.logger call is forwarded to the OTel LoggerProvider and exported to the Tracelit logs table via OTLP. The original logger output is preserved — nothing changes for your existing log pipeline.
Log records are automatically correlated with the active trace via trace_id and span_id.
Sampling and error guarantee
Set config.sample_rate below 1.0 to reduce trace volume in high-traffic environments:
config.sample_rate = 0.1 # keep 10% of traces
Error spans are always exported, even when the parent trace is outside the sample ratio. The SDK uses a custom ErrorAlwaysOnSampler + ErrorSpanProcessor pair to guarantee this — no configuration required.
Disabling in tests
# config/initializers/tracelit.rb
Tracelit.configure do |config|
config.api_key = ENV["TRACELIT_API_KEY"]
config.service_name = "my-app"
config.enabled = ENV["TRACELIT_ENABLED"] != "false"
end
Then in your test environment:
TRACELIT_ENABLED=false bundle exec rspec
Or set it permanently in config/environments/test.rb / .env.test:
TRACELIT_ENABLED=false
Running the SDK's own tests
bundle install
bundle exec rspec