golang 1.7 http client trace example

Kiyor | Created: 08-23-16 08:46:59, Last Update: 08-23-16 11:07:26



most of code copy from official go/src/net/http/transport_test.go

package main

import (
    "bytes"
    "context"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "net/http/httptrace"
    "sync"
    "time"
)

func main() {
    req, err := http.NewRequest("HEAD", "https://www.google.com", nil)
    if err != nil {
        log.Println(err.Error())
        return
    }

    var t1 time.Time

    var mu sync.Mutex
    var buf bytes.Buffer
    logf := func(format string, args ...interface{}) {
        mu.Lock()
        defer mu.Unlock()
        fmt.Fprintf(&buf, time.Since(t1).String()+" "+format, args...)
        buf.WriteByte('\n')
    }

    ctx := context.Background()
    trace := &httptrace.ClientTrace{
        GetConn:              func(hostPort string) { t1 = time.Now(); logf("Getting conn for %v ...", hostPort) },
        GotConn:              func(ci httptrace.GotConnInfo) { logf("got conn: %+v", ci) },
        GotFirstResponseByte: func() { logf("first response byte") },
        PutIdleConn:          func(err error) { logf("PutIdleConn = %v", err) },
        DNSStart:             func(e httptrace.DNSStartInfo) { logf("DNS start: %+v", e) },
        DNSDone:              func(e httptrace.DNSDoneInfo) { logf("DNS done: %+v", e) },
        ConnectStart:         func(network, addr string) { logf("ConnectStart: Connecting to %s %s ...", network, addr) },
        ConnectDone: func(network, addr string, err error) {
            if err != nil {
                logf("ConnectDone: %v", err)
            }
            logf("ConnectDone: connected to %s %s = %v", network, addr, err)
        },
        Wait100Continue: func() { logf("Wait100Continue") },
        Got100Continue:  func() { logf("Got100Continue") },
        WroteRequest: func(e httptrace.WroteRequestInfo) {
            logf("WroteRequest: %+v", e)
        },
    }
    req = req.WithContext(httptrace.WithClientTrace(ctx, trace))

    client := new(http.Client)
    t1 = time.Now()
    resp, err := client.Do(req)
    if err != nil {
        log.Println(err.Error())
        return
    }
    defer resp.Body.Close()
    ioutil.ReadAll(resp.Body)
    fmt.Println(buf.String())
    fmt.Println(time.Since(t1), resp.Status)
}
955ns Getting conn for www.google.com:443 ...
181.143µs DNS start: {Host:www.google.com}
23.113771ms DNS done: {Addrs:[{IP:216.58.194.164 Zone:} {IP:2607:f8b0:4005:804::2004 Zone:}] Err:<nil> Coalesced:false}
23.172604ms ConnectStart: Connecting to tcp 216.58.194.164:443 ...
25.058901ms ConnectDone: connected to tcp 216.58.194.164:443 = <nil>
108.660729ms got conn: {Conn:0xc420067500 Reused:false WasIdle:false IdleTime:0s}
108.809026ms WroteRequest: {Err:<nil>}
153.106683ms first response byte

154.284484ms 200 OK


Category: none