Support custom success codes in http input (#6549)

This commit is contained in:
Dheeraj Dwivedi 2019-10-22 02:53:36 +05:30 committed by Daniel Nelson
parent 3802c8b8cb
commit a01d273c45
4 changed files with 51 additions and 4 deletions

View File

@ -2604,6 +2604,9 @@
# ## Amount of time allowed to complete the HTTP request # ## Amount of time allowed to complete the HTTP request
# # timeout = "5s" # # timeout = "5s"
# #
# ## List of success status codes
# # success_status_codes = [200]
#
# ## Data format to consume. # ## Data format to consume.
# ## Each data format has its own unique set of configuration options, read # ## Each data format has its own unique set of configuration options, read
# ## more about them here: # ## more about them here:

View File

@ -40,6 +40,9 @@ The HTTP input plugin collects metrics from one or more HTTP(S) endpoints. The
## Amount of time allowed to complete the HTTP request ## Amount of time allowed to complete the HTTP request
# timeout = "5s" # timeout = "5s"
## List of success status codes
# success_status_codes = [200]
## Data format to consume. ## Data format to consume.
## Each data format has its own unique set of configuration options, read ## Each data format has its own unique set of configuration options, read
## more about them here: ## more about them here:

View File

@ -29,6 +29,8 @@ type HTTP struct {
Password string `toml:"password"` Password string `toml:"password"`
tls.ClientConfig tls.ClientConfig
SuccessStatusCodes []int `toml:"success_status_codes"`
Timeout internal.Duration `toml:"timeout"` Timeout internal.Duration `toml:"timeout"`
client *http.Client client *http.Client
@ -71,6 +73,9 @@ var sampleConfig = `
## Amount of time allowed to complete the HTTP request ## Amount of time allowed to complete the HTTP request
# timeout = "5s" # timeout = "5s"
## List of success status codes
# success_status_codes = [200]
## Data format to consume. ## Data format to consume.
## Each data format has its own unique set of configuration options, read ## Each data format has its own unique set of configuration options, read
## more about them here: ## more about them here:
@ -101,6 +106,11 @@ func (h *HTTP) Init() error {
}, },
Timeout: h.Timeout.Duration, Timeout: h.Timeout.Duration,
} }
// Set default as [200]
if len(h.SuccessStatusCodes) == 0 {
h.SuccessStatusCodes = []int{200}
}
return nil return nil
} }
@ -171,12 +181,19 @@ func (h *HTTP) gatherURL(
} }
defer resp.Body.Close() defer resp.Body.Close()
if resp.StatusCode != http.StatusOK { responseHasSuccessCode := false
return fmt.Errorf("Received status code %d (%s), expected %d (%s)", for _, statusCode := range h.SuccessStatusCodes {
if resp.StatusCode == statusCode {
responseHasSuccessCode = true
break
}
}
if !responseHasSuccessCode {
return fmt.Errorf("received status code %d (%s), expected any value out of %v",
resp.StatusCode, resp.StatusCode,
http.StatusText(resp.StatusCode), http.StatusText(resp.StatusCode),
http.StatusOK, h.SuccessStatusCodes)
http.StatusText(http.StatusOK))
} }
b, err := ioutil.ReadAll(resp.Body) b, err := ioutil.ReadAll(resp.Body)

View File

@ -106,6 +106,30 @@ func TestInvalidStatusCode(t *testing.T) {
require.Error(t, acc.GatherError(plugin.Gather)) require.Error(t, acc.GatherError(plugin.Gather))
} }
func TestSuccessStatusCodes(t *testing.T) {
fakeServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusAccepted)
}))
defer fakeServer.Close()
url := fakeServer.URL + "/endpoint"
plugin := &plugin.HTTP{
URLs: []string{url},
SuccessStatusCodes: []int{200, 202},
}
metricName := "metricName"
p, _ := parsers.NewParser(&parsers.Config{
DataFormat: "json",
MetricName: metricName,
})
plugin.SetParser(p)
var acc testutil.Accumulator
plugin.Init()
require.NoError(t, acc.GatherError(plugin.Gather))
}
func TestMethod(t *testing.T) { func TestMethod(t *testing.T) {
fakeServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fakeServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" { if r.Method == "POST" {