Add default retry for load config via url (#8803)

This commit is contained in:
Helen Weller 2021-02-12 11:38:40 -05:00 committed by GitHub
parent 2118681958
commit 71a3a3cf20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 9 deletions

View File

@ -49,6 +49,7 @@ var (
`"`, `\"`, `"`, `\"`,
`\`, `\\`, `\`, `\\`,
) )
httpLoadConfigRetryInterval = 10 * time.Second
) )
// Config specifies the URL/user/password for the database that telegraf // Config specifies the URL/user/password for the database that telegraf
@ -921,17 +922,27 @@ func fetchConfig(u *url.URL) ([]byte, error) {
} }
req.Header.Add("Accept", "application/toml") req.Header.Add("Accept", "application/toml")
req.Header.Set("User-Agent", internal.ProductToken()) req.Header.Set("User-Agent", internal.ProductToken())
resp, err := http.DefaultClient.Do(req)
if err != nil { retries := 3
return nil, err for i := 0; i <= retries; i++ {
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("Retry %d of %d failed connecting to HTTP config server %s", i, retries, err)
}
if resp.StatusCode != http.StatusOK {
if i < retries {
log.Printf("Error getting HTTP config. Retry %d of %d in %s. Status=%d", i, retries, httpLoadConfigRetryInterval, resp.StatusCode)
time.Sleep(httpLoadConfigRetryInterval)
continue
}
return nil, fmt.Errorf("Retry %d of %d failed to retrieve remote config: %s", i, retries, resp.Status)
}
defer resp.Body.Close()
return ioutil.ReadAll(resp.Body)
} }
if resp.StatusCode != http.StatusOK { return nil, nil
return nil, fmt.Errorf("failed to retrieve remote config: %s", resp.Status)
}
defer resp.Body.Close()
return ioutil.ReadAll(resp.Body)
} }
// parseConfig loads a TOML configuration from a provided path and // parseConfig loads a TOML configuration from a provided path and

View File

@ -1,6 +1,8 @@
package config package config
import ( import (
"net/http"
"net/http/httptest"
"os" "os"
"strings" "strings"
"testing" "testing"
@ -278,3 +280,37 @@ func TestConfig_AzureMonitorNamespacePrefix(t *testing.T) {
assert.Equal(t, "", azureMonitor.NamespacePrefix) assert.Equal(t, "", azureMonitor.NamespacePrefix)
assert.Equal(t, true, ok) assert.Equal(t, true, ok)
} }
func TestConfig_URLRetries3Fails(t *testing.T) {
httpLoadConfigRetryInterval = 0 * time.Second
responseCounter := 0
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
responseCounter++
}))
defer ts.Close()
c := NewConfig()
err := c.LoadConfig(ts.URL)
require.Error(t, err)
require.Equal(t, 4, responseCounter)
}
func TestConfig_URLRetries3FailsThenPasses(t *testing.T) {
httpLoadConfigRetryInterval = 0 * time.Second
responseCounter := 0
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if responseCounter <= 2 {
w.WriteHeader(http.StatusNotFound)
} else {
w.WriteHeader(http.StatusOK)
}
responseCounter++
}))
defer ts.Close()
c := NewConfig()
err := c.LoadConfig(ts.URL)
require.NoError(t, err)
require.Equal(t, 4, responseCounter)
}