From a43a1680a99487a41195adf518de937096ce3756 Mon Sep 17 00:00:00 2001 From: Frederick Roth Date: Tue, 16 May 2017 13:13:57 +0200 Subject: [PATCH] http_response: Measure data in case of timeout or dns error --- plugins/inputs/http_response/README.md | 3 +++ plugins/inputs/http_response/http_response.go | 18 +++++++++++----- .../http_response/http_response_test.go | 21 ++++++++++++++++--- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/plugins/inputs/http_response/README.md b/plugins/inputs/http_response/README.md index 3f4e62d94210b..3ea0efc3667a1 100644 --- a/plugins/inputs/http_response/README.md +++ b/plugins/inputs/http_response/README.md @@ -41,6 +41,9 @@ This input plugin will test HTTP/HTTPS connections. - http_response - response_time (float, seconds) - http_response_code (int) #The code received + - connection_failed (int) # 1 when no http connection could be established + - response_timeout (int) # 1 when response timeouts + - response_string_match (int) # 1 when response matches "response_string_match" configuration ### Tags: diff --git a/plugins/inputs/http_response/http_response.go b/plugins/inputs/http_response/http_response.go index cd3d735d2ed9b..7eb0fa72efa22 100644 --- a/plugins/inputs/http_response/http_response.go +++ b/plugins/inputs/http_response/http_response.go @@ -5,6 +5,7 @@ import ( "io" "io/ioutil" "log" + "net" "net/http" "net/url" "regexp" @@ -130,15 +131,20 @@ func (h *HTTPResponse) httpGather() (map[string]interface{}, error) { // Start Timer start := time.Now() resp, err := h.client.Do(request) + if err != nil { + if netErr, ok := err.(net.Error); ok && netErr.Timeout() { + fields["response_timeout"] = time.Since(start).Seconds() + } + fields["connection_failed"] = 1 if h.FollowRedirects { - return nil, err + return fields, nil } if urlError, ok := err.(*url.Error); ok && urlError.Err == ErrRedirectAttempted { err = nil } else { - return nil, err + return fields, nil } } defer func() { @@ -148,6 +154,7 @@ func (h *HTTPResponse) httpGather() (map[string]interface{}, error) { fields["response_time"] = time.Since(start).Seconds() fields["http_response_code"] = resp.StatusCode + fields["connection_failed"] = 0 // Check the response for a regex match. if h.ResponseStringMatch != "" { @@ -215,10 +222,11 @@ func (h *HTTPResponse) Gather(acc telegraf.Accumulator) error { // Gather data fields, err = h.httpGather() if err != nil { - return err + acc.AddError(err) + } else { + // Add metrics + acc.AddFields("http_response", fields, tags) } - // Add metrics - acc.AddFields("http_response", fields, tags) return nil } diff --git a/plugins/inputs/http_response/http_response_test.go b/plugins/inputs/http_response/http_response_test.go index ee2390d2d30df..1ad52a48dcba2 100644 --- a/plugins/inputs/http_response/http_response_test.go +++ b/plugins/inputs/http_response/http_response_test.go @@ -106,6 +106,9 @@ func TestFields(t *testing.T) { value, ok := acc.IntField("http_response", "http_response_code") require.True(t, ok) require.Equal(t, http.StatusOK, value) + value, ok = acc.IntField("http_response", "connection_failed") + require.True(t, ok) + require.Equal(t, 0, value) } func TestRedirects(t *testing.T) { @@ -143,10 +146,15 @@ func TestRedirects(t *testing.T) { } acc = testutil.Accumulator{} err = h.Gather(&acc) - require.Error(t, err) + require.NoError(t, err) value, ok = acc.IntField("http_response", "http_response_code") require.False(t, ok) + value, ok = acc.IntField("http_response", "response_string_match") + require.False(t, ok) + value, ok = acc.IntField("http_response", "connection_failed") + require.True(t, ok) + require.Equal(t, 1, value) } func TestMethod(t *testing.T) { @@ -363,8 +371,15 @@ func TestTimeout(t *testing.T) { } var acc testutil.Accumulator err := h.Gather(&acc) - require.Error(t, err) + require.NoError(t, err) - ok := acc.HasIntField("http_response", "http_response_code") + value, ok := acc.IntField("http_response", "http_response_code") + require.False(t, ok) + _, ok = acc.FloatField("http_response", "response_timeout") + require.True(t, ok) + value, ok = acc.IntField("http_response", "connection_failed") + require.True(t, ok) + require.Equal(t, 1, value) + _, ok = acc.FloatField("http_response", "response_time") require.False(t, ok) }