Skip to content

Commit 03397d4

Browse files
authored
Add client.TimedClient implementing Requester (#74)
* Add `client.TimedClient` implementing `Requester` This helps in chaining clients doing requests. Such as client.NewTimedClient(http.DefaultClient, someCollector} * Code cleanup, add tests - Return concrete type - Use custom type for context key - Add tests
1 parent 1df6402 commit 03397d4

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

http/client/client.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,39 @@ type Requester interface {
1616
Do(req *http.Request) (*http.Response, error)
1717
}
1818

19+
// TimedClient instruments a request. It implements Requester.
20+
type TimedClient struct {
21+
client Requester
22+
collector instrument.Collector
23+
}
24+
25+
type contextKey int
26+
27+
// OperationNameContextKey specifies the operation name location within the context
28+
// for instrumentation.
29+
const OperationNameContextKey contextKey = 0
30+
31+
// NewTimedClient creates a Requester that instruments requests on `client`.
32+
func NewTimedClient(client Requester, collector instrument.Collector) *TimedClient {
33+
return &TimedClient{
34+
client: client,
35+
collector: collector,
36+
}
37+
}
38+
39+
// Do executes the request.
40+
func (c TimedClient) Do(r *http.Request) (*http.Response, error) {
41+
return TimeRequest(r.Context(), c.operationName(r), c.collector, c.client, r)
42+
}
43+
44+
func (c TimedClient) operationName(r *http.Request) string {
45+
operation, _ := r.Context().Value(OperationNameContextKey).(string)
46+
if operation == "" {
47+
operation = r.URL.Path
48+
}
49+
return operation
50+
}
51+
1952
// TimeRequest performs an HTTP client request and records the duration in a histogram.
2053
func TimeRequest(ctx context.Context, operation string, coll instrument.Collector, client Requester, request *http.Request) (*http.Response, error) {
2154
var response *http.Response

http/client/client_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package client
2+
3+
import (
4+
"context"
5+
"net/http"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestTimedClient_operationName(t *testing.T) {
12+
r, err := http.NewRequest("GET", "https://weave.test", nil)
13+
assert.NoError(t, err)
14+
15+
r = r.WithContext(context.WithValue(context.Background(), OperationNameContextKey, "opp"))
16+
c := NewTimedClient(http.DefaultClient, nil)
17+
18+
assert.Equal(t, "opp", c.operationName(r))
19+
}
20+
21+
func TestTimedClient_operationName_Default(t *testing.T) {
22+
r, err := http.NewRequest("GET", "https://weave.test/you/know/me", nil)
23+
assert.NoError(t, err)
24+
25+
r = r.WithContext(context.Background())
26+
c := NewTimedClient(http.DefaultClient, nil)
27+
28+
assert.Equal(t, "/you/know/me", c.operationName(r))
29+
}

0 commit comments

Comments
 (0)