Allow collection of HTTP Headers in http_response input (#7405)
This commit is contained in:
parent
40fdafe193
commit
7ef1d53551
|
@ -47,6 +47,11 @@ This input plugin checks HTTP/HTTPS connections.
|
|||
# [inputs.http_response.headers]
|
||||
# Host = "github.com"
|
||||
|
||||
## Optional setting to map reponse http headers into tags
|
||||
## If the http header is not present on the request, no corresponding tag will be added
|
||||
## If multiple instances of the http header are present, only the first value will be used
|
||||
# http_header_tags = {"HTTP_HEADER" = "TAG_NAME"}
|
||||
|
||||
## Interface to use when dialing an address
|
||||
# interface = "eth0"
|
||||
```
|
||||
|
|
|
@ -27,6 +27,7 @@ type HTTPResponse struct {
|
|||
Body string
|
||||
Method string
|
||||
ResponseTimeout internal.Duration
|
||||
HTTPHeaderTags map[string]string `toml:"http_header_tags"`
|
||||
Headers map[string]string
|
||||
FollowRedirects bool
|
||||
// Absolute path to file with Bearer token
|
||||
|
@ -98,6 +99,11 @@ var sampleConfig = `
|
|||
# [inputs.http_response.headers]
|
||||
# Host = "github.com"
|
||||
|
||||
## Optional setting to map reponse http headers into tags
|
||||
## If the http header is not present on the request, no corresponding tag will be added
|
||||
## If multiple instances of the http header are present, only the first value will be used
|
||||
# http_header_tags = {"HTTP_HEADER" = "TAG_NAME"}
|
||||
|
||||
## Interface to use when dialing an address
|
||||
# interface = "eth0"
|
||||
`
|
||||
|
@ -265,6 +271,14 @@ func (h *HTTPResponse) httpGather(u string) (map[string]interface{}, map[string]
|
|||
resp, err := h.client.Do(request)
|
||||
response_time := time.Since(start).Seconds()
|
||||
|
||||
// Add the response headers
|
||||
for headerName, tag := range h.HTTPHeaderTags {
|
||||
headerValues, foundHeader := resp.Header[headerName]
|
||||
if foundHeader && len(headerValues) > 0 {
|
||||
tags[tag] = headerValues[0]
|
||||
}
|
||||
}
|
||||
|
||||
// If an error in returned, it means we are dealing with a network error, as
|
||||
// HTTP error codes do not generate errors in the net/http library
|
||||
if err != nil {
|
||||
|
|
|
@ -86,6 +86,11 @@ func setUpTestMux() http.Handler {
|
|||
http.Redirect(w, req, "/good", http.StatusMovedPermanently)
|
||||
})
|
||||
mux.HandleFunc("/good", func(w http.ResponseWriter, req *http.Request) {
|
||||
w.Header().Set("Server", "MyTestServer")
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
fmt.Fprintf(w, "hit the good page!")
|
||||
})
|
||||
mux.HandleFunc("/noheader", func(w http.ResponseWriter, req *http.Request) {
|
||||
fmt.Fprintf(w, "hit the good page!")
|
||||
})
|
||||
mux.HandleFunc("/jsonresponse", func(w http.ResponseWriter, req *http.Request) {
|
||||
|
@ -218,6 +223,72 @@ func TestFields(t *testing.T) {
|
|||
checkOutput(t, &acc, expectedFields, expectedTags, absentFields, nil)
|
||||
}
|
||||
|
||||
func TestHTTPHeaderTags(t *testing.T) {
|
||||
mux := setUpTestMux()
|
||||
ts := httptest.NewServer(mux)
|
||||
defer ts.Close()
|
||||
|
||||
h := &HTTPResponse{
|
||||
Log: testutil.Logger{},
|
||||
Address: ts.URL + "/good",
|
||||
Body: "{ 'test': 'data'}",
|
||||
Method: "GET",
|
||||
ResponseTimeout: internal.Duration{Duration: time.Second * 20},
|
||||
HTTPHeaderTags: map[string]string{"Server": "my_server", "Content-Type": "content_type"},
|
||||
Headers: map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
FollowRedirects: true,
|
||||
}
|
||||
|
||||
var acc testutil.Accumulator
|
||||
err := h.Gather(&acc)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedFields := map[string]interface{}{
|
||||
"http_response_code": http.StatusOK,
|
||||
"result_type": "success",
|
||||
"result_code": 0,
|
||||
"response_time": nil,
|
||||
"content_length": nil,
|
||||
}
|
||||
expectedTags := map[string]interface{}{
|
||||
"server": nil,
|
||||
"method": "GET",
|
||||
"status_code": "200",
|
||||
"result": "success",
|
||||
"my_server": "MyTestServer",
|
||||
"content_type": "application/json; charset=utf-8",
|
||||
}
|
||||
absentFields := []string{"response_string_match"}
|
||||
checkOutput(t, &acc, expectedFields, expectedTags, absentFields, nil)
|
||||
|
||||
h = &HTTPResponse{
|
||||
Log: testutil.Logger{},
|
||||
Address: ts.URL + "/noheader",
|
||||
Body: "{ 'test': 'data'}",
|
||||
Method: "GET",
|
||||
ResponseTimeout: internal.Duration{Duration: time.Second * 20},
|
||||
HTTPHeaderTags: map[string]string{"Server": "my_server", "Content-Type": "content_type"},
|
||||
Headers: map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
FollowRedirects: true,
|
||||
}
|
||||
|
||||
acc = testutil.Accumulator{}
|
||||
err = h.Gather(&acc)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedTags = map[string]interface{}{
|
||||
"server": nil,
|
||||
"method": "GET",
|
||||
"status_code": "200",
|
||||
"result": "success",
|
||||
}
|
||||
checkOutput(t, &acc, expectedFields, expectedTags, absentFields, nil)
|
||||
}
|
||||
|
||||
func findInterface() (net.Interface, error) {
|
||||
potential, _ := net.Interfaces()
|
||||
|
||||
|
|
Loading…
Reference in New Issue