diff --git a/README.md b/README.md index 8a48a41..6c0e1c7 100644 --- a/README.md +++ b/README.md @@ -41,20 +41,23 @@ To authenticate this way, set both `CF_API_KEY` and `CF_API_EMAIL`. ## Configuration The exporter can be configured using env variables or command flags. -| **KEY** | **description** | -|-|-| -| `CF_API_EMAIL` | user email (see https://support.cloudflare.com/hc/en-us/articles/200167836-Managing-API-Tokens-and-Keys) | -| `CF_API_KEY` | API key associated with email (`CF_API_EMAIL` is required if this is set)| -| `CF_API_TOKEN` | API authentication token (recommended before API key + email. Version 0.0.5+. see https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth) | -| `CF_ZONES` | (Optional) cloudflare zones to export, comma delimited list of zone ids. If not set, all zones from account are exported | -| `CF_EXCLUDE_ZONES` | (Optional) cloudflare zones to exclude, comma delimited list of zone ids. If not set, no zones from account are excluded | -| `FREE_TIER` | (Optional) scrape only metrics included in free plan. Accepts `true` or `false`, default `false`. | -| `LISTEN` | listen on addr:port (default `:8080`), omit addr to listen on all interfaces | -| `METRICS_PATH` | path for metrics, default `/metrics` | -| `SCRAPE_DELAY` | scrape delay in seconds, default `300` | -| `CF_BATCH_SIZE` | cloudflare request zones batch size (1 - 10), default `10` | -| `METRICS_DENYLIST` | (Optional) cloudflare-exporter metrics to not export, comma delimited list of cloudflare-exporter metrics. If not set, all metrics are exported | -| `ZONE_` | `DEPRECATED since 0.0.5` (optional) Zone ID. Add zones you want to scrape by adding env vars in this format. You can find the zone ids in Cloudflare dashboards. | +| **KEY** | **description** | +|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `CF_API_EMAIL` | user email (see https://support.cloudflare.com/hc/en-us/articles/200167836-Managing-API-Tokens-and-Keys) | +| `CF_API_KEY` | API key associated with email (`CF_API_EMAIL` is required if this is set) | +| `CF_API_TOKEN` | API authentication token (recommended before API key + email. Version 0.0.5+. see https://developers.cloudflare.com/analytics/graphql-api/getting-started/authentication/api-token-auth) | +| `CF_ZONES` | (Optional) cloudflare zones to export, comma delimited list of zone ids. If not set, all zones from account are exported | +| `CF_EXCLUDE_ZONES` | (Optional) cloudflare zones to exclude, comma delimited list of zone ids. If not set, no zones from account are excluded | +| `CF_MAX_RETRIES` | (Optional) max retries for cloudflare api, default `3` | +| `CF_MIN_RETRY_DELAY` | (Optional) min retry delay for cloudflare api, default `1s` | +| `CF_MAX_RETRY_DELAY` | (Optional) max retry delay for cloudflare api, default `10s` | +| `FREE_TIER` | (Optional) scrape only metrics included in free plan. Accepts `true` or `false`, default `false`. | +| `LISTEN` | listen on addr:port (default `:8080`), omit addr to listen on all interfaces | +| `METRICS_PATH` | path for metrics, default `/metrics` | +| `SCRAPE_DELAY` | scrape delay in seconds, default `300` | +| `CF_BATCH_SIZE` | cloudflare request zones batch size (1 - 10), default `10` | +| `METRICS_DENYLIST` | (Optional) cloudflare-exporter metrics to not export, comma delimited list of cloudflare-exporter metrics. If not set, all metrics are exported | +| `ZONE_` | `DEPRECATED since 0.0.5` (optional) Zone ID. Add zones you want to scrape by adding env vars in this format. You can find the zone ids in Cloudflare dashboards. | Corresponding flags: ``` @@ -63,6 +66,9 @@ Corresponding flags: -cf_api_token="": cloudflare api token (version 0.0.5+, preferred) -cf_zones="": cloudflare zones to export, comma delimited list -cf_exclude_zones="": cloudflare zones to exclude, comma delimited list + -cf_max_retries="3": max retries for cloudflare api, defaults to 3 + -cf_min_retry_delay="1s": min retry delay for cloudflare api, defaults to 1s + -cf_max_retry_delay="10s": max retry delay for cloudflare api, defaults to 10s -free_tier=false: scrape only metrics included in free plan, default false -listen=":8080": listen on addr:port ( default :8080), omit addr to listen on all interfaces -metrics_path="/metrics": path for metrics, default /metrics diff --git a/cloudflare.go b/cloudflare.go index 4b96d94..b35fe97 100644 --- a/cloudflare.go +++ b/cloudflare.go @@ -254,9 +254,9 @@ func fetchZones() []cloudflare.Zone { var api *cloudflare.API var err error if len(viper.GetString("cf_api_token")) > 0 { - api, err = cloudflare.NewWithAPIToken(viper.GetString("cf_api_token")) + api, err = cloudflare.NewWithAPIToken(viper.GetString("cf_api_token"), newRetryPolicy()) } else { - api, err = cloudflare.New(viper.GetString("cf_api_key"), viper.GetString("cf_api_email")) + api, err = cloudflare.New(viper.GetString("cf_api_key"), viper.GetString("cf_api_email"), newRetryPolicy()) } if err != nil { log.Fatal(err) @@ -275,9 +275,9 @@ func fetchFirewallRules(zoneID string) map[string]string { var api *cloudflare.API var err error if len(viper.GetString("cf_api_token")) > 0 { - api, err = cloudflare.NewWithAPIToken(viper.GetString("cf_api_token")) + api, err = cloudflare.NewWithAPIToken(viper.GetString("cf_api_token"), newRetryPolicy()) } else { - api, err = cloudflare.New(viper.GetString("cf_api_key"), viper.GetString("cf_api_email")) + api, err = cloudflare.New(viper.GetString("cf_api_key"), viper.GetString("cf_api_email"), newRetryPolicy()) } if err != nil { log.Fatal(err) @@ -319,9 +319,9 @@ func fetchAccounts() []cloudflare.Account { var api *cloudflare.API var err error if len(viper.GetString("cf_api_token")) > 0 { - api, err = cloudflare.NewWithAPIToken(viper.GetString("cf_api_token")) + api, err = cloudflare.NewWithAPIToken(viper.GetString("cf_api_token"), newRetryPolicy()) } else { - api, err = cloudflare.New(viper.GetString("cf_api_key"), viper.GetString("cf_api_email")) + api, err = cloudflare.New(viper.GetString("cf_api_key"), viper.GetString("cf_api_email"), newRetryPolicy()) } if err != nil { log.Fatal(err) @@ -786,3 +786,11 @@ func filterNonFreePlanZones(zones []cloudflare.Zone) (filteredZones []cloudflare } return } + +func newRetryPolicy() cloudflare.Option { + return cloudflare.UsingRetryPolicy( + viper.GetInt("cf_max_retries"), + int(viper.GetDuration("cf_min_retry_delay").Seconds()), + int(viper.GetDuration("cf_max_retry_delay").Seconds()), + ) +} diff --git a/main.go b/main.go index c31f522..1052a5a 100644 --- a/main.go +++ b/main.go @@ -247,6 +247,18 @@ func main() { viper.BindEnv("metrics_denylist") viper.SetDefault("metrics_denylist", "") + flags.Int("cf_max_retries", 3, "max retries for cloudflare api, defaults to 3") + viper.BindEnv("cf_max_retries") + viper.SetDefault("cf_max_retries", 3) + + flags.Duration("cf_min_retry_delay", 1*time.Second, "min retry delay for cloudflare api, defaults to 1s") + viper.BindEnv("cf_min_retry_delay") + viper.SetDefault("cf_min_retry_delay", 1*time.Second) + + flags.Duration("cf_max_retry_delay", 10*time.Second, "max retry delay for cloudflare api, defaults to 10s") + viper.BindEnv("cf_max_retry_delay") + viper.SetDefault("cf_max_retry_delay", 10*time.Second) + viper.BindPFlags(flags) cmd.Execute() }