# Ruby

> Rails and Sinatra with the OpenTelemetry Ruby SDK

## Install

```ruby
# Gemfile
gem 'opentelemetry-sdk'
gem 'opentelemetry-exporter-otlp'
gem 'opentelemetry-instrumentation-all'
```

```bash
bundle install
```

## Configure

For Rails, put this in `config/initializers/opentelemetry.rb`:

```ruby
require 'opentelemetry/sdk'
require 'opentelemetry/instrumentation/all'
require 'opentelemetry/exporter/otlp'

OpenTelemetry::SDK.configure do |c|
  c.service_name = 'my-ruby-service'
  c.use_all      # every available instrumentation
end
```

```bash
export OTEL_EXPORTER_OTLP_ENDPOINT="https://ingress.rocketlog.io"
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer rg_live_xxxxxx"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
```

`use_all` covers Rails, Rack, ActiveRecord, Net::HTTP, Redis, Sidekiq and Faraday. To pick
individually, replace it with `c.use 'OpenTelemetry::Instrumentation::Rails'` and friends.

## Forking servers

Puma and Unicorn fork workers. The batch exporter's background thread does not survive a
fork, so telemetry stops after boot unless you restart it in the child:

```ruby
# config/puma.rb
on_worker_boot do
  OpenTelemetry.tracer_provider.force_flush
end
```

> **Warning:** This is the usual reason a Rails app reports spans in development and nothing in
  production — development runs single-process, production forks.

## Custom spans

```ruby
tracer = OpenTelemetry.tracer_provider.tracer('payments')

tracer.in_span('settle-transfer', attributes: { 'transfer.id' => transfer_id }) do |span|
  begin
    settle(transfer_id)
  rescue => e
    span.record_exception(e)
    span.status = OpenTelemetry::Trace::Status.error(e.message)
    raise
  end
end
```
