Heroku Log Drain

Kloudfuse collects logs from Heroku applications using Heroku’s HTTPS log drain feature. When a drain is configured, Heroku’s Logplex system streams all application and system logs to the Kloudfuse ingester in real time over HTTPS.

Overview

Heroku Logplex aggregates log output from every dyno in your application — web, worker, and system components — and delivers it to any registered log drain endpoint. The drain sends batches of newline-delimited syslog-format messages to the target URL over HTTPS.

Kloudfuse receives these messages at:

https://<kloudfuse-hostname>/ingester/heroku/logs

Each log line is parsed and stored with metadata extracted from the Logplex syslog frame, making logs immediately queryable in Kloudfuse alongside metrics and traces.

Prerequisites

  • A deployed Heroku application.

  • The Heroku CLI installed and authenticated, or access to the Heroku Dashboard.

  • The external hostname of your Kloudfuse cluster.

  • If ingestion authentication is enabled on your cluster, an API key — see Ingestion Authentication with API Key.

Configure the Log Drain

Using the Heroku CLI

  1. Add the Kloudfuse HTTPS drain to your application:

    heroku drains:add "https://<kloudfuse-hostname>/ingester/heroku/logs" \
      --app <app-name>

    If ingestion authentication is enabled, append the API key as a URL parameter:

    heroku drains:add "https://<kloudfuse-hostname>/ingester/heroku/logs?kf-api-key=<token>" \
      --app <app-name>
  2. Confirm the drain was created:

    heroku drains --app <app-name>

    The output lists the drain URL and a unique drain token, for example:

    https://<kloudfuse-hostname>/ingester/heroku/logs (d.a1b2c3d4-e5f6-7890-abcd-ef1234567890)

    Kloudfuse stores the drain token as the drain_token label on every log record from this drain.

Using the Heroku Dashboard

  1. Open your application in the Heroku Dashboard.

  2. Go to Settings > Log Drains and click Add Drain.

  3. Enter the drain URL:

    https://<kloudfuse-hostname>/ingester/heroku/logs?kf-api-key=<token>
  4. Click Save Drain.

Add Custom Labels

Append any additional labels as URL query parameters. Kloudfuse attaches them to every log record from this drain, making it easy to filter by environment, region, or team:

heroku drains:add "https://<kloudfuse-hostname>/ingester/heroku/logs?kf-api-key=<token>&env=production&region=us-east" \
  --app <app-name>

The kf-api-key parameter is consumed for authentication and is not stored as a label. All other parameters are stored as labels.

Log Metadata

Kloudfuse automatically extracts and indexes the following fields from every Heroku log message:

Field Description

source

Always set to heroku — use this to filter all Heroku logs.

drain_token

Unique drain identifier assigned by Heroku (e.g. d.a1b2c3d4-…). Useful for distinguishing drains when multiple apps write to the same Kloudfuse cluster.

timestamp

Log timestamp from the Logplex syslog frame (RFC 3164 format).

log_level

Severity extracted from the syslog priority field (e.g. info, error).

log_type

Source component within Heroku — app for dyno output, heroku for platform messages (router, scheduler, etc.).

app

Heroku application name.

dyno

Dyno identifier (e.g. web.1, worker.2).

Verify Logs Are Arriving

After adding the drain, generate some activity in your application, then confirm logs are arriving in the Kloudfuse UI:

  1. Click the Logs tab to open the Logs search view.

  2. In the Filters panel on the left, locate the Source facet and select heroku, or type heroku in the search bar to filter by source.

  3. Set the time range to the last 15 minutes using the interval picker in the top-right corner.

  4. Confirm that log entries appear in the list. Each entry shows the application name, dyno identifier, and log message text.

  5. Click any log row to open the Detail view. The Facets section displays parsed fields such as app, dyno, log_type, and log_level.

  6. To narrow results to a specific application or dyno type, click the app or log_type value in the Facets section and choose Filter By.

Remove the Log Drain

To stop forwarding logs, remove the drain by its URL:

heroku drains:remove "https://<kloudfuse-hostname>/ingester/heroku/logs" \
  --app <app-name>

If the URL is no longer known, list drains first to get the drain token, then remove by token:

heroku drains --app <app-name>
heroku drains:remove <drain-token> --app <app-name>

Troubleshooting

No Logs Appearing in Kloudfuse

If source="heroku" returns no results after adding the drain:

  1. Confirm the drain is listed and shows no error state:

    heroku drains --app <app-name>
  2. Tail the Heroku log stream to confirm log output is being generated:

    heroku logs --tail --app <app-name>
  3. Verify the Kloudfuse ingress hostname is reachable from Heroku’s network (Heroku dynos use public internet egress).

  4. Check that the URL is correct and does not contain any unintended characters introduced by shell quoting.

Authentication Failures

If the drain is listed but logs are not arriving and authentication is enabled:

  • Confirm the kf-api-key value is URL-encoded. Characters such as +, =, / in the token must be percent-encoded (e.g. %2B, %3D, %2F).

  • Verify the token is active in Admin > Settings > Auth key labels in the Kloudfuse UI.

  • Test the endpoint directly with curl to confirm the key works:

    curl -X POST "https://<kloudfuse-hostname>/ingester/heroku/logs?kf-api-key=<token>" \
      -H "Content-Type: application/logplex-1" \
      -d "83 <190>1 2024-01-01T00:00:00.000000+00:00 host app web.1 - test message"

    A 200 OK response confirms the endpoint and key are working.

Heroku Reports Drain Errors

If heroku drains --app <app-name> shows a drain in an error state:

  • Heroku retries failed drains and marks them healthy once delivery succeeds.

  • A sustained error state usually means the drain URL is unreachable — confirm the Kloudfuse hostname resolves and port 443 is open.

  • Remove and re-add the drain to reset the error state after fixing connectivity.