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

transport.go « httprange « internal - gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 9bb6e80512e0a28d375b8194a0e821d11036e3ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package httprange

import (
	"crypto/tls"
	"net/http"
	"net/http/httptrace"
	"time"

	"gitlab.com/gitlab-org/labkit/log"

	"gitlab.com/gitlab-org/gitlab-pages/metrics"
)

type tracedTransport struct {
	next http.RoundTripper
}

// withRoundTripper takes an original RoundTripper, reports metrics based on the
// gauge and counter collectors passed
func (tr *tracedTransport) RoundTrip(r *http.Request) (*http.Response, error) {
	r = r.WithContext(httptrace.WithClientTrace(r.Context(), newTracer(time.Now())))

	return tr.next.RoundTrip(r)
}

func newTracer(start time.Time) *httptrace.ClientTrace {
	trace := &httptrace.ClientTrace{
		GetConn: func(host string) {
			httpTraceObserve("httptrace.ClientTrace.GetConn", start)

			log.WithFields(log.Fields{
				"host": host,
			}).Traceln("httptrace.ClientTrace.GetConn")
		},
		GotConn: func(connInfo httptrace.GotConnInfo) {
			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() {
			httpTraceObserve("httptrace.ClientTrace.GotFirstResponseByte", start)
		},
		DNSStart: func(d httptrace.DNSStartInfo) {
			httpTraceObserve("httptrace.ClientTrace.DNSStart", start)
		},
		DNSDone: func(d httptrace.DNSDoneInfo) {
			httpTraceObserve("httptrace.ClientTrace.DNSDone", start)

			log.WithFields(log.Fields{}).WithError(d.Err).
				Traceln("httptrace.ClientTrace.DNSDone")
		},
		ConnectStart: func(net, addr string) {
			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) {
			httpTraceObserve("httptrace.ClientTrace.ConnectDone", start)

			log.WithFields(log.Fields{
				"network": net,
				"address": addr,
			}).WithError(err).Traceln("httptrace.ClientTrace.ConnectDone")
		},
		TLSHandshakeStart: func() {
			httpTraceObserve("httptrace.ClientTrace.TLSHandshakeStart", start)
		},
		TLSHandshakeDone: func(connState tls.ConnectionState, err error) {
			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 httpTraceObserve(label string, start time.Time) {
	metrics.HTTPRangeTraceDuration.WithLabelValues(label).
		Observe(time.Since(start).Seconds())
}