A log drain sends every line the organization's services write on to where you keep logs already, about a minute after it's written. Add one under Settings → Log drains (admins), or from the command line:
alf drains add datadog --api-key … # --site datadoghq.eu for the EU
alf drains add betterstack --token …
alf drains add axiom --token … --dataset shop
alf drains add https --url https://logs.example.com/in
alf drains add s3 --bucket my-logs --region eu-central-1 --access-key-id … --secret-access-key …
alf drains add bucket --bucket logs # one of your Alf buckets
alf drains test datadog # a test line, now
alf drains # each one, and how it's doing
Keys left out are asked for at a terminal without being shown, and aren't shown again afterwards. --project keeps a drain to one project's services.
Each line with where it came from:
{"at": "2026-10-30T13:04:05.123456789Z", "service": "web", "service_id": "svc_…", "project": "shop", "stream": "stderr", "server": "srv_…", "container": 1, "line": "TypeError: …"}
| Drain | How |
|---|---|
| Datadog | Its logs intake (ddsource: alf, the service as service, project: and stream: as tags). |
| Better Stack | Its HTTP source, with dt and message. |
| Axiom | The dataset's ingest, with _time and message. |
| HTTPS | A POST of NDJSON (one line as above per line of the body), with X-Alf-Signature: sha256=…, an HMAC-SHA256 of the body with the secret shown once when the drain is added. |
| S3, an Alf bucket | One gzipped NDJSON file per delivery, under <prefix><date>/. Any S3: --endpoint for one that isn't AWS (Cloudflare R2, MinIO and the like). |
A drain that can't deliver tries again later, waiting longer each time, up to an hour. After a day of failing it's switched off, and the organization hears about it (the A log drain kept failing notification). Switch on (or PATCH /log-drains/{id} with enabled: true) carries on from where it stopped: lines are kept three days, so a drain off for longer misses the oldest.