---
title: "Ruby"
description: "Monitor Ruby applications effectively by configuring Middleware APM to track performance, errors, and system resource usage."
section: "APM"
breadcrumb: "APM > Ruby"
canonical: "https://docs.middleware.io/get-started/apm/ruby"
---
# 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`
- Ruby 3.0+
  Check using the following command:

```bash
    ruby --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

```ruby
    gem 'opentelemetry-sdk'
gem 'opentelemetry-exporter-otlp'
gem 'opentelemetry-instrumentation-all'
gem 'pyroscope'
gem 'middleware_apm_linux', '~> 2.1.0'
```

#### Windows

```ruby
    gem 'opentelemetry-sdk'
gem 'opentelemetry-exporter-otlp'
gem 'opentelemetry-instrumentation-all'
gem 'pyroscope'
gem 'middleware_apm_windows', '~> 2.1.0'
```

#### Heroku

```ruby
    gem 'opentelemetry-sdk'
gem 'opentelemetry-exporter-otlp'
gem 'opentelemetry-instrumentation-all'
gem 'pyroscope'
gem 'middleware_apm_linux', '~> 2.1.0'
```

Then install:

```bash
    bundle 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

```ruby
    require 'middleware/ruby_gem_linux'
Middleware::RubyGem.init
```

#### Windows

```ruby
    require 'middleware/ruby_gem_windows'
Middleware::RubyGem.init
```

#### Heroku

```ruby
    require 'middleware/ruby_gem_linux'
Middleware::RubyGem.init
```

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

```ruby
    # config/environment.rb
require_relative "application"
require 'middleware/ruby_gem_linux'

# Initialize Middleware.io application monitoring
Middleware::RubyGem.init

# Initialize the Rails application.
Rails.application.initialize!
```

## 3. Capture application data

#### Linux

```ruby
        OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:9320 \
    OTEL_SERVICE_NAME="<YOUR_SERVICE_NAME>" \
    OTEL_RESOURCE_ATTRIBUTES=project.name="<YOUR_PROJECT_NAME>" \
    MW_API_KEY="<MW_API_KEY>" \
    <YOUR RUBY COMMAND>   # e.g., bundle exec puma -C config/puma.rb
```

#### Windows

```ruby
    $env:OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:9320"
$env:OTEL_SERVICE_NAME="<YOUR_SERVICE_NAME>"
$env:OTEL_RESOURCE_ATTRIBUTES='project.name="<YOUR_PROJECT_NAME>"'
$env:MW_API_KEY="<MW_API_KEY>"
ruby your_app.rb
```

#### Heroku

- 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:

```ruby
    OTEL_SERVICE_NAME="<YOUR_SERVICE_NAME>"
OTEL_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](https://app.middleware.io/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:

  ```bash
      export APPNAME=<YOUR_HEROKU_APP>
  ```
- Enable dyno metadata (required for hostname continuity features):

  ```bash
      heroku labs:enable runtime-dyno-metadata -a $APPNAME
  ```
- Add/open config:

  ```bash
      heroku config:add MW_API_KEY=<MW_API_KEY>
      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? Get in touch with us via our Contact Us page or join our Slack channel.
