Ruby
| Traces | Metrics | App Logs | Custom Logs | Profiling |
|---|---|---|---|---|
| ✅ | ✖ | ✖ | ✖ | ✅ |
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
- Docker:
- Ruby 3.0+ Check using the following command:
1ruby --versionHeroku: 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
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 installThe 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
1require 'middleware/ruby_gem_linux'
2Middleware::RubyGem.init1require 'middleware/ruby_gem_windows'
2Middleware::RubyGem.init1require 'middleware/ruby_gem_linux'
2Middleware::RubyGem.initFor 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
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.rb1$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
| Variable | Scope | Purpose | Example |
|---|---|---|---|
MW_AGENT_SERVICE | Host (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_ENDPOINT | All | Where 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_KEY | All | Middleware API key (required for export). | xxxx… |
OTEL_SERVICE_NAME | All | Logical service name shown in APM. | orders-api |
OTEL_RESOURCE_ATTRIBUTES | All | Extra resource attrs; used for project scoping. | project.name=shop-app |
MW_TARGET | Heroku | Target 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, ensureMW_AGENT_SERVICEpoints to the correct gateway/service and that you’re usinghttp://localhost:9320inside the same host/namespace. - Rails not sending spans: Ensure
require 'middleware/ruby_gem_*'andMiddleware::RubyGem.initrun beforeRails.application.initialize!. - Heroku not wiring OTLP: Verify the buildpack is installed and ordered correctly (Middleware before your language buildpack), and that
MW_API_KEYandMW_TARGETare set. Check dyno withheroku ps:execand 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.