Heroku Buildpack for Middleware
The Middleware Heroku buildpack installs and runs mw-agent
on each dyno to collect metrics and traces, forwarding them to the Middleware Observability platform. It does not handle logs, and you are required to use the Heroku Log Drain integration for log collection instead.
Prerequisites
- Heroku CLI installed and authenticated.
- An existing Heroku app.
- Your Middleware API Key (
MW_API_KEY
) and Tenant URL (MW_TARGET
).
1. Set APPNAME
1export APPNAME=<YOUR_HEROKU_APPLICATION_NAME>
2. Add & Configure the Buildpack
1cd <HEROKU_APPLICATION_DIRECTORY>
2
3# Enable Dyno metadata (needed for hostname continuity)
4heroku labs:enable runtime-dyno-metadata -a $APPNAME
5
6# Supply your Middleware credentials
7heroku config:add MW_API_KEY=<MW_API_KEY> -a $APPNAME
8heroku config:add MW_TARGET=https://<MW_UID>.middleware.io:443 -a $APPNAME
9
10# Add the Middleware buildpack
11heroku buildpacks:add https://github.com/middleware-labs/heroku-buildpack-middleware.git -a $APPNAME
12
13# Rebuild your slug
14git commit --allow-empty -m "Add Middleware buildpack"
15git push heroku main
3. Buildpack Ordering
Your application’s primary buildpack must follow the Middleware buildpack. Otherwise, Middleware will override the Dyno’s process type and prevent your app from starting correctly.
Additionally, any buildpacks that override /app
directory should be listed before the Middleware buildpack. For example, if your application requires Node, Middleware, and apt
buildpacks, the output of heroku buildpacks should be as follows:
1https://github.com/heroku/heroku-buildpack-apt.git
2https://github.com/middleware-labs/heroku-buildpack-middleware.git
3heroku/nodejs # or ruby, python, etc.
4. Pinning Versions (Optional)
Pin buildpack to a Git tag:
1heroku buildpacks:add https://github.com/middleware-labs/heroku-buildpack-middleware.git#<TAG_NAME>
Pin agent version:
1heroku config:add MW_AGENT_VERSION=1.7.7 -a $APPNAME
Rebuild the slug after changes:
1git commit --allow-empty -m "Rebuild slug"
2git push heroku main
5. Configuration Variables
Below is the list of all environment variables that you can set in your Heroku application to change the behavior of the Middleware buildpack and mw-agent
.
Variable | Required | Description |
---|---|---|
MW_API_KEY | Yes | Your Middleware API key. |
MW_TARGET | Yes | Your tenant URL (https://<MW_UID>.middleware.io:443 ). |
MW_AGENT_VERSION | No | Override the default mw-agent tag. |
MW_DYNO_DISABLE_AGENT | No | If true , disables mw-agent on this Dyno. |
MW_DYNO_HOSTNAME | No | If true , use appname.type.num as hostname (see below). |
MW_DYNO_PREEXEC_SCRIPT | No | Path to a script to run before starting mw-agent . |
MW_HOST_TAGS | No | Comma-separated key:value pairs (e.g. env:prod,role:web ). |
MW_FLUENT_PORT | No | Fluent receiver port (default 8006 ). |
MW_AGENT_FEATURES_METRIC_COLLECTION | No | Enable infra metrics (default true). |
MW_AGENT_FEATURES_LOG_COLLECTION | No | Enable log collection (not used by this buildpack). |
6. Dyno Hostnames
By default, dynos report their internal container ID as hostname. To maintain continuity across dyno restarts, set:
1heroku config:add MW_DYNO_HOSTNAME=true -a $APPNAME
This requires runtime-dyno-metadata to be enabled
7. Preexec Script
If you need to adjust config vars or disable the agent for certain dyno types, point MW_DYNO_PREEXEC_SCRIPT
at a script bundled with your app:
1heroku config:add MW_DYNO_PREEXEC_SCRIPT=/app/preexec.sh -a $APPNAME
Inside preexec.sh
, you might do:
1#!/bin/bash
2DYNO_TYPE="${DYNO%%.*}"
3if [ "$DYNO_TYPE" == "run" ]; then
4 export MW_DYNO_DISABLE_AGENT=true
5fi
6# ...additional setup...
8. Exposed Endpoints
mw-agent
listens locally for:
- OTLP gRPC: port
9313
- OTLP HTTP: port
9320
- Fluent Forward: port
8006
9. Managing the Agent
Use Heroku CLI to inspect and debug the agent on your dynos:
Action | Command |
---|---|
List dynos | heroku ps -a $APPNAME |
Exec into a dyno | heroku ps:exec -a $APPNAME |
Check mw-agent process | ps aux grep mw-agent (inside dyno) |
View live agent logs | heroku logs --ps web -a $APPNAME --num 1500 grep mw-agent |
Cat agent log file | heroku ps:exec -a $APPNAME → cat /app/mw-agent/mw-agent.log |
Troubleshooting
- Is the agent running?
1heroku ps:exec -a $APPNAME 2ps aux | grep mw-agent
- Inspect logs inside dyno:
1cat /app/mw-agent/mw-agent.log
- Verify config vars:
1heroku config -a $APPNAME
- Network check: Ensure outbound HTTPS (443) to <MW_UID>.middleware.io isn’t blocked.
Uninstall
Remove the buildpack:
1heroku buildpacks:remove https://github.com/middleware-labs/heroku-buildpack-middleware.git -a $APPNAME
Unset all Middleware vars:
1heroku config:unset MW_API_KEY MW_TARGET MW_AGENT_VERSION MW_DYNO_DISABLE_AGENT \ 2MW_DYNO_HOSTNAME MW_DYNO_PREEXEC_SCRIPT MW_HOST_TAGS MW_FLUENT_PORT \ 3MW_AGENT_FEATURES_METRIC_COLLECTION MW_AGENT_FEATURES_LOG_COLLECTION -a $APPNAME
Rebuild the slug to apply the removal:
1git commit --allow-empty -m "Remove Middleware buildpack" 2git push heroku main
(Optional) Clear all buildpacks:
1heroku buildpacks:clear -a $APPNAME