> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tracelit.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Ruby SDK

> Zero-touch OpenTelemetry instrumentation for Rails, Sinatra, and Rack apps. Drop in the gem and Tracelit wires up traces, metrics, and logs — including Sidekiq, ActiveRecord, and Redis — automatically.

<Note>
  **Requirements:** Ruby ≥ 3.0
</Note>

***

## Installation

Add to your `Gemfile`:

```ruby Gemfile theme={null}
gem "tracelit"
```

Then run:

```bash theme={null}
bundle install
```

***

## Quick start

<Tabs>
  <Tab title="Rails">
    <Steps>
      <Step title="Create an initializer">
        ```ruby config/initializers/tracelit.rb theme={null}
        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
        ```
      </Step>

      <Step title="You're done">
        The Railtie picks up the configuration automatically and calls `Tracelit.start!` at boot. No further changes needed.
      </Step>
    </Steps>
  </Tab>

  <Tab title="Sinatra / Rack">
    <Steps>
      <Step title="Require and configure">
        ```ruby app.rb theme={null}
        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
        ```
      </Step>
    </Steps>
  </Tab>
</Tabs>

***

## 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.** Service name shown in Tracelit                 |
| `environment`         | `TRACELIT_ENVIRONMENT`  | `"production"`                | Deployment environment tag                                   |
| `endpoint`            | `TRACELIT_ENDPOINT`     | `https://ingest.tracelit.app` | Override only when self-hosting                              |
| `sample_rate`         | `TRACELIT_SAMPLE_RATE`  | `1.0`                         | Head-based sampling ratio `0.0`–`1.0`. Errors always export. |
| `enabled`             | `TRACELIT_ENABLED`      | `true`                        | Set `false` to disable all telemetry                         |
| `resource_attributes` | —                       | `{}`                          | Extra key/value pairs on every span, metric, and log         |

### Custom resource attributes

```ruby theme={null}
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
```

***

## Tracing

### Manual spans

`Tracelit.tracer` is an `OpenTelemetry::Trace::Tracer` and supports the full OpenTelemetry Ruby API.

```ruby theme={null}
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
```

### Nesting spans

```ruby theme={null}
Tracelit.tracer.in_span("checkout") do |checkout_span|
  checkout_span.set_attribute("cart.items", cart.size)

  Tracelit.tracer.in_span("validate-inventory") do |inv_span|
    validate_inventory!(cart)
  end

  Tracelit.tracer.in_span("charge-card") do |pay_span|
    pay_span.set_attribute("payment.gateway", "stripe")
    charge_card!(cart, payment_method)
  end
end
```

### Recording errors

```ruby theme={null}
Tracelit.tracer.in_span("risky-operation") do |span|
  begin
    risky!
  rescue => e
    span.record_exception(e)
    span.status = OpenTelemetry::Trace::Status.error(e.message)
    raise
  end
end
```

### Automatic instrumentation

The SDK enables every instrumentation gem bundled in `opentelemetry-instrumentation-all`:

| 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.

***

## Metrics

### Automatic metrics

The SDK emits the following metrics out of the box — no configuration required:

| Metric                         | Type           | Interval    | Description                                                                      |
| ------------------------------ | -------------- | ----------- | -------------------------------------------------------------------------------- |
| `http.server.request.count`    | Counter        | per request | Total HTTP requests, tagged by `http.route`, `http.method`, `http.status_code`   |
| `http.server.request.duration` | Histogram (ms) | per request | End-to-end request duration                                                      |
| `http.server.error.count`      | Counter        | per request | 5xx responses only                                                               |
| `db.query.duration`            | Histogram (ms) | per request | Total ActiveRecord time per request                                              |
| `sidekiq.job.count`            | Counter        | per job     | Jobs processed, tagged by `sidekiq.job.class`, `sidekiq.queue`, `sidekiq.status` |
| `sidekiq.job.duration`         | Histogram (ms) | per job     | Job execution time                                                               |
| `sidekiq.job.error.count`      | Counter        | per job     | Jobs that raised an error                                                        |
| `db.connection_pool.size`      | Gauge          | 30 s        | Maximum connections in the pool                                                  |
| `db.connection_pool.busy`      | Gauge          | 30 s        | Connections currently checked out                                                |
| `db.connection_pool.idle`      | Gauge          | 30 s        | Connections available for checkout                                               |
| `db.connection_pool.waiting`   | Gauge          | 30 s        | Threads waiting for a connection                                                 |
| `process.memory.rss`           | Gauge (MB)     | 60 s        | Process resident set size                                                        |
| `process.runtime.cpu.usage`    | Gauge (%)      | 30 s        | Process CPU utilisation                                                          |

