mirror of https://github.com/status-im/consul.git
Add truncation to body (#17723)
This commit is contained in:
parent
abb05deeed
commit
7ab287c1d5
|
@ -32,6 +32,10 @@ const (
|
||||||
// defaultRetryMax is set to 0 to turn off retry functionality, until dynamic configuration is possible.
|
// defaultRetryMax is set to 0 to turn off retry functionality, until dynamic configuration is possible.
|
||||||
// This is to circumvent any spikes in load that may cause or exacerbate server-side issues for now.
|
// This is to circumvent any spikes in load that may cause or exacerbate server-side issues for now.
|
||||||
defaultRetryMax = 0
|
defaultRetryMax = 0
|
||||||
|
|
||||||
|
// defaultErrRespBodyLength refers to the max character length of the body on a failure to export metrics.
|
||||||
|
// anything beyond we will truncate.
|
||||||
|
defaultErrRespBodyLength = 100
|
||||||
)
|
)
|
||||||
|
|
||||||
// MetricsClient exports Consul metrics in OTLP format to the HCP Telemetry Gateway.
|
// MetricsClient exports Consul metrics in OTLP format to the HCP Telemetry Gateway.
|
||||||
|
@ -150,8 +154,18 @@ func (o *otlpClient) ExportMetrics(ctx context.Context, protoMetrics *metricpb.R
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return fmt.Errorf("failed to export metrics: code %d: %s", resp.StatusCode, string(body))
|
truncatedBody := truncate(respData.String(), defaultErrRespBodyLength)
|
||||||
|
return fmt.Errorf("failed to export metrics: code %d: %s", resp.StatusCode, truncatedBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func truncate(text string, width uint) string {
|
||||||
|
if len(text) <= int(width) {
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
r := []rune(text)
|
||||||
|
trunc := r[:width]
|
||||||
|
return string(trunc) + "..."
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package client
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -64,10 +65,21 @@ func TestNewMetricsClient(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZäöüÄÖÜ世界")
|
||||||
|
|
||||||
|
func randStringRunes(n int) string {
|
||||||
|
b := make([]rune, n)
|
||||||
|
for i := range b {
|
||||||
|
b[i] = letterRunes[rand.Intn(len(letterRunes))]
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
func TestExportMetrics(t *testing.T) {
|
func TestExportMetrics(t *testing.T) {
|
||||||
for name, test := range map[string]struct {
|
for name, test := range map[string]struct {
|
||||||
wantErr string
|
wantErr string
|
||||||
status int
|
status int
|
||||||
|
largeBodyError bool
|
||||||
}{
|
}{
|
||||||
"success": {
|
"success": {
|
||||||
status: http.StatusOK,
|
status: http.StatusOK,
|
||||||
|
@ -76,8 +88,14 @@ func TestExportMetrics(t *testing.T) {
|
||||||
status: http.StatusBadRequest,
|
status: http.StatusBadRequest,
|
||||||
wantErr: "failed to export metrics: code 400",
|
wantErr: "failed to export metrics: code 400",
|
||||||
},
|
},
|
||||||
|
"failsWithNonRetryableErrorWithLongError": {
|
||||||
|
status: http.StatusBadRequest,
|
||||||
|
wantErr: "failed to export metrics: code 400",
|
||||||
|
largeBodyError: true,
|
||||||
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
|
randomBody := randStringRunes(1000)
|
||||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
require.Equal(t, r.Header.Get("content-type"), "application/x-protobuf")
|
require.Equal(t, r.Header.Get("content-type"), "application/x-protobuf")
|
||||||
require.Equal(t, r.Header.Get("x-hcp-resource-id"), testResourceID)
|
require.Equal(t, r.Header.Get("x-hcp-resource-id"), testResourceID)
|
||||||
|
@ -91,7 +109,12 @@ func TestExportMetrics(t *testing.T) {
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/x-protobuf")
|
w.Header().Set("Content-Type", "application/x-protobuf")
|
||||||
w.WriteHeader(test.status)
|
w.WriteHeader(test.status)
|
||||||
|
if test.largeBodyError {
|
||||||
|
w.Write([]byte(randomBody))
|
||||||
|
} else {
|
||||||
w.Write(bytes)
|
w.Write(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
}))
|
}))
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
|
@ -105,6 +128,10 @@ func TestExportMetrics(t *testing.T) {
|
||||||
if test.wantErr != "" {
|
if test.wantErr != "" {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.Contains(t, err.Error(), test.wantErr)
|
require.Contains(t, err.Error(), test.wantErr)
|
||||||
|
if test.largeBodyError {
|
||||||
|
truncatedBody := truncate(randomBody, defaultErrRespBodyLength)
|
||||||
|
require.Contains(t, err.Error(), truncatedBody)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,3 +139,37 @@ func TestExportMetrics(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTruncate(t *testing.T) {
|
||||||
|
for name, tc := range map[string]struct {
|
||||||
|
body string
|
||||||
|
expectedSize int
|
||||||
|
}{
|
||||||
|
"ZeroSize": {
|
||||||
|
body: "",
|
||||||
|
expectedSize: 0,
|
||||||
|
},
|
||||||
|
"LessThanSize": {
|
||||||
|
body: "foobar",
|
||||||
|
expectedSize: 6,
|
||||||
|
},
|
||||||
|
"defaultSize": {
|
||||||
|
body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vel tincidunt nunc, sed tristique risu",
|
||||||
|
expectedSize: 100,
|
||||||
|
},
|
||||||
|
"greaterThanSize": {
|
||||||
|
body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vel tincidunt nunc, sed tristique risus",
|
||||||
|
expectedSize: 103,
|
||||||
|
},
|
||||||
|
"greaterThanSizeWithUnicode": {
|
||||||
|
body: randStringRunes(1000),
|
||||||
|
expectedSize: 103,
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
truncatedBody := truncate(tc.body, defaultErrRespBodyLength)
|
||||||
|
truncatedRunes := []rune(truncatedBody)
|
||||||
|
require.Equal(t, len(truncatedRunes), tc.expectedSize)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue