Skip to content

Commit d147085

Browse files
committed
Rewrite client middleware
1 parent 5402fe3 commit d147085

File tree

4 files changed

+54
-177
lines changed

4 files changed

+54
-177
lines changed

prometheus/promhttp/client.go

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,34 +34,29 @@ type httpClient interface {
3434
PostForm(string, url.Values) (*http.Response, error)
3535
}
3636

37-
type Middleware func(req *http.Request) (*http.Response, error)
37+
type ClientMiddleware func(req *http.Request) (*http.Response, error)
3838

39-
type Client struct {
40-
c httpClient
41-
middleware Middleware
39+
func (c ClientMiddleware) Do(r *http.Request) (*http.Response, error) {
40+
return c(r)
4241
}
4342

44-
func (c *Client) Do(r *http.Request) (*http.Response, error) {
45-
return c.middleware(r)
46-
}
47-
48-
func (c *Client) Get(url string) (resp *http.Response, err error) {
43+
func (c ClientMiddleware) Get(url string) (resp *http.Response, err error) {
4944
req, err := http.NewRequest("GET", url, nil)
5045
if err != nil {
5146
return nil, err
5247
}
5348
return c.Do(req)
5449
}
5550

56-
func (c *Client) Head(url string) (*http.Response, error) {
51+
func (c ClientMiddleware) Head(url string) (*http.Response, error) {
5752
req, err := http.NewRequest("HEAD", url, nil)
5853
if err != nil {
5954
return nil, err
6055
}
61-
return c.middleware(req)
56+
return c.Do(req)
6257
}
6358

64-
func (c *Client) Post(url string, contentType string, body io.Reader) (*http.Response, error) {
59+
func (c ClientMiddleware) Post(url string, contentType string, body io.Reader) (*http.Response, error) {
6560
req, err := http.NewRequest("POST", url, body)
6661
if err != nil {
6762
return nil, err
@@ -70,6 +65,6 @@ func (c *Client) Post(url string, contentType string, body io.Reader) (*http.Res
7065
return c.Do(req)
7166
}
7267

73-
func (c *Client) PostForm(url string, data url.Values) (*http.Response, error) {
68+
func (c ClientMiddleware) PostForm(url string, data url.Values) (*http.Response, error) {
7469
return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
7570
}

prometheus/promhttp/client_test.go

Lines changed: 23 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -20,89 +20,47 @@
2020
package promhttp
2121

2222
import (
23-
"log"
2423
"net/http"
24+
"net/http/httputil"
2525
"testing"
2626
"time"
2727

2828
"github.com/prometheus/client_golang/prometheus"
2929
)
3030

31-
func TestMiddlewareWrapsFirstToLast(t *testing.T) {
32-
order := []int{}
33-
first := func(r *http.Request, next Middleware) (*http.Response, error) {
34-
order = append(order, 0)
35-
36-
resp, err := next(r)
37-
38-
order = append(order, 3)
39-
return resp, err
40-
}
41-
42-
second := func(req *http.Request, next Middleware) (*http.Response, error) {
43-
order = append(order, 1)
44-
45-
return next(req)
46-
}
47-
48-
third := func(req *http.Request, next Middleware) (*http.Response, error) {
49-
order = append(order, 2)
50-
return next(req)
51-
}
52-
53-
promclient, err := NewClient(SetMiddleware(first, second, third))
54-
if err != nil {
55-
t.Fatalf("%v", err)
56-
}
57-
58-
resp, err := promclient.Get("http://google.com")
59-
if err != nil {
60-
t.Fatalf("%v", err)
61-
}
62-
defer resp.Body.Close()
63-
64-
for want, got := range order {
65-
if want != got {
66-
t.Fatalf("wanted %d, got %d", want, got)
67-
}
68-
}
69-
}
70-
71-
func TestMiddlewareAPI(t *testing.T) {
31+
func TestClientMiddlewareAPI(t *testing.T) {
7232
client := *http.DefaultClient
7333
client.Timeout = 300 * time.Millisecond
7434

7535
inFlightGauge := prometheus.NewGauge(prometheus.GaugeOpts{Name: "inFlight"})
76-
inFlight := func(r *http.Request, next Middleware) (*http.Response, error) {
77-
inFlightGauge.Inc()
78-
79-
resp, err := next(r)
80-
81-
inFlightGauge.Dec()
82-
83-
return resp, err
84-
}
8536

86-
counter := prometheus.NewCounter(prometheus.CounterOpts{Name: "test_counter"})
87-
addFortyTwo := func(req *http.Request, next Middleware) (*http.Response, error) {
88-
counter.Add(42)
37+
counter := prometheus.NewCounterVec(
38+
prometheus.CounterOpts{Name: "test_counter"},
39+
[]string{"code", "method"},
40+
)
41+
42+
histVec := prometheus.NewHistogramVec(
43+
prometheus.HistogramOpts{
44+
Name: "latency",
45+
Buckets: prometheus.DefBuckets,
46+
},
47+
[]string{"event"},
48+
)
49+
50+
promclient := InFlightC(inFlightGauge,
51+
CounterC(counter,
52+
ClientTrace(histVec, &client),
53+
),
54+
)
8955

90-
return next(req)
91-
}
92-
93-
logging := func(req *http.Request, next Middleware) (*http.Response, error) {
94-
log.Println("log something interesting")
95-
return next(req)
96-
}
97-
98-
promclient, err := NewClient(SetClient(client), SetMiddleware(inFlight, addFortyTwo, logging))
56+
resp, err := promclient.Get("http://google.com")
9957
if err != nil {
10058
t.Fatalf("%v", err)
10159
}
60+
defer resp.Body.Close()
10261

103-
resp, err := promclient.Get("http://google.com")
62+
out, err := httputil.DumpResponse(resp, true)
10463
if err != nil {
10564
t.Fatalf("%v", err)
10665
}
107-
defer resp.Body.Close()
10866
}

prometheus/promhttp/middleware.go

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,60 +33,60 @@ import (
3333
func ClientTrace(obs prometheus.ObserverVec, c httpClient) httpClient {
3434
// The supplied histogram NEEDS a label for the httptrace event.
3535
// TODO: Using `event` for now, but any other name is acceptable.
36-
wc := &Client{
37-
c: c,
38-
}
3936

4037
// TODO: Check for `event` label on histogram.
4138

42-
wc.middleware = func(r *http.Request) (*http.Response, error) {
39+
return ClientMiddleware(func(r *http.Request) (*http.Response, error) {
4340
var (
44-
host = r.URL.Host
4541
start = time.Now()
4642
)
4743

4844
trace := &httptrace.ClientTrace{
4945
DNSStart: func(_ httptrace.DNSStartInfo) {
50-
obs.WithLabelValues(host, "DNSStart").Observe(time.Since(start).Seconds())
46+
obs.WithLabelValues("DNSStart").Observe(time.Since(start).Seconds())
5147
},
5248
DNSDone: func(_ httptrace.DNSDoneInfo) {
53-
obs.WithLabelValues(host, "DNSDone").Observe(time.Since(start).Seconds())
49+
obs.WithLabelValues("DNSDone").Observe(time.Since(start).Seconds())
5450
},
5551
ConnectStart: func(_, _ string) {
56-
obs.WithLabelValues(host, "ConnectStart").Observe(time.Since(start).Seconds())
52+
obs.WithLabelValues("ConnectStart").Observe(time.Since(start).Seconds())
5753
},
5854
ConnectDone: func(net, addr string, err error) {
5955
if err != nil {
6056
return
6157
}
62-
obs.WithLabelValues(host, "ConnectDone").Observe(time.Since(start).Seconds())
58+
obs.WithLabelValues("ConnectDone").Observe(time.Since(start).Seconds())
6359
},
6460
GotConn: func(_ httptrace.GotConnInfo) {
65-
obs.WithLabelValues(host, "GotConn").Observe(time.Since(start).Seconds())
61+
obs.WithLabelValues("GotConn").Observe(time.Since(start).Seconds())
6662
},
6763
GotFirstResponseByte: func() {
68-
obs.WithLabelValues(host, "GotFirstResponseByte").Observe(time.Since(start).Seconds())
64+
obs.WithLabelValues("GotFirstResponseByte").Observe(time.Since(start).Seconds())
6965
},
7066
}
7167
r = r.WithContext(httptrace.WithClientTrace(context.Background(), trace))
7268

73-
return wc.Do(r)
74-
}
75-
76-
return wc
69+
return c.Do(r)
70+
})
7771
}
7872

7973
// InFlight is middleware that instruments number of open requests partitioned
8074
// by http client and request host.
81-
var InFlight = func(gauge prometheus.Gauge, c httpClient) httpClient {
82-
wc := &Client{
83-
c: c,
84-
}
85-
wc.middleware = func(r *http.Request) (*http.Response, error) {
75+
func InFlightC(gauge prometheus.Gauge, c httpClient) httpClient {
76+
return ClientMiddleware(func(r *http.Request) (*http.Response, error) {
8677
gauge.Inc()
87-
resp, err := wc.Do(r)
78+
resp, err := c.Do(r)
8879
gauge.Dec()
8980
return resp, err
90-
}
91-
return wc
81+
})
82+
}
83+
84+
func CounterC(counter *prometheus.CounterVec, c httpClient) httpClient {
85+
code, method := checkLabels(counter)
86+
87+
return ClientMiddleware(func(r *http.Request) (*http.Response, error) {
88+
resp, err := c.Do(r)
89+
counter.With(labels(code, method, r.Method, resp.StatusCode)).Inc()
90+
return resp, err
91+
})
9292
}

prometheus/promhttp/middleware_test.go

Lines changed: 0 additions & 76 deletions
This file was deleted.

0 commit comments

Comments
 (0)