<Note>
  Sidekiq and ActiveRecord metrics are only installed when those libraries are present. All pollers are fork-safe — they restart automatically inside each Puma cluster worker.
</Note>

### Manual metrics

```ruby theme={null}
# Counter — increment on each event
orders = Tracelit.metrics.counter("orders.placed", description: "Total orders placed")
orders.add(1, attributes: { "currency" => "USD" })

# Histogram — record a measured value
latency = Tracelit.metrics.histogram("payment.duration", unit: "ms")
latency.record(elapsed_ms, attributes: { "gateway" => "stripe" })

# Gauge — record a point-in-time value
depth = Tracelit.metrics.gauge("queue.depth", description: "Current queue depth")
depth.record(queue.size, attributes: { "queue" => "default" })
```

***

## 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.

* 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`

```ruby theme={null}
# This works exactly as before — no changes needed
Rails.logger.info("Order #{order.id} created", { amount: order.total })
# ↑ Automatically includes trace_id + span_id in Tracelit
```

***

## Sampling and error guarantee

```ruby theme={null}
config.sample_rate = 0.1   # keep 10% of traces
```

<Note>
  **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.
</Note>

***

## Disabling in specific environments

### Tests

```ruby theme={null}
# 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
```

```bash theme={null}
# Run tests with telemetry off
TRACELIT_ENABLED=false bundle exec rspec

# Or set permanently in config/environments/test.rb or .env.test
TRACELIT_ENABLED=false
```

### Rails console

By default the SDK initialises during `rails console`, printing OTel instrumentation startup lines before your prompt. Suppress this with:

```ruby theme={null}
# config/initializers/tracelit.rb
Tracelit.configure do |config|
  config.api_key      = ENV["TRACELIT_API_KEY"]
  config.service_name = ENV["TRACELIT_SERVICE_NAME"]
  config.environment  = ENV["TRACELIT_ENVIRONMENT"]
  config.enabled      = !defined?(Rails::Console)
end
```

`Rails::Console` is defined only when the process was started via `rails console`, so this has no effect on your server or background workers.

***

## Commit SHA tracking

The SDK automatically attaches the current commit SHA as `service.commit_sha` on every span, metric, and log. It resolves the SHA from common CI/CD environment variables with no configuration needed:

| Platform       | Environment variable                           |
| -------------- | ---------------------------------------------- |
| GitHub Actions | `GITHUB_SHA`                                   |
| Heroku         | `HEROKU_SLUG_COMMIT` / `SOURCE_VERSION`        |
| Render         | `RENDER_GIT_COMMIT`                            |
| Fly.io         | `FLY_APP_VERSION`                              |
| Railway        | `RAILWAY_GIT_COMMIT_SHA`                       |
| Generic CI     | `COMMIT_SHA` / `GIT_COMMIT_SHA` / `GIT_COMMIT` |
| Local dev      | `git rev-parse HEAD` (subprocess fallback)     |

No action required — if any of the above is set at boot time the SHA is picked up automatically.

***

## GitHub

Source code and issue tracker: [github.com/Tracelit-AI/tracelit-ruby](https://github.com/Tracelit-AI/tracelit-ruby)
