diff options
author | Jaime Martinez <jmartinez@gitlab.com> | 2020-10-01 08:40:45 +0300 |
---|---|---|
committer | Jaime Martinez <jmartinez@gitlab.com> | 2020-10-01 08:40:45 +0300 |
commit | c10cf875b6110fdff6a389fc4d51ecc923e3c61d (patch) | |
tree | ddd00766c3b65f29d0da042d93446b46db23ab09 /internal/httptransport | |
parent | 0e0c86e51ab7597dd357466513141061384ef69b (diff) |
Move tracer to httptransport
Diffstat (limited to 'internal/httptransport')
-rw-r--r-- | internal/httptransport/trace.go | 77 | ||||
-rw-r--r-- | internal/httptransport/transport.go | 10 |
2 files changed, 85 insertions, 2 deletions
diff --git a/internal/httptransport/trace.go b/internal/httptransport/trace.go new file mode 100644 index 00000000..9ece5fc4 --- /dev/null +++ b/internal/httptransport/trace.go @@ -0,0 +1,77 @@ +package httptransport + +import ( + "crypto/tls" + "net/http/httptrace" + "time" + + "gitlab.com/gitlab-org/labkit/log" +) + +func (mrt *meteredRoundTripper) newTracer(start time.Time) *httptrace. + ClientTrace { + trace := &httptrace.ClientTrace{ + GetConn: func(host string) { + mrt.httpTraceObserve("httptrace.ClientTrace.GetConn", start) + + log.WithFields(log.Fields{ + "host": host, + }).Traceln("httptrace.ClientTrace.GetConn") + }, + GotConn: func(connInfo httptrace.GotConnInfo) { + mrt.httpTraceObserve("httptrace.ClientTrace.GotConn", start) + + log.WithFields(log.Fields{ + "reused": connInfo.Reused, + "was_idle": connInfo.WasIdle, + "idle_time_ms": connInfo.IdleTime.Milliseconds(), + }).Traceln("httptrace.ClientTrace.GotConn") + }, + GotFirstResponseByte: func() { + mrt.httpTraceObserve("httptrace.ClientTrace.GotFirstResponseByte", start) + }, + DNSStart: func(d httptrace.DNSStartInfo) { + mrt.httpTraceObserve("httptrace.ClientTrace.DNSStart", start) + }, + DNSDone: func(d httptrace.DNSDoneInfo) { + mrt.httpTraceObserve("httptrace.ClientTrace.DNSDone", start) + + log.WithFields(log.Fields{}).WithError(d.Err). + Traceln("httptrace.ClientTrace.DNSDone") + }, + ConnectStart: func(net, addr string) { + mrt.httpTraceObserve("httptrace.ClientTrace.ConnectStart", start) + + log.WithFields(log.Fields{ + "network": net, + "address": addr, + }).Traceln("httptrace.ClientTrace.ConnectStart") + }, + ConnectDone: func(net string, addr string, err error) { + mrt.httpTraceObserve("httptrace.ClientTrace.ConnectDone", start) + + log.WithFields(log.Fields{ + "network": net, + "address": addr, + }).WithError(err).Traceln("httptrace.ClientTrace.ConnectDone") + }, + TLSHandshakeStart: func() { + mrt.httpTraceObserve("httptrace.ClientTrace.TLSHandshakeStart", start) + }, + TLSHandshakeDone: func(connState tls.ConnectionState, err error) { + mrt.httpTraceObserve("httptrace.ClientTrace.TLSHandshakeDone", start) + + log.WithFields(log.Fields{ + "version": connState.Version, + "connection_resumed": connState.DidResume, + }).WithError(err).Traceln("httptrace.ClientTrace.TLSHandshakeDone") + }, + } + + return trace +} + +func (mrt *meteredRoundTripper) httpTraceObserve(label string, start time.Time) { + mrt.tracer.WithLabelValues(label). + Observe(time.Since(start).Seconds()) +} diff --git a/internal/httptransport/transport.go b/internal/httptransport/transport.go index 304ac1c6..bc871ea7 100644 --- a/internal/httptransport/transport.go +++ b/internal/httptransport/transport.go @@ -5,6 +5,7 @@ import ( "crypto/x509" "net" "net/http" + "net/http/httptrace" "strconv" "strings" "sync" @@ -27,6 +28,7 @@ var ( type meteredRoundTripper struct { next http.RoundTripper name string + tracer *prometheus.HistogramVec durations *prometheus.HistogramVec counter *prometheus.CounterVec } @@ -46,11 +48,13 @@ func newInternalTransport() *http.Transport { // NewTransportWithMetrics will create a custom http.RoundTripper that can be used with an http.Client. // The RoundTripper will report metrics based on the collectors passed. -func NewTransportWithMetrics(name string, histogramVec *prometheus.HistogramVec, counterVec *prometheus.CounterVec) http.RoundTripper { +func NewTransportWithMetrics(name string, tracerVec, durationsVec *prometheus. + HistogramVec, counterVec *prometheus.CounterVec) http.RoundTripper { return &meteredRoundTripper{ next: InternalTransport, name: name, - durations: histogramVec, + tracer: tracerVec, + durations: durationsVec, counter: counterVec, } } @@ -84,6 +88,8 @@ func loadPool() { func (mrt *meteredRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { start := time.Now() + r = r.WithContext(httptrace.WithClientTrace(r.Context(), mrt.newTracer(start))) + resp, err := mrt.next.RoundTrip(r) if err != nil { mrt.counter.WithLabelValues("error").Inc() |