# OpenTelemetry Setup (/sdks/ruby/how-to/observability/opentelemetry-setup)



## Overview [#overview]

**OpenTelemetry integration** wires the client's messaging operations into your tracing pipeline without hand-instrumenting every call site. In a distributed system where a message might be published by one service, queued, and consumed by three others, per-call logging tells you almost nothing — you need spans that correlate across process boundaries. The Ruby SDK doesn't ship its own OTel code; it relies entirely on the standard Ruby OpenTelemetry SDK's gRPC auto-instrumentation, which keeps the client itself lightweight.

When a `TracerProvider` is configured globally via `OpenTelemetry::SDK.configure`, every gRPC call the client makes — `send_event`, `subscribe`, and the rest — is automatically instrumented, as long as `opentelemetry-instrumentation-grpc` is installed alongside the core `opentelemetry-sdk` gem. &#x2A;*Gotchas:** `OpenTelemetry::SDK.configure` must run *before* the KubeMQ client is created, or the first calls go unrecorded; `c.use_all` enables every available instrumentation library on the classpath, which can be noisier than you want in production — prefer `c.use 'OpenTelemetry::Instrumentation::GRPC'` to scope it down; and without a configured exporter (OTLP, Jaeger, Zipkin), spans are created but never sent anywhere.

## Prerequisites [#prerequisites]

* KubeMQ server running on `localhost:50000`
* Ruby SDK installed (`gem install kubemq`)
* OpenTelemetry gems: `opentelemetry-sdk`, `opentelemetry-exporter-otlp`

## Code [#code]

```ruby title="main.rb"
require 'kubemq'

# The KubeMQ Ruby client supports OpenTelemetry through the standard
# Ruby OpenTelemetry SDK. When a TracerProvider is configured globally,
# gRPC calls are automatically instrumented.
#
# Setup:
#   require 'opentelemetry/sdk'
#   require 'opentelemetry/exporter/otlp'
#
#   OpenTelemetry::SDK.configure do |c|
#     c.service_name = 'kubemq-ruby-example'
#     c.use_all
#   end

puts 'OpenTelemetry configured'

address = ENV.fetch('KUBEMQ_ADDRESS', 'localhost:50000')

begin
  client = KubeMQ::PubSubClient.new(address: address, client_id: 'otel-example')
  puts "Connected to #{address}"

  msg = KubeMQ::PubSub::EventMessage.new(
    channel: 'ruby-observability.opentelemetry-setup',
    metadata: 'otel-demo',
    body: 'traced-event'
  )
  client.send_event(msg)
  puts 'Event sent with tracing enabled'
rescue KubeMQ::Error => e
  puts "KubeMQ error: #{e.message}"
ensure
  client&.close
  puts 'Done'
end
```

## How It Works [#how-it-works]

* The Ruby SDK integrates with OpenTelemetry through the standard Ruby OpenTelemetry SDK.
* When a `TracerProvider` is configured globally, gRPC calls are automatically instrumented.
* Install `opentelemetry-instrumentation-grpc` for automatic gRPC span creation.
* Configure an exporter (OTLP, Jaeger, Zipkin) to view traces in your observability platform.
* Review timeouts, channel names, and client IDs before running against shared environments.

## Related [#related]

* [Ruby SDK Reference](/sdks/ruby/reference)
* [Basic Pub/Sub](/sdks/ruby/tutorials/basic-pubsub)
