Ruby
This guide covers adding OpenTelemetry instrumentation to Ruby applications. Ruby has auto-instrumentation support for Rails, Sinatra, Rack, and popular database and HTTP client libraries.
Prerequisites
Section titled “Prerequisites”- Ruby 3.0+
- OTel Collector running at
localhost:4317(gRPC) orlocalhost:4318(HTTP) - Bundler for dependency management
Install dependencies
Section titled “Install dependencies”Add to your Gemfile:
gem "opentelemetry-sdk"gem "opentelemetry-exporter-otlp"gem "opentelemetry-instrumentation-all"Then install:
bundle installThe opentelemetry-instrumentation-all meta-gem includes instrumentation for Rails, Sinatra, Rack, Faraday, Net::HTTP, pg, mysql2, redis, sidekiq, and more.
For a minimal install, pick individual instrumentation gems:
gem "opentelemetry-sdk"gem "opentelemetry-exporter-otlp"gem "opentelemetry-instrumentation-rack"gem "opentelemetry-instrumentation-rails"SDK setup
Section titled “SDK setup”Initialize OpenTelemetry early in your application startup:
require "opentelemetry/sdk"require "opentelemetry/exporter/otlp"require "opentelemetry/instrumentation/all"
OpenTelemetry::SDK.configure do |c| c.service_name = "my-ruby-service" c.service_version = "1.0.0"
c.resource = OpenTelemetry::SDK::Resources::Resource.create( "deployment.environment" => "development" )
c.add_span_processor( OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new( OpenTelemetry::Exporter::OTLP::Exporter.new( endpoint: "http://localhost:4317" ) ) )
c.use_all # Auto-instrument all installed librariesendAuto-instrumentation
Section titled “Auto-instrumentation”The use_all method shown above enables auto-instrumentation for all installed instrumentation gems. To selectively enable instrumentations:
OpenTelemetry::SDK.configure do |c| c.use "OpenTelemetry::Instrumentation::Rack" c.use "OpenTelemetry::Instrumentation::Rails" c.use "OpenTelemetry::Instrumentation::Net::HTTP" c.use "OpenTelemetry::Instrumentation::PG"endTo configure individual instrumentations:
OpenTelemetry::SDK.configure do |c| c.use "OpenTelemetry::Instrumentation::Rails", { enable_recognize_route: true } c.use "OpenTelemetry::Instrumentation::Sidekiq", { span_naming: :job_class }endManual instrumentation
Section titled “Manual instrumentation”Creating spans
Section titled “Creating spans”tracer = OpenTelemetry.tracer_provider.tracer("my-module")
def process_order(order_id) tracer = OpenTelemetry.tracer_provider.tracer("my-module")
tracer.in_span("process_order", attributes: { "order.id" => order_id }) do |span| validate_payment(order_id)
span.add_event("order_processed", attributes: { "order.id" => order_id }) endendRecording errors
Section titled “Recording errors”tracer.in_span("risky_operation") do |span| begin perform_operation rescue StandardError => e span.record_exception(e) span.status = OpenTelemetry::Trace::Status.error(e.message) raise endendRecording metrics
Section titled “Recording metrics”meter = OpenTelemetry.meter_provider.meter("my-module")
request_counter = meter.create_counter( "http.server.request_count", description: "Number of HTTP requests", unit: "1")
request_duration = meter.create_histogram( "http.server.duration", description: "HTTP request duration", unit: "ms")
def handle_request(method, route, duration_ms) attributes = { "http.method" => method, "http.route" => route } request_counter.add(1, attributes: attributes) request_duration.record(duration_ms, attributes: attributes)endFramework integration
Section titled “Framework integration”Create an initializer at config/initializers/opentelemetry.rb:
require "opentelemetry/sdk"require "opentelemetry/exporter/otlp"require "opentelemetry/instrumentation/rails"require "opentelemetry/instrumentation/active_record"
OpenTelemetry::SDK.configure do |c| c.service_name = "my-rails-app"
c.add_span_processor( OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new( OpenTelemetry::Exporter::OTLP::Exporter.new( endpoint: "http://localhost:4317" ) ) )
c.use "OpenTelemetry::Instrumentation::Rails" c.use "OpenTelemetry::Instrumentation::ActiveRecord" c.use "OpenTelemetry::Instrumentation::ActionPack" c.use "OpenTelemetry::Instrumentation::ActionView"endSinatra
Section titled “Sinatra”require "sinatra"require "opentelemetry/sdk"require "opentelemetry/exporter/otlp"require "opentelemetry/instrumentation/sinatra"
OpenTelemetry::SDK.configure do |c| c.service_name = "my-sinatra-app"
c.add_span_processor( OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new( OpenTelemetry::Exporter::OTLP::Exporter.new( endpoint: "http://localhost:4317" ) ) )
c.use "OpenTelemetry::Instrumentation::Sinatra"end
get "/orders/:id" do { order_id: params[:id] }.to_jsonendSidekiq
Section titled “Sidekiq”require "opentelemetry/instrumentation/sidekiq"
OpenTelemetry::SDK.configure do |c| c.use "OpenTelemetry::Instrumentation::Sidekiq", { span_naming: :job_class, propagation_style: :link }endEnvironment variables
Section titled “Environment variables”| Variable | Description | Example |
|---|---|---|
OTEL_SERVICE_NAME | Service name | my-ruby-service |
OTEL_EXPORTER_OTLP_ENDPOINT | Collector endpoint | http://localhost:4317 |
OTEL_EXPORTER_OTLP_PROTOCOL | Export protocol | grpc |
OTEL_TRACES_SAMPLER | Sampler type | parentbased_traceidratio |
OTEL_TRACES_SAMPLER_ARG | Sampler argument | 0.1 |
OTEL_RESOURCE_ATTRIBUTES | Additional resource attributes | deployment.environment=prod |
OTEL_RUBY_DISABLED_INSTRUMENTATIONS | Disabled instrumentations | sidekiq,redis |
Related links
Section titled “Related links”- Applications overview
- Auto-instrumentation
- Manual instrumentation
- OpenTelemetry Ruby documentation — Official OTel Ruby SDK reference
- Ruby instrumentation libraries — Available auto-instrumentation packages