Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaime Martinez <jmartinez@gitlab.com>2020-10-01 08:40:45 +0300
committerJaime Martinez <jmartinez@gitlab.com>2020-10-01 08:40:45 +0300
commitc10cf875b6110fdff6a389fc4d51ecc923e3c61d (patch)
treeddd00766c3b65f29d0da042d93446b46db23ab09 /internal/httptransport
parent0e0c86e51ab7597dd357466513141061384ef69b (diff)
Move tracer to httptransport
Diffstat (limited to 'internal/httptransport')
-rw-r--r--internal/httptransport/trace.go77
-rw-r--r--internal/httptransport/transport.go10
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()