Skip to content

aymanbagabas/cloudflare-prometheus-exporter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cloudflare-prometheus-exporter

A self-hostable Prometheus exporter for Cloudflare metrics. Runs as a standalone Go binary with no runtime dependencies.

Metrics

Zone-level (GraphQL — paid zones only)

Metric Type Labels
cloudflare_zone_requests_total counter zone
cloudflare_zone_requests_cached gauge zone
cloudflare_zone_requests_ssl_encrypted_total counter zone
cloudflare_zone_requests_content_type_total counter zone, content_type
cloudflare_zone_requests_country_total counter zone, country
cloudflare_zone_requests_status_total counter zone, status
cloudflare_zone_requests_browser_map_page_views_total counter zone, family
cloudflare_zone_requests_ip_class_total counter zone, ip_type
cloudflare_zone_requests_ssl_protocol_total counter zone, ssl_protocol
cloudflare_zone_requests_http_version_total counter zone, http_version
cloudflare_zone_bandwidth_total counter zone
cloudflare_zone_bandwidth_cached_total counter zone
cloudflare_zone_bandwidth_ssl_encrypted_total counter zone
cloudflare_zone_bandwidth_content_type_total counter zone, content_type
cloudflare_zone_bandwidth_country_total counter zone, country
cloudflare_zone_threats_total counter zone
cloudflare_zone_threats_country_total counter zone, country
cloudflare_zone_threats_type_total counter zone, type
cloudflare_zone_pageviews_total counter zone
cloudflare_zone_uniques_total counter zone
cloudflare_zone_cache_hit_ratio gauge zone
cloudflare_zone_firewall_events_total counter zone, action, source, rule, host, country
cloudflare_zone_firewall_bots_detected_total counter zone, bot_score, detection_source
cloudflare_zone_bot_requests_by_country_total counter zone, country
cloudflare_zone_customer_error_4xx_total counter zone, status, country, host
cloudflare_zone_customer_error_5xx_total counter zone, status, country, host
cloudflare_zone_origin_response_duration_seconds gauge zone, status, country, host
cloudflare_zone_origin_error_rate gauge zone
cloudflare_zone_requests_status_country_host_total counter zone, edge_status, country, host
cloudflare_zone_edge_error_rate gauge zone
cloudflare_zone_colocation_visits_total counter zone, colo, host
cloudflare_zone_colocation_edge_response_bytes_total counter zone, colo, host
cloudflare_zone_colocation_requests_total counter zone, colo, host, status
cloudflare_zone_colocation_requests_status_total counter zone, colo, host, status
cloudflare_zone_requests_method_total counter zone, method
cloudflare_zone_health_check_events_total counter zone, health_status, origin_ip, region, fqdn, failure_reason
cloudflare_zone_health_check_rtt_avg_ms gauge zone, origin_ip, region, fqdn
cloudflare_zone_health_check_ttfb_avg_ms gauge zone, origin_ip, region, fqdn
cloudflare_zone_lb_pool_requests_total counter zone, lb, pool, origin, region
cloudflare_zone_lb_pool_healthy gauge zone, lb, pool
cloudflare_zone_lb_pool_rtt_avg_ms gauge zone, lb, pool
cloudflare_zone_lb_origins_selected_total counter zone, lb, steering_policy
cloudflare_zone_logpush_failed_jobs_total counter zone, job_id, status, destination_type
cloudflare_zone_origin_status_total counter zone, status, country, host
cloudflare_zone_cache_miss_origin_response_duration_seconds gauge zone, country, host

Zone-level (REST — all zones)

Metric Type Labels
cloudflare_zone_ssl_certificate_expiry_timestamp gauge zone, cert_id, type, issuer, status
cloudflare_zone_lb_pool_origin_weight gauge zone, lb, pool, origin, address

Zone-level — Hostname (GraphQL — requires HOST_METRICS_ALLOWLIST)

All gauges — window snapshots fetched over 1h and 2h lookback windows from the current maxtime. The window label is 1h or 2h.

