internal/requestlog: add end-to-end benchmarks

Results from my workstation:

BenchmarkE2E/Baseline-12  	   20000	     85744 ns/op	    5171 B/op	      68 allocs/op
BenchmarkE2E/WithLog-12   	   20000	     98693 ns/op	    6321 B/op	     102 allocs/op

We can expect ~10us CPU and ~1KB RAM of overhead per each request.
Likely fluentd will be the bottleneck at that point.

I dug in with the profiler and the overhead is almost entirely coming
from JSON encoding.  If performances becomes an issue, use of the
encoding/json package could be eschewed for a custom marshaler.

Change-Id: I757740b31d168ac339e4775bf24212ba12329ae9
Reviewed-on: https://go-review.googlesource.com/73770
Reviewed-by: Sarah Adams <shadams@google.com>
diff --git a/internal/requestlog/fluentd_test.go b/internal/requestlog/fluentd_test.go
index 8bdf243..ac64428 100644
--- a/internal/requestlog/fluentd_test.go
+++ b/internal/requestlog/fluentd_test.go
@@ -9,7 +9,11 @@
 import (
 	"bytes"
 	"encoding/json"
+	"fmt"
+	"io"
 	"io/ioutil"
+	"net/http"
+	"net/http/httptest"
 	"strings"
 	"testing"
 	"time"
@@ -184,3 +188,32 @@
 		l.Log(ent)
 	}
 }
+
+func BenchmarkE2E(b *testing.B) {
+	run := func(b *testing.B, handler http.Handler) {
+		s := httptest.NewServer(handler)
+		defer s.Close()
+		b.ReportAllocs()
+		for i := 0; i < b.N; i++ {
+			resp, err := s.Client().Get(s.URL)
+			if err != nil {
+				b.Fatal(err)
+			}
+			io.Copy(ioutil.Discard, resp.Body)
+			resp.Body.Close()
+		}
+	}
+	b.Run("Baseline", func(b *testing.B) {
+		run(b, http.HandlerFunc(benchHandler))
+	})
+	b.Run("WithLog", func(b *testing.B) {
+		l := NewFluentdLogger(ioutil.Discard, "mytag", func(error) {})
+		run(b, NewHandler(l, http.HandlerFunc(benchHandler)))
+	})
+}
+
+func benchHandler(w http.ResponseWriter, r *http.Request) {
+	const msg = "Hello, World!"
+	w.Header().Set("Content-Length", fmt.Sprint(len(msg)))
+	io.WriteString(w, msg)
+}