Time Every HTTP Request Using net/http in Go

In our continuing quest to show you how to time everything in your code, here’s how you can time every http request in a net/http powered Go web server.

It builds upon the same ideas as our Time Any Function in Go post. We changed the timeTrack function slightly:

{% highlight go %} func timeTrack(start time.Time, name string) { elapsed := time.Since(start) log.Printf(“%s request took %s”, name, elapsed) } {% endhighlight %}

We’re going to use the web server code from golang.org’s Effective Go document.

To register a handler, it does this:

{% highlight go %} http.Handle(“/”, http.HandlerFunc(QR)) {% endhighlight %}

Here’s a closure that will call our timeTrack function:

{% highlight go %} func track(fn http.HandlerFunc, name string) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { defer timeTrack(time.Now(), name) fn(w, req) } } {% endhighlight %}

So change the Handle call to use our closure:

{% highlight go %} http.Handle(“/”, track(QR, “root”)) {% endhighlight %}

And now every request will be timed.

By the way, if anyone out there is using our bingo context handlers, it calculates request times for you. To get access to them, set bingo.NotifyRequestTime to any function that takes a time.Duration and path string as parameters.

{% highlight go %} func logSlowRequests(elapsed time.Duration, path string) { if elapsed > 100 * time.Millisecond { log.Warnf(“slow request %s: %s”, path, elapsed) } }

func main() { bingo.NotifyRequestTime = logSlowRequests } {% endhighlight %}

Comments? Send us a tweet.


Refactoring with sed
New Twitter Account @stathat