Tracing HTTP request latency in golang

httpstat as a golang package

deeeet
deeeet
Sep 27, 2016 · 2 min read

reorx/httpstat ( and followed @davecheney’s golang implementation ) is getting hot recently ( there is also node implementation !) . It’s very useful to see these latency with intuitive way in console when something wrong happens on network.

While contributing the project, I thought it’s very useful if I can output the same information on my own golang HTTP client ( or my network connected CLI tool ) when debugging. So I wrote a small package to do this, https://github.com/tcnksm/go-httpstat .

Because it creates a httptrace powered `context.Context`, you just need to pass it to your `http.Request` by `withContext()` method ( So must be less code modification !).

The following is an example usage of this package (trace request to https://github.com ).

// Create a new HTTP request
req, err := http.NewRequest("GET", "https://github.com", nil)
if err != nil {
log.Fatal(err)
}
// Create a httpstat powered context
var result httpstat.Result
ctx := httpstat.WithHTTPStat(req.Context(), &result)
req = req.WithContext(ctx)
// Send request by default HTTP client
client := http.DefaultClient
res, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
if _, err := io.Copy(ioutil.Discard, res.Body); err != nil {
log.Fatal(err)
}
res.Body.Close()
end := time.Now()
// Show the results
log.Printf("DNS lookup: %d ms", int(result.DNSLookup/time.Millisecond))
log.Printf("TCP connection: %d ms", int(result.TCPConnection/time.Millisecond))
log.Printf("TLS handshake: %d ms", int(result.TLSHandshake/time.Millisecond))
log.Printf("Server processing: %d ms", int(result.ServerProcessing/time.Millisecond))
log.Printf("Content transfer: %d ms", int(result.ContentTransfer(time.Now())/time.Millisecond))

The result of this is like below,

2016/09/27 17:58:38 DNS lookup: 5 ms
2016/09/27 17:58:38 TCP connection: 180 ms
2016/09/27 17:58:38 TLS handshake: 461 ms
2016/09/27 17:58:38 Server processing: 296 ms
2016/09/27 17:58:38 Content transfer: 180 ms

The results are pretty much same as `httpstat` command. But there are some concerns about TLS handshaking time (see #7). Be care to use this in production as for now. I’ll continue to improve this.

If you find a something, please file a issue on Github.

deeeet

Written by

deeeet

Taichi Nakashima, a Gopher at Mercari Inc. https;://twitter.com/deeeet

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade