Monitor Fly.io with Sazabi
Last verified on Nov 8, 2026.
Fly.io runs your apps as Machines in regions around the world, and each Machine writes to its own stdout. The platform turns that output into logs, and keeps them in an internal stream. A single customer request may touch Machines in two regions. The log lines for it are separate, unless something collects them.
Sazabi is AI-native observability and security. Fly gives you no managed log export, so the way in is a small shipper app that you run in your own organization.
What Sazabi reads from Fly.io
The shipper subscribes to the internal NATS log stream, which Fly serves to your apps at nats://[fdaa::3]:4223, and forwards what it reads. Sazabi's docs describe two shipper options. Option A is fly-log-shipper, configured by setting HTTP_URL to your intake URL plus the /fly-log-shipper path and HTTP_TOKEN to the shipper token. Option B is a dedicated Vector app that wraps each event in an OTLP resourceLogs envelope and posts it to the intake URL with the /v1/logs suffix, which gives richer resource attributes (Fly.io: Export logs).
Fly's own docs say the Log Shipper runs Vector and pulls logs from the internal stream, so it needs no inbound connections. That has a practical effect: remove the [http_service] section from its fly.toml and deploy it with fly deploy --no-public-ips.
The flyctl command is a separate connection. The Fly.io CLI connection gives the agent flyctl in its sandbox with a FLY_API_TOKEN.
Questions it answers
- Which Machine or region logged the error, and did the other regions stay quiet?
- Did logs from one app stop after a deploy, or did the shipper stop?
- Which app in the organization is the noisiest?
- What did the proxy log for a request that never reached my app?
- Is the same error appearing across every instance, or only one?
A worked example: shipping only the apps you care about
By default the shipper takes logs from every app in the organization. That is convenient and also expensive when a staging app is chatty. Fly's SUBJECT setting narrows the stream. Subjects have the form logs.<app_name>.<region>.<instance_id>, with * matching a segment and > matching the rest.
[env]
SUBJECT = "logs.checkout.>"This ships every region and instance of an app named checkout. To watch one region across all apps instead, use logs.*.dfw.>. Then check that the filter did what you meant by asking Sazabi:
sazabi logs ask "Which Fly.io apps sent logs in the last 15 minutes, and how many records did each send?"If an app you expected is absent, the subject is too narrow or the app lives in another organization. If an app you did not expect appears, the shipper is still reading the whole stream, so check that SUBJECT is set in the shipper's own fly.toml and not in the app you are monitoring.
Run the shipper so it keeps working
Fly warns that the Log Shipper can stop shipping without exiting. Add a top-level [checks] section that polls Vector's /health endpoint on port 8686, and read it with fly checks list. If you run more than one shipper Machine for availability, set QUEUE to the same name on each so NATS delivers each message to only one of them. Without it you will get duplicate records.
How it fits with other integrations
Fly.io hosts your compute, and the data tier is often somewhere else, such as Neon or Supabase. Option B speaks OTLP, which is covered by the OpenTelemetry integration. Compare other platforms under cloud platforms, or see Railway for another service where your app has to push its own logs.
Log sources
- Fly.io (manual log source, cloud platforms): Run a fly-log-shipper or Vector app inside your Fly organization pointed at your Sazabi intake URL to forward application logs from all Fly apps.
What Sazabi detects from these logs today
These detections are on for every production project, with no monitors or alert rules to write. Sazabi opens an issue when one fires.
- Novel event: A kind of error that has never appeared before.
Frequently Asked Questions
Does Fly.io have a log export I can point at Sazabi?
No. Fly.io has no managed API for exporting logs, so you run a log shipper app inside your Fly organization. It reads Fly's internal NATS log stream and forwards the logs to your Sazabi intake URL.
Which shipper should I use?
fly-log-shipper is the recommended option. Use the dedicated Vector app when you want richer OTLP resource attributes, because it wraps each event in an OTLP resourceLogs envelope and posts to the intake URL with a /v1/logs suffix.
Why does the shipper need a token?
Fly's log shipper requires one. HTTP_TOKEN must be the shipper token from the Sazabi setup screen, not a Fly.io API token. The intake URL already identifies your log source.
Only some of my apps show up. What is wrong?
The shipper reads the organization-level NATS stream, so it only sees apps in its own organization. Confirm the shipper app is in the same Fly organization as the apps that are missing.
Sources
- No managed API for exporting logs; fly-log-shipper or an OTLP Vector app reads Fly's NATS stream and forwards every app in the organization; HTTP_URL path suffix and HTTP_TOKEN (accessed Nov 8, 2026)
- flyctl in the agent sandbox with FLY_API_TOKEN and optional FLY_TOKEN_TYPE (accessed Nov 8, 2026)
- Log Shipper runs Vector on the internal NATS stream at nats://[fdaa::3]:4223, SUBJECT format logs.<app_name>.<region>.<instance_id> with * and > wildcards, QUEUE for multiple shippers, /health check on port 8686 (accessed Nov 8, 2026)