Fly.io is an app hosting platform that lets you run full-stack apps close to your users. SigNoz supports two signals from Fly.io:
- Logs — forwarded via fly-log-shipper, a Vector-based log draining app. SigNoz is a named provider in fly-log-shipper.
- Metrics — scraped from Fly's Prometheus federation endpoint using the OpenTelemetry Collector. See the full Fly.io Metrics guide.
Prerequisites
- A
SigNoz Cloud(or self-hosted) workspace Fly CLIinstalled and a Fly.io account
Forward Logs
Fly.io logs are forwarded to SigNoz using fly-log-shipper — a Fly app that runs Vector and drains logs from your entire Fly.io organisation.
Step 1: Clone fly-log-shipper
git clone https://github.com/superfly/fly-log-shipper.git
cd fly-log-shipperStep 2: Create the shipper app (without deploying yet)
fly launch --no-deployThis creates a new Fly app in your organisation without starting it.
Step 3: Create a read-only access token
fly tokens create readonly personalSave the token value — you will set it as a secret in the next step.
Step 4: Set the required secrets
fly secrets set \
ACCESS_TOKEN="<your-readonly-fly-token>" \
SIGNOZ_INGESTION_KEY="<your-signoz-ingestion-key>" \
SIGNOZ_INGESTION_URL="https://ingest.<region>.signoz.cloud:443"Replace:
<your-readonly-fly-token>— the token from Step 3<your-signoz-ingestion-key>— your SigNoz ingestion key<region>— your SigNoz Cloud region (e.g.us,eu). See regions.
Step 5: Deploy
fly deployOnce deployed, fly-log-shipper begins draining logs from all apps in the organisation and forwarding them to SigNoz.
Step 6: Verify logs in SigNoz
Open Logs Explorer in SigNoz. Within a minute you should see log entries with Fly.io-specific attributes such as app, region, and instance_id.
Troubleshooting
- fly-log-shipper not running — run
fly statusinside thefly-log-shipperdirectory and confirm the app is in arunningstate. - Wrong secrets — re-check
ACCESS_TOKEN,SIGNOZ_INGESTION_KEY, andSIGNOZ_INGESTION_URLwithfly secrets list. Update them withfly secrets setand redeploy. - Token scope — ensure the token was created with
fly tokens create readonly personal, not a deploy token.
Collect Metrics
Fly.io exposes application and infrastructure metrics via a Prometheus federation endpoint. The OpenTelemetry Collector scrapes this endpoint and forwards metrics to SigNoz. For the full reference, see Fly.io Metrics.
Step 1: Create an org metrics token
Generate a token at the org scope:
fly tokens create org --org <your-org-slug>This prints a value beginning with FlyV1 .... Save only the raw part after FlyV1 to a file (do not include the prefix):
# Save the raw token (without the "FlyV1 " prefix)
echo '<RAW_TOKEN_AFTER_FlyV1>' > fly_federate_tokenStep 2: Configure the OpenTelemetry Collector
Follow instructions here to install OpenTelemetry Binary as an agent
Update config.yaml in the otelcol-contrib folder with the following:
receivers:
prometheus:
config:
scrape_configs:
- job_name: fly-federate
scheme: https
metrics_path: /prometheus/<your-org-slug>/federate # e.g., /prometheus/personal/federate
params:
match[]: ['{__name__=~"fly_.*"}']
static_configs:
- targets: ["api.fly.io"]
authorization:
type: FlyV1
credentials_file: /etc/otel/secret/fly_federate_tokenReplace <your-org-slug> with your actual organization slug. Then add the prometheus receiver to your receivers configuration.
processors:
transform/fly_metrics:
error_mode: ignore
metric_statements:
- context: datapoint
statements:
- 'convert_gauge_to_sum("cumulative", true) where IsMatch(metric.name, "^fly_.*_count$") or metric.name == "fly_instance_cpu" or metric.name == "fly_instance_net_sent_bytes" or metric.name == "fly_instance_net_recv_bytes"'Add the transform/fly_metrics processor to your processors configuration.
exporters:
otlphttp:
endpoint: "https://ingest.{region}.signoz.cloud:443"
headers:
signoz-access-token: <YOUR_SIGNOZ_API_KEY>Replace {region} with your SigNoz Cloud region and <YOUR_SIGNOZ_API_KEY> with your Ingestion Key.
service:
telemetry:
logs:
level: debug
pipelines:
metrics:
receivers: [prometheus]
processors: [transform/fly_metrics, batch]
exporters: [otlphttp]Step 3: Run the Collector
./otelcol-contrib --config ./config.yamlInstall the OpenTelemetry Collector for Docker.
Update otel.yaml with the following:
receivers:
prometheus:
config:
scrape_configs:
- job_name: fly-federate
scheme: https
metrics_path: /prometheus/<your-org-slug>/federate
params:
match[]: ['{__name__=~"fly_.*"}']
static_configs:
- targets: ["api.fly.io"]
authorization:
type: FlyV1
credentials_file: /etc/otel/secret/fly_federate_tokenReplace <your-org-slug> with your actual organization slug.
processors:
transform/fly_metrics:
error_mode: ignore
metric_statements:
- context: datapoint
statements:
- 'convert_gauge_to_sum("cumulative", true) where IsMatch(metric.name, "^fly_.*_count$") or metric.name == "fly_instance_cpu" or metric.name == "fly_instance_net_sent_bytes" or metric.name == "fly_instance_net_recv_bytes"'exporters:
otlphttp:
endpoint: "https://ingest.{region}.signoz.cloud:443"
headers:
signoz-access-token: <YOUR_SIGNOZ_API_KEY>Replace {region} with your SigNoz Cloud region and <YOUR_SIGNOZ_API_KEY> with your Ingestion Key.
service:
telemetry:
logs:
level: debug
pipelines:
metrics:
receivers: [prometheus]
processors: [transform/fly_metrics, batch]
exporters: [otlphttp]Step 3: Run the Collector
docker run --rm -it \
-v "$(pwd)/otel.yaml:/etc/otel/config.yaml" \
-v "$(pwd)/fly_federate_token:/etc/otel/secret/fly_federate_token:ro" \
otel/opentelemetry-collector-contrib:0.103.1 \
--config /etc/otel/config.yamlInstall the SigNoz K8s Infra chart.
Create the namespace (if needed):
kubectl create namespace signozCreate the secret for the Fly token:
kubectl create secret generic fly-federate-token \
--from-file=fly_federate_token=./fly_federate_token \
-n signozUpdate override-values.yaml:
global:
cloud: others
clusterName: <CLUSTER_NAME>
deploymentEnvironment: <DEPLOYMENT_ENVIRONMENT>
otelCollectorEndpoint: ingest.{region}.signoz.cloud:443
otelInsecure: false
signozApiKey: <your-ingestion-key>
otelAgent:
image:
repository: otel/opentelemetry-collector-contrib
tag: 0.103.1
config:
receivers:
prometheus:
config:
scrape_configs:
- job_name: fly-federate
scheme: https
metrics_path: /prometheus/<your-org-slug>/federate
params:
match[]: ['{__name__=~"fly_.*"}']
static_configs:
- targets: ["api.fly.io"]
authorization:
type: FlyV1
credentials_file: /etc/otel/secret/fly_federate_token
processors:
transform/fly_metrics:
error_mode: ignore
metric_statements:
- context: datapoint
statements:
- 'convert_gauge_to_sum("cumulative", true) where IsMatch(metric.name, "^fly_.*_count$") or metric.name == "fly_instance_cpu" or metric.name == "fly_instance_net_sent_bytes" or metric.name == "fly_instance_net_recv_bytes"'
exporters:
otlphttp:
endpoint: https://ingest.{region}.signoz.cloud:443
headers:
signoz-access-token: <your-ingestion-key>
service:
pipelines:
metrics:
receivers: [prometheus]
processors: [transform/fly_metrics, batch]
exporters: [otlphttp]
extraVolumes:
- name: fly-token
secret:
secretName: fly-federate-token
extraVolumeMounts:
- name: fly-token
mountPath: /etc/otel/secret/fly_federate_token
subPath: fly_federate_token
readOnly: trueStep 3: Deploy the chart
helm install my-release signoz/k8s-infra -f override-values.yamlVerify the federation endpoint
Generate some traffic and confirm metrics are returned:
curl -sS -i -G \
-H "Authorization: FlyV1 $(cat fly_federate_token)" \
--data-urlencode 'match[]={__name__=~"fly_.*"}' \
https://api.fly.io/prometheus/<your-org-slug>/federate | head -n 40You should see lines like fly_instance_cpu_user_seconds_total, fly_instance_memory_resident, etc.
Troubleshooting
- Wrong org slug — confirm
<your-org-slug>inmetrics_pathmatches the output offly orgs list. - Token format — the token file must contain only the raw value after
FlyV1(no prefix, no trailing newline). - Gauge vs counter — Fly's federation endpoint does not expose metric types; all metrics default to Gauge. Use the
transform/fly_metricsprocessor to convert counters. See Fly.io Metrics for details.
Pre-built Dashboard
A pre-built Fly.io Prometheus dashboard is available to import directly into SigNoz:
Recommended. Uses the V2 dashboard schema and needs SigNoz v0.135.0 or newer.
Import it in SigNoz with Dashboards → + New dashboard → Import JSON. Import guide

Next Steps
- Set up metric-based alerts on Fly.io app metrics.
- Set up log-based alerts to get notified on error patterns in Fly.io logs.
- Create a dashboard to combine Fly.io metrics and logs in a single view.
Get Help
If you need help with the steps in this topic, please reach out to us on SigNoz Community Slack. If you are a SigNoz Cloud user, please use in product chat support located at the bottom right corner of your SigNoz instance or contact us at cloud-support@signoz.io.