Skip to content

Commit ea55aa8

Browse files
committed
httplog: bench normal and structured logger
go test -bench=. -benchmem -benchtime 10s goos: darwin goarch: arm64 pkg: github.com/saucelabs/forwarder/httplog cpu: Apple M1 Pro BenchmarkNormalShortURL-10 33868418 352.9 ns/op 288 B/op 11 allocs/op BenchmarkNormalHeaders-10 3090453 3852 ns/op 7480 B/op 52 allocs/op BenchmarkNormalBody-10 2540685 4772 ns/op 10299 B/op 60 allocs/op BenchmarkStructuredShortURL-10 42058107 287.0 ns/op 464 B/op 8 allocs/op BenchmarkStructuredHeaders-10 7712139 1558 ns/op 2704 B/op 22 allocs/op BenchmarkStructuredBody-10 6497708 1852 ns/op 3904 B/op 30 allocs/op PASS Note: Actual performance may vary depending on the logFunc implementation and the sink.
1 parent 7c99150 commit ea55aa8

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

httplog/httplog_bench_test.go

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// Copyright 2022-2024 Sauce Labs Inc., all rights reserved.
2+
//
3+
// This Source Code Form is subject to the terms of the Mozilla Public
4+
// License, v. 2.0. If a copy of the MPL was not distributed with this
5+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
6+
7+
package httplog
8+
9+
import (
10+
"io"
11+
"net/http"
12+
"strings"
13+
"testing"
14+
"time"
15+
16+
"github.com/saucelabs/forwarder/middleware"
17+
)
18+
19+
var (
20+
message string
21+
arguments []any
22+
)
23+
24+
func dummyLogFunc(msg string, args ...any) {
25+
message = msg
26+
arguments = args
27+
}
28+
29+
// benchmarkLogger runs the given logger for a fixed log entry.
30+
func benchmarkLogger(b *testing.B, logFunc middleware.Logger) {
31+
b.Helper()
32+
33+
reqBody := "sample request body"
34+
req, err := http.NewRequest(http.MethodGet, "http://example.com", io.NopCloser(strings.NewReader(reqBody)))
35+
if err != nil {
36+
b.Fatal(err)
37+
}
38+
req.Header.Add("X-Custom-Request-1", "RequestHeaderValue")
39+
req.Header.Add("X-Custom-Request-2", "RequestHeaderValue")
40+
req.Header.Add("X-Custom-Request-3", "RequestHeaderValue")
41+
req.TransferEncoding = []string{"chunked"}
42+
req.Trailer = http.Header{"X-Trailer-Request": []string{"TrailerValue"}}
43+
44+
res := &http.Response{
45+
StatusCode: http.StatusOK,
46+
Status: "200 OK",
47+
Proto: "HTTP/1.1",
48+
Header: make(http.Header),
49+
TransferEncoding: []string{"chunked"},
50+
}
51+
res.Header.Add("X-Custom-Response", "ResponseHeaderValue")
52+
res.Header.Add("X-Custom-Response-1", "ResponseHeaderValue")
53+
res.Header.Add("X-Custom-Response-2", "ResponseHeaderValue")
54+
res.Header.Add("X-Custom-Response-3", "ResponseHeaderValue")
55+
res.Header.Add("X-Custom-Response-4", "ResponseHeaderValue")
56+
res.Header.Add("X-Custom-Response-5", "ResponseHeaderValue")
57+
res.Header.Add("X-Custom-Response-6", "ResponseHeaderValue")
58+
res.Header.Add("X-Custom-Response-7", "ResponseHeaderValue")
59+
res.Header.Add("X-Custom-Response-8", "ResponseHeaderValue")
60+
res.Header.Add("X-Custom-Response-9", "ResponseHeaderValue")
61+
resBody := "sample response body"
62+
res.Body = io.NopCloser(strings.NewReader(resBody))
63+
res.ContentLength = int64(len(resBody))
64+
res.Trailer = http.Header{"X-Trailer-Response": []string{"TrailerValue"}}
65+
66+
entry := middleware.LogEntry{
67+
Request: req,
68+
Response: res,
69+
Status: res.StatusCode,
70+
Duration: 100 * time.Millisecond,
71+
}
72+
73+
b.ResetTimer()
74+
for i := 0; i < b.N; i++ {
75+
logFunc(entry)
76+
}
77+
}
78+
79+
// BenchmarkNormalShortURL benchmarks a normal (non-structured) logger in ShortURL mode.
80+
func BenchmarkNormalShortURL(b *testing.B) {
81+
logger := NewLogger(dummyLogFunc, ShortURL)
82+
benchmarkLogger(b, logger.LogFunc())
83+
}
84+
85+
// BenchmarkNormalHeaders benchmarks a normal (non-structured) logger in Headers mode.
86+
func BenchmarkNormalHeaders(b *testing.B) {
87+
logger := NewLogger(dummyLogFunc, Headers)
88+
benchmarkLogger(b, logger.LogFunc())
89+
}
90+
91+
// BenchmarkNormalBody benchmarks a normal (non-structured) logger in Body mode.
92+
func BenchmarkNormalBody(b *testing.B) {
93+
logger := NewLogger(dummyLogFunc, Body)
94+
benchmarkLogger(b, logger.LogFunc())
95+
}
96+
97+
// BenchmarkStructuredShortURL benchmarks a structured logger in ShortURL mode.
98+
func BenchmarkStructuredShortURL(b *testing.B) {
99+
logger := NewStructuredLogger(dummyLogFunc, ShortURL)
100+
benchmarkLogger(b, logger.LogFunc())
101+
}
102+
103+
// BenchmarkStructuredHeaders benchmarks a structured logger in Headers mode.
104+
func BenchmarkStructuredHeaders(b *testing.B) {
105+
logger := NewStructuredLogger(dummyLogFunc, Headers)
106+
benchmarkLogger(b, logger.LogFunc())
107+
}
108+
109+
// BenchmarkStructuredBody benchmarks a structured logger in Body mode.
110+
func BenchmarkStructuredBody(b *testing.B) {
111+
logger := NewStructuredLogger(dummyLogFunc, Body)
112+
benchmarkLogger(b, logger.LogFunc())
113+
}

0 commit comments

Comments
 (0)