/
httptraceutils.go
110 lines (94 loc) · 3.12 KB
/
httptraceutils.go
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Package httptraceutils is helper package for httptrace.
//
// Go 1.7 introduces net/http/httptrace package. That provides mechanisms for tracing within HTTP requests.
// Since it only provides the low level struct to set hooks for various states of request,
// you need to write logging or displaying part by yourself.
// go-httptraceutils is a small helper package for logging out each hook info of httptrace.
package httptraceutils
import (
"context"
"log"
"net/http/httptrace"
"os"
"strings"
)
var defaultLogger = log.New(os.Stderr, "", log.LstdFlags)
// WithClientTrace wraps `httptrace.WithClientTrace` and
// sets logging hook in each step function of `httptrace.ClientTrace`.
func WithClientTrace(ctx context.Context) context.Context {
return withClientTraceLogger(ctx, defaultLogger)
}
func withClientTraceLogger(ctx context.Context, logger *log.Logger) context.Context {
return httptrace.WithClientTrace(ctx, newClientTrace(logger))
}
func newClientTrace(logger *log.Logger) *httptrace.ClientTrace {
return &httptrace.ClientTrace{
GetConn: func(hostPort string) {
logger.Printf("[GetConn] HostPort: %s", hostPort)
},
GotConn: func(info httptrace.GotConnInfo) {
logger.Printf("[GotConn] LocalAddr: %s", info.Conn.LocalAddr())
logger.Printf("[GotConn] RemoteAddr: %s", info.Conn.RemoteAddr())
logger.Printf("[GotConn] Reused: %v", info.Reused)
logger.Printf("[GotConn] WasIdle: %#v", info.WasIdle)
if info.WasIdle {
logger.Printf("[GotConn] IdleTime: %#v", info.IdleTime)
}
},
PutIdleConn: func(err error) {
if err != nil {
logger.Printf("[PutIdeConn] Error: %s", err)
return
}
logger.Printf("[PutIdeConn] Error: nil")
},
GotFirstResponseByte: func() {
logger.Printf("[GotFirstResponseByte]")
},
Got100Continue: func() {
logger.Printf("[Got100Continue]")
},
DNSStart: func(info httptrace.DNSStartInfo) {
logger.Printf("[DNSStart] Host: %s", info.Host)
},
DNSDone: func(info httptrace.DNSDoneInfo) {
addrs := make([]string, 0, len(info.Addrs))
for _, addr := range info.Addrs {
addrs = append(addrs, addr.String())
}
logger.Printf("[DNSDone] Addrs: %s", strings.Join(addrs, ","))
logger.Printf("[DNSDone] Coalesced: %v", info.Coalesced)
if info.Err != nil {
logger.Printf("[DNSDone] Error: %s", info.Err)
return
}
logger.Printf("[DNSDone] Error: nil")
},
ConnectStart: func(network, addr string) {
logger.Printf("[ConnectStart] Network: %s", network)
logger.Printf("[ConnectStart] Addr: %s", addr)
},
ConnectDone: func(network, addr string, err error) {
logger.Printf("[ConnectDone] Network: %s", network)
logger.Printf("[ConnectDone] Addr: %s", addr)
if err != nil {
logger.Printf("[ConnectDone] Error: %s", err)
return
}
logger.Printf("[ConnectDone] Error: nil")
},
WroteHeaders: func() {
logger.Printf("[WroteHeaders]")
},
Wait100Continue: func() {
logger.Printf("[Wait100Continue]")
},
WroteRequest: func(info httptrace.WroteRequestInfo) {
if info.Err != nil {
logger.Printf("[WroteRequest] Error: %s", info.Err)
return
}
logger.Printf("[WroteRequest] Error: nil")
},
}
}