Ruby

TracesMetricsApp LogsCustom LogsProfiling

This guide walks you through instrumenting Ruby 3.0+ applications with Middleware APM in host-based and Heroku setups. It follows the same structure as your other language pages and keeps per-platform code blocks.

1. Prerequisites

  • Middleware Host Agent running on the same machine (host-based mode). If your app is containerized, point it to the Host Agent via MW_AGENT_SERVICE:
    • Docker: 172.17.0.1
    • Kubernetes: mw-service.mw-agent-ns.svc.cluster.local
  • Ruby 3.0+ Check using the following command:
1ruby --version

Heroku: If you deploy on Heroku, use the official Heroku buildpack for Middleware; it runs mw-agent inside the dyno and exposes local OTLP endpoints (HTTP 9320, gRPC 9313).

Supported frameworks: Rails, Sinatra, and generic Rack apps are covered via opentelemetry-instrumentation-all. No framework-specific code changes are required beyond the initialize step below.

Container networking tip: When the app runs inside a container on the same host as the Host Agent, use MW_AGENT_SERVICE=172.17.0.1 (Docker) or the in-cluster service DNS for Kubernetes so the app can reach the Host Agent on the host/cluster network.

2. Install

1 Add gems to your Gemfile

Linux
Windows
Heroku
1gem 'opentelemetry-sdk'
2gem 'opentelemetry-exporter-otlp'
3gem 'opentelemetry-instrumentation-all'
4gem 'pyroscope'
5gem 'middleware_apm_linux', '~> 2.1.0'
1gem 'opentelemetry-sdk'
2gem 'opentelemetry-exporter-otlp'
3gem 'opentelemetry-instrumentation-all'
4gem 'pyroscope'
5gem 'middleware_apm_windows', '~> 2.1.0'
1gem 'opentelemetry-sdk'
2gem 'opentelemetry-exporter-otlp'
3gem 'opentelemetry-instrumentation-all'
4gem 'pyroscope'
5gem 'middleware_apm_linux', '~> 2.1.0'

Then install:

1bundle install

The middleware_apm_* gems provide Middleware’s Ruby bootstrap plus profiling (via pyroscope). Latest published versions are listed on RubyGems.

2 Import & initialize the tracker at the very start of your app

Linux
Windows
Heroku
1require 'middleware/ruby_gem_linux'
2Middleware::RubyGem.init
1require 'middleware/ruby_gem_windows'
2Middleware::RubyGem.init
1require 'middleware/ruby_gem_linux'
2Middleware::RubyGem.init

For Rails, you can add the require/init in config/environment.rb (before Rails.application.initialize!). Example:

1# config/environment.rb
2require_relative "application"
3require 'middleware/ruby_gem_linux'
4
5# Initialize Middleware.io application monitoring
6Middleware::RubyGem.init
7
8# Initialize the Rails application.
9Rails.application.initialize!

3. Capture application data

Linux
Windows
Heroku
1OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:9320 \
2    OTEL_SERVICE_NAME="<YOUR_SERVICE_NAME>" \
3    OTEL_RESOURCE_ATTRIBUTES=project.name="<YOUR_PROJECT_NAME>" \
4    MW_API_KEY="<MW_API_KEY>" \
5    <YOUR RUBY COMMAND>   # e.g., bundle exec puma -C config/puma.rb
1$env:OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:9320"
2$env:OTEL_SERVICE_NAME="<YOUR_SERVICE_NAME>"
3$env:OTEL_RESOURCE_ATTRIBUTES='project.name="<YOUR_PROJECT_NAME>"'
4$env:MW_API_KEY="<MW_API_KEY>"
5ruby your_app.rb
  • The Middleware Heroku buildpack auto-configures the local OTLP endpoints and instrumentation. You typically don’t need to set OTEL_EXPORTER_OTLP_ENDPOINT.
  • If you want to override service/project only, set:
1OTEL_SERVICE_NAME="<YOUR_SERVICE_NAME>"
2OTEL_RESOURCE_ATTRIBUTES='project.name=<YOUR_PROJECT_NAME>'

(For Rails, you may set these envs in config/environment.rb before initializing the Middleware gem.)

4. Profiling

No extra steps required here. Profiling is auto-configured once you complete Step 2 (the pyroscope gem is part of the Gemfile set above).

5. View your data

After installation, wait 3–5 minutes, then open Middleware and check APM → Traces and Continuous Profiling. (Ruby does not currently expose app logs/custom logs in the Ruby guide.)

6. Environment variables

VariableScopePurposeExample
MW_AGENT_SERVICEHost (containers)Address/DNS of Host Agent (host-based installs)172.17.0.1 (Docker), mw-service.mw-agent-ns.svc.cluster.local (K8s)
OTEL_EXPORTER_OTLP_ENDPOINTAllWhere to send OTLP (HTTP). Host-based default is the Host Agent at http://localhost:9320. Heroku buildpack sets this automatically.http://localhost:9320
MW_API_KEYAllMiddleware API key (required for export).xxxx…
OTEL_SERVICE_NAMEAllLogical service name shown in APM.orders-api
OTEL_RESOURCE_ATTRIBUTESAllExtra resource attrs; used for project scoping.project.name=shop-app
MW_TARGETHerokuTarget ingest URL (set by the buildpack during setup).https://<MW_UID>.middleware.io:443

(Host-based vars and run commands: Ruby page; Heroku vars and behavior: Heroku buildpack page.)

7. Heroku buildpack quick setup (optional)

  • From your Heroku app directory:
    1export APPNAME=<YOUR_HEROKU_APP>
  • Enable dyno metadata (required for hostname continuity features):
    1heroku labs:enable runtime-dyno-metadata -a $APPNAME
  • Add/open config:
    1heroku config:add MW_API_KEY=<MW_API_KEY>
    2    heroku config:add MW_TARGET=https://<MW_UID>.middleware.io:443

Note: Ensure buildpack order: Middleware BEFORE your app buildpack The buildpack installs mw-agent into /app/mw-agent, starts it automatically, and exposes OTLP on ports 9313 (gRPC) and 9320 (HTTP).

8. Troubleshooting

  • No data (host-based): Confirm that the Host Agent is running and that you have exported the MW_API_KEY. If running in Docker/K8s, ensure MW_AGENT_SERVICE points to the correct gateway/service and that you’re using http://localhost:9320 inside the same host/namespace.
  • Rails not sending spans: Ensure require 'middleware/ruby_gem_*' and Middleware::RubyGem.init run before Rails.application.initialize!.
  • Heroku not wiring OTLP: Verify the buildpack is installed and ordered correctly (Middleware before your language buildpack), and that MW_API_KEY and MW_TARGET are set. Check dyno with heroku ps:exec and inspect /app/mw-agent/mw-agent.log.

Need assistance or want to learn more about Middleware? Contact our support team at [email protected] or join our Slack channel.