From 15fcfe60a95b2f7b05d115029f6237405ec4634e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Rasc=C3=A3o?= Date: Fri, 17 Dec 2021 00:39:34 +0000 Subject: [PATCH] request: provide observability over HTTP request latency (#848) --- exchanges/request/options.go | 7 +++++++ exchanges/request/report.go | 17 +++++++++++++++++ exchanges/request/request.go | 8 ++++++++ exchanges/request/request_types.go | 2 ++ 4 files changed, 34 insertions(+) create mode 100644 exchanges/request/report.go diff --git a/exchanges/request/options.go b/exchanges/request/options.go index 7a86727e..51f16735 100644 --- a/exchanges/request/options.go +++ b/exchanges/request/options.go @@ -20,3 +20,10 @@ func WithRetryPolicy(p RetryPolicy) RequesterOption { r.retryPolicy = p } } + +// WithReporter configures the reporter for a Requester. +func WithReporter(rep Reporter) RequesterOption { + return func(r *Requester) { + r.reporter = rep + } +} diff --git a/exchanges/request/report.go b/exchanges/request/report.go new file mode 100644 index 00000000..8288c1a4 --- /dev/null +++ b/exchanges/request/report.go @@ -0,0 +1,17 @@ +package request + +import ( + "time" +) + +// Reporter interface groups observability functionality over +// HTTP request latency. +type Reporter interface { + Latency(name, method, path string, t time.Duration) +} + +// SetupGlobalReporter sets a reporter interface to be used +// for all exchange requests +func SetupGlobalReporter(r Reporter) { + globalReporter = r +} diff --git a/exchanges/request/request.go b/exchanges/request/request.go index 6cccfae1..15c77938 100644 --- a/exchanges/request/request.go +++ b/exchanges/request/request.go @@ -39,6 +39,7 @@ func New(name string, httpRequester *http.Client, opts ...RequesterOption) *Requ retryPolicy: DefaultRetryPolicy, maxRetries: MaxRetryAttempts, timedLock: timedmutex.NewTimedMutex(DefaultMutexLockTimeout), + reporter: globalReporter, } for _, o := range opts { @@ -150,7 +151,14 @@ func (r *Requester) doRequest(ctx context.Context, endpoint EndpointLimit, newRe } } + start := time.Now() + resp, err := r.HTTPClient.Do(req) + + if r.reporter != nil { + r.reporter.Latency(r.Name, p.Method, p.Path, time.Since(start)) + } + if retry, checkErr := r.retryPolicy(resp, err); checkErr != nil { return checkErr } else if retry { diff --git a/exchanges/request/request_types.go b/exchanges/request/request_types.go index 166fa6c0..6279d8fc 100644 --- a/exchanges/request/request_types.go +++ b/exchanges/request/request_types.go @@ -23,12 +23,14 @@ const ( var ( MaxRequestJobs = DefaultMaxRequestJobs MaxRetryAttempts = DefaultMaxRetryAttempts + globalReporter Reporter ) // Requester struct for the request client type Requester struct { HTTPClient *http.Client limiter Limiter + reporter Reporter Name string UserAgent string maxRetries int