slog: add benchmarks for zerolog

Add benchmarks for github.com/rs/zerolog, another popular structured
logging package.  Put them in a separate module to avoid having
the exp repo depend on zerolog.

Zerolog doesn't support flexible handlers: it outputs only JSON or
(with a compile-time tag) CBOR. Treat JSON output to io.Discard
as the "fastText discard" case.

Implement only the most important benchmarks: "fastTest discard"
with 5 and 10 arguments.

Also, rename zapbenchmarks to zap_benchmarks for consistency.

Change-Id: I1a58c9b1c9054d88c0e677cfffd1b627d6065dce
Reviewed-on: https://go-review.googlesource.com/c/exp/+/461996
Run-TryBot: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/slog/benchmarks/zapbenchmarks/go.mod b/slog/benchmarks/zap_benchmarks/go.mod
similarity index 81%
rename from slog/benchmarks/zapbenchmarks/go.mod
rename to slog/benchmarks/zap_benchmarks/go.mod
index 316b87c..80c31ad 100644
--- a/slog/benchmarks/zapbenchmarks/go.mod
+++ b/slog/benchmarks/zap_benchmarks/go.mod
@@ -1,4 +1,4 @@
-module golang.org/x/exp/slog/benchmarks/zapbenchmarks
+module golang.org/x/exp/slog/benchmarks/zap_benchmarks
 
 go 1.19
 
diff --git a/slog/benchmarks/zapbenchmarks/go.sum b/slog/benchmarks/zap_benchmarks/go.sum
similarity index 100%
rename from slog/benchmarks/zapbenchmarks/go.sum
rename to slog/benchmarks/zap_benchmarks/go.sum
diff --git a/slog/benchmarks/zapbenchmarks/run_benchmarks.sh b/slog/benchmarks/zap_benchmarks/run_benchmarks.sh
similarity index 100%
rename from slog/benchmarks/zapbenchmarks/run_benchmarks.sh
rename to slog/benchmarks/zap_benchmarks/run_benchmarks.sh
diff --git a/slog/benchmarks/zapbenchmarks/zap.bench b/slog/benchmarks/zap_benchmarks/zap.bench
similarity index 100%
rename from slog/benchmarks/zapbenchmarks/zap.bench
rename to slog/benchmarks/zap_benchmarks/zap.bench
diff --git a/slog/benchmarks/zapbenchmarks/zap_benchmarks_test.go b/slog/benchmarks/zap_benchmarks/zap_benchmarks_test.go
similarity index 99%
rename from slog/benchmarks/zapbenchmarks/zap_benchmarks_test.go
rename to slog/benchmarks/zap_benchmarks/zap_benchmarks_test.go
index 30f4fd2..b8fe875 100644
--- a/slog/benchmarks/zapbenchmarks/zap_benchmarks_test.go
+++ b/slog/benchmarks/zap_benchmarks/zap_benchmarks_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package zapbenchmarks
+package zap_benchmarks
 
 import (
 	"testing"
diff --git a/slog/benchmarks/zapbenchmarks/zap_encoders.go b/slog/benchmarks/zap_benchmarks/zap_encoders.go
similarity index 99%
rename from slog/benchmarks/zapbenchmarks/zap_encoders.go
rename to slog/benchmarks/zap_benchmarks/zap_encoders.go
index ded1142..918d2dd 100644
--- a/slog/benchmarks/zapbenchmarks/zap_encoders.go
+++ b/slog/benchmarks/zap_benchmarks/zap_encoders.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package zapbenchmarks
+package zap_benchmarks
 
 import (
 	"io"
diff --git a/slog/benchmarks/zapbenchmarks/zap_encoders_test.go b/slog/benchmarks/zap_benchmarks/zap_encoders_test.go
similarity index 98%
rename from slog/benchmarks/zapbenchmarks/zap_encoders_test.go
rename to slog/benchmarks/zap_benchmarks/zap_encoders_test.go
index 0058d9a..2e28cf1 100644
--- a/slog/benchmarks/zapbenchmarks/zap_encoders_test.go
+++ b/slog/benchmarks/zap_benchmarks/zap_encoders_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package zapbenchmarks
+package zap_benchmarks
 
 import (
 	"fmt"
diff --git a/slog/benchmarks/zerolog_benchmarks/go.mod b/slog/benchmarks/zerolog_benchmarks/go.mod
new file mode 100644
index 0000000..5a6704d
--- /dev/null
+++ b/slog/benchmarks/zerolog_benchmarks/go.mod
@@ -0,0 +1,13 @@
+module golang.org/x/exp/slog/benchmarks/zerolog_benchmarks
+
+go 1.20
+
+require (
+	github.com/mattn/go-colorable v0.1.12 // indirect
+	github.com/mattn/go-isatty v0.0.14 // indirect
+	github.com/rs/zerolog v1.28.0 // indirect
+	golang.org/x/exp v0.0.0-20230113152452-c42ee1cf562e // indirect
+	golang.org/x/sys v0.1.0 // indirect
+)
+
+replace golang.org/x/exp => ../../..
diff --git a/slog/benchmarks/zerolog_benchmarks/go.sum b/slog/benchmarks/zerolog_benchmarks/go.sum
new file mode 100644
index 0000000..ba2790d
--- /dev/null
+++ b/slog/benchmarks/zerolog_benchmarks/go.sum
@@ -0,0 +1,15 @@
+github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
+github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
+github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
+github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
+github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
+github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
+github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo=
+golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
diff --git a/slog/benchmarks/zerolog_benchmarks/run_benchmarks.sh b/slog/benchmarks/zerolog_benchmarks/run_benchmarks.sh
new file mode 100755
index 0000000..428022b
--- /dev/null
+++ b/slog/benchmarks/zerolog_benchmarks/run_benchmarks.sh
@@ -0,0 +1,14 @@
+#!/bin/bash -e
+
+go=${1:-go}
+
+cd $(dirname $0)
+
+set -x
+
+# Run all benchmarks a few times and capture to a file.
+$go test -bench . -count 5 > zerolog.bench
+
+# Rename the package in the output to fool benchstat into comparing
+# these benchmarks with the ones in the parent directory.
+sed -i -e 's?^pkg: .*$?pkg: golang.org/x/exp/slog/benchmarks?' zerolog.bench
diff --git a/slog/benchmarks/zerolog_benchmarks/zerolog_benchmarks_test.go b/slog/benchmarks/zerolog_benchmarks/zerolog_benchmarks_test.go
new file mode 100644
index 0000000..d2cc8b7
--- /dev/null
+++ b/slog/benchmarks/zerolog_benchmarks/zerolog_benchmarks_test.go
@@ -0,0 +1,55 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package zerolog_benchmarks
+
+import (
+	"io"
+	"testing"
+
+	"github.com/rs/zerolog"
+	slogbench "golang.org/x/exp/slog/benchmarks"
+)
+
+// Keep in sync (same names and behavior) as the
+// benchmarks in the parent directory.
+
+func BenchmarkAttrs(b *testing.B) {
+	logger := zerolog.New(io.Discard).With().Timestamp().Logger()
+	b.Run("fastText discard", func(b *testing.B) {
+		b.Run("5 args", func(b *testing.B) {
+			b.ReportAllocs()
+			b.RunParallel(func(pb *testing.PB) {
+				for pb.Next() {
+					logger.Info().
+						Str("string", slogbench.TestString).
+						Int("status", slogbench.TestInt).
+						Dur("duration", slogbench.TestDuration).
+						Time("time", slogbench.TestTime).
+						Err(slogbench.TestError).
+						Msg(slogbench.TestMessage)
+				}
+			})
+		})
+		b.Run("10 args", func(b *testing.B) {
+			b.ReportAllocs()
+			b.RunParallel(func(pb *testing.PB) {
+				for pb.Next() {
+					logger.Info().
+						Str("string", slogbench.TestString).
+						Int("status", slogbench.TestInt).
+						Dur("duration", slogbench.TestDuration).
+						Time("time", slogbench.TestTime).
+						Err(slogbench.TestError).
+						Str("string", slogbench.TestString).
+						Int("status", slogbench.TestInt).
+						Dur("duration", slogbench.TestDuration).
+						Time("time", slogbench.TestTime).
+						Err(slogbench.TestError).
+						Msg(slogbench.TestMessage)
+				}
+			})
+		})
+	})
+}