Skip to content

Commit

Permalink
Add timing metrics for endpoints.
Browse files Browse the repository at this point in the history
  • Loading branch information
mcdee committed Jan 9, 2025
1 parent 1f0ea05 commit 603f56a
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 14 deletions.
23 changes: 13 additions & 10 deletions http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"net/http"
"net/url"
"strings"
"time"

"github.com/attestantio/go-builder-client/api"
"github.com/attestantio/go-eth2-client/spec"
Expand Down Expand Up @@ -116,10 +117,11 @@ func (s *Service) post(ctx context.Context,
req.Header.Set("User-Agent", defaultUserAgent)
}

started := time.Now()
resp, err := s.client.Do(req)
if err != nil {
span.SetStatus(codes.Error, err.Error())
s.monitorPostComplete(ctx, callURL.Path, "failed")
s.monitorPostComplete(ctx, callURL.Path, "failed", time.Since(started))

return nil, errors.Join(errors.New("failed to call POST endpoint"), err)
}
Expand All @@ -143,7 +145,7 @@ func (s *Service) post(ctx context.Context,
}

span.SetStatus(codes.Error, err.Error())
s.monitorPostComplete(ctx, callURL.Path, "failed")
s.monitorPostComplete(ctx, callURL.Path, "failed", time.Since(started))

return nil, errors.Join(errors.New("failed to read POST response"), err)
}
Expand All @@ -152,7 +154,7 @@ func (s *Service) post(ctx context.Context,
// Nothing returned. This is not considered an error.
span.AddEvent("Received empty response")
log.Trace().Msg("Endpoint returned no content")
s.monitorPostComplete(ctx, callURL.Path, "succeeded")
s.monitorPostComplete(ctx, callURL.Path, "succeeded", time.Since(started))

return res, nil
}
Expand Down Expand Up @@ -184,7 +186,7 @@ func (s *Service) post(ctx context.Context,
}

span.SetStatus(codes.Error, fmt.Sprintf("Status code %d", resp.StatusCode))
s.monitorPostComplete(ctx, callURL.Path, "failed")
s.monitorPostComplete(ctx, callURL.Path, "failed", time.Since(started))

return nil, &api.Error{
Method: http.MethodPost,
Expand All @@ -194,7 +196,7 @@ func (s *Service) post(ctx context.Context,
}
}

s.monitorPostComplete(ctx, callURL.Path, "succeeded")
s.monitorPostComplete(ctx, callURL.Path, "succeeded", time.Since(started))

return res, nil
}
Expand Down Expand Up @@ -249,10 +251,11 @@ func (s *Service) get(ctx context.Context,
req.Header.Set("Accept", "application/octet-stream;q=1,application/json;q=0.9")
}

started := time.Now()
resp, err := s.client.Do(req)
if err != nil {
span.SetStatus(codes.Error, err.Error())
s.monitorGetComplete(ctx, callURL.Path, "failed")
s.monitorGetComplete(ctx, callURL.Path, "failed", time.Since(started))

return nil, errors.Join(errors.New("failed to call GET endpoint"), err)
}
Expand Down Expand Up @@ -280,7 +283,7 @@ func (s *Service) get(ctx context.Context,
}

span.SetStatus(codes.Error, err.Error())
s.monitorGetComplete(ctx, callURL.Path, "failed")
s.monitorGetComplete(ctx, callURL.Path, "failed", time.Since(started))

return nil, errors.Join(errors.New("failed to read GET response"), err)
}
Expand All @@ -289,7 +292,7 @@ func (s *Service) get(ctx context.Context,
// Nothing returned. This is not considered an error.
span.AddEvent("Received empty response")
log.Trace().Msg("Endpoint returned no content")
s.monitorGetComplete(ctx, callURL.Path, "succeeded")
s.monitorGetComplete(ctx, callURL.Path, "succeeded", time.Since(started))

return res, nil
}
Expand Down Expand Up @@ -317,7 +320,7 @@ func (s *Service) get(ctx context.Context,
log.Debug().Int("status_code", resp.StatusCode).RawJSON("response", trimmedResponse).Msg("GET failed")

span.SetStatus(codes.Error, fmt.Sprintf("Status code %d", resp.StatusCode))
s.monitorGetComplete(ctx, callURL.Path, "failed")
s.monitorGetComplete(ctx, callURL.Path, "failed", time.Since(started))

return nil, &api.Error{
Method: http.MethodGet,
Expand All @@ -331,7 +334,7 @@ func (s *Service) get(ctx context.Context,
return nil, errors.Join(errors.New("failed to parse consensus version"), err)
}

s.monitorGetComplete(ctx, callURL.Path, "succeeded")
s.monitorGetComplete(ctx, callURL.Path, "succeeded", time.Since(started))

return res, nil
}
Expand Down
17 changes: 13 additions & 4 deletions http/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package http
import (
"context"
"regexp"
"time"

"github.com/attestantio/go-eth2-client/metrics"
"github.com/prometheus/client_golang/prometheus"
Expand Down Expand Up @@ -68,20 +69,28 @@ func registerPrometheusMetrics(_ context.Context) error {
return prometheus.Register(requestsTimer)
}

func (s *Service) monitorGetComplete(_ context.Context, endpoint string, result string) {
func (s *Service) monitorGetComplete(_ context.Context, endpoint string, result string, duration time.Duration) {
if requestsCounter == nil {
return
}

requestsCounter.WithLabelValues(s.address, "GET", reduceEndpoint(endpoint), result).Inc()
endpoint = reduceEndpoint(endpoint)
requestsCounter.WithLabelValues(s.address, "GET", endpoint, result).Inc()
if result == "succeeded" {
requestsTimer.WithLabelValues(s.address, "GET", endpoint).Observe(duration.Seconds())
}
}

func (s *Service) monitorPostComplete(_ context.Context, endpoint string, result string) {
func (s *Service) monitorPostComplete(_ context.Context, endpoint string, result string, duration time.Duration) {
if requestsCounter == nil {
return
}

requestsCounter.WithLabelValues(s.address, "POST", reduceEndpoint(endpoint), result).Inc()
endpoint = reduceEndpoint(endpoint)
requestsCounter.WithLabelValues(s.address, "POST", endpoint, result).Inc()
if result == "succeeded" {
requestsTimer.WithLabelValues(s.address, "POST", endpoint).Observe(duration.Seconds())
}
}

type templateReplacement struct {
Expand Down

0 comments on commit 603f56a

Please sign in to comment.