Skip to content

Ruby

Ruby uses the OpenTelemetry Ruby SDK plus opentelemetry-instrumentation-all, which instruments Rails, Rack, Sinatra, ActiveRecord, Net::HTTP, Faraday, Redis, Sidekiq and more. You add a few lines of setup; the rest needs no code changes.

Use this page when you run a Ruby or Rails service and want it in FuseScope.

Signal Status What is sent
Traces Stable Spans for requests, HTTP calls, database and jobs.
Metrics Development Your own metrics, through separate pre-1.0 gems.
Logs Development Ruby Logger and Rails logger records with trace IDs, through separate pre-1.0 gems.

Metrics and logs work, but their gems are still 0.x and can change between releases. Traces alone need only the first three gems below.

  • CRuby 3.3 or later (current gems require it). JRuby and TruffleRuby are best effort.
  • Bundler.
  • A FuseScope collector you can reach on port 4318. See OTLP.
Terminal window
bundle add opentelemetry-sdk opentelemetry-exporter-otlp opentelemetry-instrumentation-all
# Optional: metrics and logs
bundle add opentelemetry-metrics-sdk opentelemetry-exporter-otlp-metrics
bundle add opentelemetry-logs-sdk opentelemetry-exporter-otlp-logs opentelemetry-instrumentation-logger
  1. Configure the SDK as early as possible. In Rails, use an initializer:

    config/initializers/opentelemetry.rb
    require "opentelemetry/sdk"
    require "opentelemetry/exporter/otlp"
    require "opentelemetry/instrumentation/all"
    # Optional: metrics and logs. Load them before configure.
    require "opentelemetry-metrics-sdk"
    require "opentelemetry/exporter/otlp_metrics"
    require "opentelemetry-logs-sdk"
    require "opentelemetry/exporter/otlp_logs"
    require "opentelemetry/instrumentation/logger"
    OpenTelemetry::SDK.configure do |c|
    c.use_all
    end

    use_all turns on every instrumentation whose library is loaded. Outside Rails, put this at the top of your entry point (for example config.ru), before the app is built.

  2. Configure the exporter:

    Terminal window
    export OTEL_SERVICE_NAME=checkout
    export OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production,service.version=1.4.2
    export OTEL_EXPORTER_OTLP_ENDPOINT=http://fusescope-collector.example.com:4318
    export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf

    Traces, metrics and logs default to otlp once their gems are loaded. Set OTEL_METRICS_EXPORTER=none or OTEL_LOGS_EXPORTER=none to turn one off.

  3. Run the app as usual:

    Terminal window
    bundle exec rails server

Not supported by the Ruby SDK. Use Direct (HTTP 4318), or send to a local collector over HTTP and let it forward over gRPC.

The gems are in the Gemfile, so bundle install adds them:

Dockerfile
FROM ruby:3.3-slim
RUN apt-get update && apt-get install -y --no-install-recommends build-essential \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
Terminal window
docker run \
-e OTEL_SERVICE_NAME=checkout \
-e OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production \
-e OTEL_EXPORTER_OTLP_ENDPOINT=http://fusescope-collector.example.com:4318 \
-e OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \
checkout:latest

Set the variables in the pod spec. The downward API adds the pod name and namespace:

deployment.yaml
env:
- name: OTEL_SERVICE_NAME
value: checkout
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: http://fusescope-otel-collector.fusescope.svc.cluster.local:4318
- name: OTEL_EXPORTER_OTLP_PROTOCOL
value: http/protobuf
- name: K8S_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: K8S_NAMESPACE_NAME
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: OTEL_RESOURCE_ATTRIBUTES
value: deployment.environment.name=production,k8s.pod.name=$(K8S_POD_NAME),k8s.namespace.name=$(K8S_NAMESPACE_NAME)

$(VAR) only expands variables defined earlier in the list, so keep OTEL_RESOURCE_ATTRIBUTES last.

With opentelemetry-logs-sdk, opentelemetry-exporter-otlp-logs and opentelemetry-instrumentation-logger installed, use_all patches Ruby’s Logger and the Rails logger. Each record is still written where it was before, and is also exported over OTLP with the trace and span IDs of the active span.

Logs support is in development: the gems are 0.x. If a collector already reads your stdout, set OTEL_LOGS_EXPORTER=none so each line is stored once.

  1. Send a few requests to the service.
  2. Open Services. The service appears under its OTEL_SERVICE_NAME within a minute.
  3. Open the Traces explorer and filter by service.name.

Nothing arrives? Run with OTEL_TRACES_EXPORTER=console to print spans to stdout, and look for warnings from OpenTelemetry at boot, such as a missing exporter gem or an unsupported protocol.