Metric Type Labels
cloudflare_zone_hostname_requests gauge zone, host, window
cloudflare_zone_hostname_requests_by_status gauge zone, host, status, window
cloudflare_zone_hostname_cache_status gauge zone, host, cache_status, window
cloudflare_zone_hostname_edge_ttfb_seconds gauge zone, host, quantile, window
cloudflare_zone_hostname_origin_response_duration_seconds gauge zone, host, quantile, window

Account-level — Magic Transit (GraphQL)

Metric Type Labels
cloudflare_magic_transit_active_tunnels gauge account, tunnel_name, site_name
cloudflare_magic_transit_healthy_tunnels gauge account, tunnel_name, site_name
cloudflare_magic_transit_tunnel_failures gauge account, tunnel_name, site_name
cloudflare_magic_transit_edge_colo_count gauge account, tunnel_name, site_name
cloudflare_magic_transit_tunnel_failure_by_status gauge account, tunnel_name, site_name, result_status
cloudflare_magic_transit_tunnel_state_healthy gauge account, tunnel_name, site_name
cloudflare_magic_transit_tunnel_state_degraded gauge account, tunnel_name, site_name
cloudflare_magic_transit_tunnel_state_down gauge account, tunnel_name, site_name
cloudflare_magic_transit_tunnel_slo_status gauge account, tunnel_name, site_name, status
cloudflare_magic_transit_tunnel_effective_slo gauge account, tunnel_name, site_name
cloudflare_magic_transit_tunnel_target_slo gauge account, tunnel_name, site_name
cloudflare_magic_transit_tunnel_traffic_bits_total counter account, tunnel_name, direction, on_ramp, off_ramp
cloudflare_magic_transit_tunnel_traffic_packets_total counter account, tunnel_name, direction, on_ramp, off_ramp
cloudflare_magic_firewall_rule_bits_total counter account, rule_id
cloudflare_magic_firewall_rule_packets_total counter account, rule_id

Account-level (GraphQL)

Metric Type Labels
cloudflare_worker_requests_total counter account, script_name
cloudflare_worker_errors_total counter account, script_name
cloudflare_worker_cpu_time_seconds gauge account, script_name, quantile
cloudflare_worker_duration_seconds gauge account, script_name, quantile
cloudflare_logpush_failed_jobs_account_total counter account, job_id, status, destination_type
cloudflare_stream_video_playback_count_total counter account, country, media_type
cloudflare_stream_video_playback_time_viewed_seconds_total counter account, country, media_type
cloudflare_stream_live_input_segments_total counter account, event_code
cloudflare_stream_live_input_bit_rate_bps gauge account, event_code
cloudflare_stream_live_input_gop_duration_seconds gauge account, event_code
cloudflare_stream_live_input_upload_duration_ratio gauge account, event_code
cloudflare_network_analytics_magic_transit_bits_total counter account, outcome, direction, ip_protocol, mitigation_system
cloudflare_network_analytics_magic_transit_packets_total counter account, outcome, direction, ip_protocol, mitigation_system
cloudflare_network_analytics_magic_firewall_bits_total counter account, outcome, direction, ip_protocol
cloudflare_network_analytics_magic_firewall_packets_total counter account, outcome, direction, ip_protocol
cloudflare_network_analytics_dosd_bits_total counter account, outcome, direction, ip_protocol, attack_vector
cloudflare_network_analytics_dosd_packets_total counter account, outcome, direction, ip_protocol, attack_vector
cloudflare_network_analytics_idps_bits_total counter account, outcome, direction, ip_protocol
cloudflare_network_analytics_idps_packets_total counter account, outcome, direction, ip_protocol
cloudflare_network_analytics_tcp_protection_bits_total counter account, outcome, direction, ip_protocol
cloudflare_network_analytics_tcp_protection_packets_total counter account, outcome, direction, ip_protocol
cloudflare_network_analytics_dns_protection_bits_total counter account, outcome, direction, ip_protocol
cloudflare_network_analytics_dns_protection_packets_total counter account, outcome, direction, ip_protocol

