Heroku Integration

Monitor your Heroku applications with OpenTelemetry

Overview

Instrument your Heroku applications to send logs, metrics, and traces to Qorrelate. This guide covers setting up OpenTelemetry instrumentation and configuring log drains.

What You'll Get

  • • Distributed traces across your Heroku dynos
  • • Application logs with full-text search
  • • Custom metrics from your application
  • • Heroku platform metrics (with add-on)

Quick Setup

1. Set Environment Variables

Add your Qorrelate credentials to your Heroku app:

heroku config:set OTEL_EXPORTER_OTLP_ENDPOINT="https://qorrelate.io" \
  OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer YOUR_API_KEY,X-Organization-Id=YOUR_ORG_ID" \
  OTEL_SERVICE_NAME="my-heroku-app" \
  -a your-app-name

2. Add OpenTelemetry to Your App

Choose your language below for specific instructions.

Heroku Log Drains

Send Heroku's platform logs (router logs, dyno metrics) to Qorrelate using a log drain:

heroku drains:add "https://qorrelate.io/v1/heroku/logs?api_key=YOUR_API_KEY&org_id=YOUR_ORG_ID" \
  -a your-app-name

This will send:

  • Router logs (HTTP request/response)
  • Dyno state changes
  • Build logs
  • Heroku platform errors

Node.js on Heroku

1. Install Dependencies

npm install @opentelemetry/api @opentelemetry/sdk-node \
  @opentelemetry/auto-instrumentations-node \
  @opentelemetry/exporter-trace-otlp-http \
  @opentelemetry/exporter-metrics-otlp-http

2. Create Tracing File

Create tracing.js:

const { NodeSDK } = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-http');
const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');

const traceExporter = new OTLPTraceExporter();
const metricExporter = new OTLPMetricExporter();

const sdk = new NodeSDK({
  traceExporter,
  metricReader: new PeriodicExportingMetricReader({
    exporter: metricExporter,
    exportIntervalMillis: 60000
  }),
  instrumentations: [getNodeAutoInstrumentations()]
});

sdk.start();

process.on('SIGTERM', () => {
  sdk.shutdown().finally(() => process.exit(0));
});

3. Update Procfile

web: node -r ./tracing.js server.js

Python on Heroku

1. Add to requirements.txt

opentelemetry-api
opentelemetry-sdk
opentelemetry-exporter-otlp
opentelemetry-instrumentation
opentelemetry-distro

2. Install Auto-Instrumentation

In your build process or Dockerfile:

opentelemetry-bootstrap -a install

3. Update Procfile

# For Django
web: opentelemetry-instrument gunicorn myproject.wsgi

# For Flask
web: opentelemetry-instrument gunicorn app:app

# For FastAPI
web: opentelemetry-instrument uvicorn main:app --host 0.0.0.0 --port $PORT

Ruby on Heroku

1. Add to Gemfile

gem 'opentelemetry-sdk'
gem 'opentelemetry-exporter-otlp'
gem 'opentelemetry-instrumentation-all'

2. Configure OpenTelemetry

Create config/initializers/opentelemetry.rb:

require 'opentelemetry/sdk'
require 'opentelemetry/exporter/otlp'
require 'opentelemetry/instrumentation/all'

OpenTelemetry::SDK.configure do |c|
  c.service_name = ENV['OTEL_SERVICE_NAME'] || 'my-ruby-app'
  c.use_all # Enables all auto-instrumentation
end

Java on Heroku

1. Download the Java Agent

Add to your build (e.g., in a bin/ directory):

curl -L https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar \
  -o opentelemetry-javaagent.jar

2. Update Procfile

web: java -javaagent:opentelemetry-javaagent.jar -jar target/myapp.jar

Dyno Metrics

Enable Heroku's log-runtime-metrics to get dyno resource metrics:

heroku labs:enable log-runtime-metrics -a your-app-name

This adds metrics to your logs:

  • memory_total - Total memory
  • memory_rss - Resident set size
  • memory_cache - Cache memory
  • memory_swap - Swap usage
  • memory_pgpgin / memory_pgpgout - Page in/out
  • load_avg_1m - 1-minute load average

When using the log drain, these metrics are automatically parsed and stored as Qorrelate metrics.

Review Apps

For Heroku Review Apps, use environment-specific service names to distinguish data:

// app.json
{
  "env": {
    "OTEL_SERVICE_NAME": {
      "value": "my-app-review-$HEROKU_APP_NAME"
    }
  }
}

This ensures each review app's telemetry is tagged with its unique name.

Need Help?

Having trouble setting up Heroku integration? Contact our team for assistance.