Skip to content

Commit

Permalink
*: update ResponseError type (#142)
Browse files Browse the repository at this point in the history
* Show Code/Message so that it's easy to generate database schema
* Add URL in error

Signed-off-by: Wei Fu <weifu@microsoft.com>
  • Loading branch information
fuweid authored Dec 18, 2024
1 parent 4346c43 commit 66af6c9
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 7 deletions.
6 changes: 4 additions & 2 deletions api/types/metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,20 @@ const (

// ResponseError is the record about that error.
type ResponseError struct {
// URL indicates target resource.
URL string `json:"url"`
// Timestamp indicates when this error was received.
Timestamp time.Time `json:"timestamp"`
// Duration records timespan in seconds.
Duration float64 `json:"duration"`
// Type indicates that category to which the error belongs.
Type ResponseErrorType `json:"type"`
// Code only works when Type is http.
Code int `json:"code,omitempty"`
Code int `json:"code"`
// Message shows error message for this error.
//
// NOTE: When Type is http, this field will be empty.
Message string `json:"message,omitempty"`
Message string `json:"message"`
}

// ResponseStats is the report about benchmark result.
Expand Down
5 changes: 3 additions & 2 deletions metrics/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type ResponseMetric interface {
// ObserveLatency observes latency.
ObserveLatency(url string, seconds float64)
// ObserveFailure observes failure response.
ObserveFailure(now time.Time, seconds float64, err error)
ObserveFailure(url string, now time.Time, seconds float64, err error)
// ObserveReceivedBytes observes the bytes read from apiserver.
ObserveReceivedBytes(bytes int64)
// Gather returns the summary.
Expand Down Expand Up @@ -52,7 +52,7 @@ func (m *responseMetricImpl) ObserveLatency(url string, seconds float64) {
}

// ObserveFailure implements ResponseMetric.
func (m *responseMetricImpl) ObserveFailure(now time.Time, seconds float64, err error) {
func (m *responseMetricImpl) ObserveFailure(url string, now time.Time, seconds float64, err error) {
if err == nil {
return
}
Expand All @@ -61,6 +61,7 @@ func (m *responseMetricImpl) ObserveFailure(now time.Time, seconds float64, err
defer m.mu.Unlock()

oerr := types.ResponseError{
URL: url,
Timestamp: now,
Duration: seconds,
}
Expand Down
19 changes: 17 additions & 2 deletions metrics/request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,90 +25,105 @@ func TestResponseMetric_ObserveFailure(t *testing.T) {

expectedErrors := []types.ResponseError{
{
URL: "0",
Timestamp: observedAt,
Duration: dur.Seconds(),
Type: types.ResponseErrorTypeHTTP,
Code: 429,
},
{
URL: "1",
Timestamp: observedAt,
Duration: dur.Seconds(),
Type: types.ResponseErrorTypeHTTP,
Code: 500,
},
{
URL: "2",
Timestamp: observedAt,
Duration: dur.Seconds(),
Type: types.ResponseErrorTypeHTTP,
Code: 504,
},
{
URL: "3",
Timestamp: observedAt,
Duration: dur.Seconds(),
Type: types.ResponseErrorTypeHTTP2Protocol,
Message: "http2: server sent GOAWAY and closed the connection; ErrCode=NO_ERROR, debug=",
},
{
URL: "4",
Timestamp: observedAt,
Duration: dur.Seconds(),
Type: types.ResponseErrorTypeHTTP2Protocol,
Message: "http2: server sent GOAWAY and closed the connection; ErrCode=PROTOCOL_ERROR, debug=",
},
{
URL: "5",
Timestamp: observedAt,
Duration: dur.Seconds(),
Type: types.ResponseErrorTypeHTTP2Protocol,
Message: "http2: client connection lost",
},
{
URL: "6",
Timestamp: observedAt,
Duration: dur.Seconds(),
Type: types.ResponseErrorTypeHTTP2Protocol,
Message: "http2: client connection lost",
},
{
URL: "7",
Timestamp: observedAt,
Duration: dur.Seconds(),
Type: types.ResponseErrorTypeHTTP2Protocol,
Message: http2.ErrCode(10).String(),
},
{
URL: "8",
Timestamp: observedAt,
Duration: dur.Seconds(),
Type: types.ResponseErrorTypeConnection,
Message: "net/http: TLS handshake timeout",
},
{
URL: "9",
Timestamp: observedAt,
Duration: dur.Seconds(),
Type: types.ResponseErrorTypeConnection,
Message: "net/http: TLS handshake timeout",
},
{
URL: "10",
Timestamp: observedAt,
Duration: dur.Seconds(),
Type: types.ResponseErrorTypeConnection,
Message: "context deadline exceeded",
},
{
URL: "11",
Timestamp: observedAt,
Duration: dur.Seconds(),
Type: types.ResponseErrorTypeConnection,
Message: syscall.ECONNRESET.Error(),
},
{
URL: "12",
Timestamp: observedAt,
Duration: dur.Seconds(),
Type: types.ResponseErrorTypeConnection,
Message: syscall.ECONNREFUSED.Error(),
},
{
URL: "13",
Timestamp: observedAt,
Duration: dur.Seconds(),
Type: types.ResponseErrorTypeConnection,
Message: io.ErrUnexpectedEOF.Error(),
},
{
URL: "14",
Timestamp: observedAt,
Duration: dur.Seconds(),
Type: types.ResponseErrorTypeUnknown,
Expand Down Expand Up @@ -150,8 +165,8 @@ func TestResponseMetric_ObserveFailure(t *testing.T) {
}

m := NewResponseMetric()
for _, err := range errs {
m.ObserveFailure(observedAt, dur.Seconds(), err)
for idx, err := range errs {
m.ObserveFailure(fmt.Sprintf("%d", idx), observedAt, dur.Seconds(), err)
}
errors := m.Gather().Errors
assert.Equal(t, expectedErrors, errors)
Expand Down
2 changes: 1 addition & 1 deletion request/schedule.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func Schedule(ctx context.Context, spec *types.LoadProfileSpec, restCli []rest.I

respMetric.ObserveReceivedBytes(bytes)
if err != nil {
respMetric.ObserveFailure(end, latency, err)
respMetric.ObserveFailure(req.URL().String(), end, latency, err)
klog.V(5).Infof("Request stream failed: %v", err)
return
}
Expand Down

0 comments on commit 66af6c9

Please sign in to comment.