Exporter self-metrics

Metric Type Labels
cloudflare_exporter_up gauge
cloudflare_exporter_accounts_total gauge
cloudflare_exporter_zones_total gauge account
cloudflare_exporter_errors_total counter account, error_code

Configuration

All configuration is via environment variables. No config files.

Variable Default Description
CF_API_TOKEN required Cloudflare API token with Analytics:Read scope
CF_ACCOUNTS (all) Comma-separated account ID allowlist
CF_ZONES (all) Comma-separated zone ID allowlist
CF_FREE_TIER_ACCOUNTS Comma-separated account IDs to treat as free tier (skips paid-only GraphQL queries)
METRIC_REFRESH_INTERVAL 60s How often to fetch metrics from Cloudflare
SCRAPE_DELAY 5m Lookback offset to account for Cloudflare analytics ingestion lag
TIME_WINDOW 1m Size of each query window
ACCOUNT_CACHE_TTL 10m How often to refresh the account list
ZONE_CACHE_TTL 30m How often to refresh zone lists
SSL_CACHE_TTL 30m How often to refresh SSL certificate data
HEALTH_CACHE_TTL 10s Health check result cache duration
METRICS_PATH /metrics Path to expose Prometheus metrics on
METRICS_DENYLIST Comma-separated metric name prefixes to exclude from output
CF_HTTP_STATUS_GROUP false Group HTTP status codes into 2xx/4xx/5xx buckets
LISTEN_ADDR :8080 Address and port to listen on
HOST_METRICS_ALLOWLIST Comma-separated list of hostnames (max 50) to collect per-host metrics for
QUERY_LIMIT 10000 Maximum rows per GraphQL query
LOG_LEVEL info Log level: debug, info, warn, error
LOG_FORMAT json Log format: json or text

API Token Permissions

Create a token at My Profile → API Tokens with:

  • Zone → Analytics → Read (for zone-level metrics)
  • Account → Analytics → Read (for account-level metrics: Workers, Stream, Network Analytics)
  • Zone → Zone → Read (for zone listing)

Scope the token to the accounts/zones you want to monitor.

Running

Docker

docker run -e CF_API_TOKEN=your_token ghcr.io/aymanbagabas/cloudflare-prometheus-exporter:latest

Binary

CF_API_TOKEN=your_token ./cloudflare-prometheus-exporter

Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cloudflare-exporter
spec:
  replicas: 1
  selector:
    matchLabels:
      app: cloudflare-exporter
  template:
    metadata:
      labels:
        app: cloudflare-exporter
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "8080"
        prometheus.io/path: "/metrics"
    spec:
      containers:
        - name: exporter
          image: ghcr.io/aymanbagabas/cloudflare-prometheus-exporter:latest
          ports:
            - containerPort: 8080
          env:
            - name: CF_API_TOKEN
              valueFrom:
                secretKeyRef:
                  name: cloudflare-exporter
                  key: api-token
          resources:
            requests:
              cpu: 50m
              memory: 32Mi
            limits:
              cpu: 200m
              memory: 128Mi

Building

make build   # produces ./cloudflare-prometheus-exporter binary
make docker  # builds Docker image
make run     # go run .

Endpoints

Path Description
GET /metrics Prometheus metrics (text format)
GET /health JSON health check — checks Cloudflare API and GraphQL reachability

Free Tier Notes

Zone-level GraphQL queries (httpRequestsAdaptiveGroups, etc.) require a paid Cloudflare plan. Free zones are automatically detected via plan ID and skipped for those queries. SSL certificate and load balancer weight metrics (REST-based) work on all plans.

If your account is entirely on the free plan, add it to CF_FREE_TIER_ACCOUNTS to skip account-level queries that require paid features (Stream, etc.).

License

MIT — see LICENSE.

About

Cloudfront Prometheus exporter

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages