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) +}