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