雑なメモ書き

気楽にいきます

Goのhttptraceを試して見た

goでは1.7からhttptraceというものが入っている。

http eventsを観測することが出来る。

  • Connection creation
  • Connection reuse
  • DNS lookups
  • Writing the request to the wire
  • Reading the response

サンプルを実行すると、DNS lookupsConnection creationが出力される。

package main

import (
    "fmt"
    "log"
    "net/http"
    "net/http/httptrace"
)

func main() {
    req, _ := http.NewRequest("GET", "http://example.com", nil)
    trace := &httptrace.ClientTrace{
        GotConn: func(connInfo httptrace.GotConnInfo) {
            fmt.Printf("Got Conn: %+v\n", connInfo)
        },
        DNSDone: func(dnsInfo httptrace.DNSDoneInfo) {
            fmt.Printf("DNS Info: %+v\n", dnsInfo)
        },
    }
    req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
    _, err := http.DefaultTransport.RoundTrip(req)
    if err != nil {
        log.Fatal(err)
    }
}

結果

DNS Info: {Addrs:[{IP:xx.xx.xx.xx Zone:}] Err:<nil> Coalesced:false}
Got Conn: {Conn:0xc0000f8000 Reused:false WasIdle:false IdleTime:0s}

ここで定義されているClientTraceという構造体があり、存在する要素に対応する関数を登録していけば取得出来る。

type ClientTrace struct {
    GetConn func(hostPort string)
    GotConn func(GotConnInfo)
    PutIdleConn func(err error)
    GotFirstResponseByte func()
    Got100Continue func()
    Got1xxResponse func(code int, header textproto.MIMEHeader) error
    DNSStart func(DNSStartInfo)
    DNSDone func(DNSDoneInfo)
    ConnectStart func(network, addr string)
    ConnectDone func(network, addr string, err error)
    TLSHandshakeStart func()
    TLSHandshakeDone func(tls.ConnectionState, error)
    WroteHeaderField func(key string, value []string)
    WroteHeaders func()
    Wait100Continue func()
    WroteRequest func(WroteRequestInfo)
}

数がそこそこあるのでコメントを削ったが、かなり詳細にtrace出来る。