httptrace是最新Go 1.7版本中添加的。可以让我们追踪Http的请求。这个包的设计也是非常的讲究的。我们可以添加一些依赖包实现一个可自定义的debugging 依赖包。
httptrace
Httptrace的基本思想就是一长串的回调,选择性的添加到一个HTTP的请求上下文对象中。我们来看一个完整的实例
https://play.golang.org/p/pVVBcrSklg.
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 |
package main import ( "fmt" "io" "net/http" "net/http/httptest" "net/http/httptrace" "os" ) func main() { server := httptest.NewServer(http.HandlerFunc(http.NotFound)) defer server.Close() c := http.Client{} req, err := http.NewRequest("GET", server.URL, nil) if err != nil { panic(err) } trace := &httptrace.ClientTrace{ GotConn: func(connInfo httptrace.GotConnInfo) { fmt.Println("Got Conn") }, ConnectStart: func(network, addr string) { fmt.Println("Dial start") }, ConnectDone: func(network, addr string, err error) { fmt.Println("Dial done") }, GotFirstResponseByte: func() { fmt.Println("First response byte!") }, WroteHeaders: func() { fmt.Println("Wrote headers") }, WroteRequest: func(wr httptrace.WroteRequestInfo) { fmt.Println("Wrote request", wr) }, } req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace)) fmt.Println("Starting request!") resp, err := c.Do(req) if err != nil { panic(err) } io.Copy(os.Stdout, resp.Body) fmt.Println("Done!") } |
输出
Starting request!
Dial start
Dial done
Got Conn
Wrote headers
Wrote request {}
First response byte!
404 page not found
Done!
ClientTrace
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 |
type ClientTrace struct { // GetConn is called before a connection is created or // retrieved from an idle pool. The hostPort is the // "host:port" of the target or proxy. GetConn is called even // if there's already an idle cached connection available. GetConn func(hostPort string) // GotConn is called after a successful connection is // obtained. There is no hook for failure to obtain a // connection; instead, use the error from // Transport.RoundTrip. GotConn func(GotConnInfo) // PutIdleConn is called when the connection is returned to // the idle pool. If err is nil, the connection was // successfully returned to the idle pool. If err is non-nil, // it describes why not. PutIdleConn is not called if // connection reuse is disabled via Transport.DisableKeepAlives. // PutIdleConn is called before the caller's Response.Body.Close // call returns. // For HTTP/2, this hook is not currently used. PutIdleConn func(err error) // GotFirstResponseByte is called when the first byte of the response // headers is available. GotFirstResponseByte func() // Got100Continue is called if the server replies with a "100 // Continue" response. Got100Continue func() // DNSStart is called when a DNS lookup begins. DNSStart func(DNSStartInfo) // DNSDone is called when a DNS lookup ends. DNSDone func(DNSDoneInfo) // ConnectStart is called when a new connection's Dial begins. // If net.Dialer.DualStack (IPv6 "Happy Eyeballs") support is // enabled, this may be called multiple times. ConnectStart func(network, addr string) // ConnectDone is called when a new connection's Dial // completes. The provided err indicates whether the // connection completedly successfully. // If net.Dialer.DualStack ("Happy Eyeballs") support is // enabled, this may be called multiple times. ConnectDone func(network, addr string, err error) // WroteHeaders is called after the Transport has written // the request headers. WroteHeaders func() // Wait100Continue is called if the Request specified // "Expected: 100-continue" and the Transport has written the // request headers but is waiting for "100 Continue" from the // server before writing the request body. Wait100Continue func() // WroteRequest is called with the result of writing the // request and any body. WroteRequest func(WroteRequestInfo) } |
Go 1.7 httptrace
有疑问加站长微信联系(非本文作者)