├── Makefile ├── README.md ├── fortiolog_test.go ├── go.mod ├── go.sum ├── gokit_test.go ├── gologging_test.go ├── log15_test.go ├── logrus_test.go ├── seelog_test.go ├── support_test.go └── zerolog_test.go /Makefile: -------------------------------------------------------------------------------- 1 | GOTEST_FLAGS=-cpu=1,2,4 -benchmem -benchtime=5s 2 | 3 | TEXT_PKGS=Gokit Logrus Log15 Gologging Seelog Zerolog Fortiolog 4 | JSON_PKGS=Gokit Logrus Log15 Zerolog 5 | 6 | TEXT_PKG_TARGETS=$(addprefix test-text-,$(TEXT_PKGS)) 7 | JSON_PKG_TARGETS=$(addprefix test-json-,$(JSON_PKGS)) 8 | 9 | .PHONY: all deps test test-text test-json $(TEXT_PKG_TARGETS) $(JSON_PKG_TARGETS) 10 | 11 | all: deps test 12 | 13 | deps: 14 | go get -u github.com/sirupsen/logrus 15 | go get -u gopkg.in/inconshreveable/log15.v2 16 | go get -u github.com/op/go-logging 17 | go get -u github.com/cihub/seelog 18 | go get -u github.com/go-kit/kit/log 19 | go get -u github.com/rs/zerolog 20 | go get -u fortio.org/fortio 21 | 22 | test: test-text test-json 23 | 24 | test-text: $(TEXT_PKG_TARGETS) 25 | 26 | $(TEXT_PKG_TARGETS): test-text-%: 27 | go test $(GOTEST_FLAGS) -bench "$*.*Text" 28 | 29 | test-json: $(JSON_PKG_TARGETS) 30 | 31 | $(JSON_PKG_TARGETS): test-json-%: 32 | go test $(GOTEST_FLAGS) -bench "$*.*JSON" 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Benchmarking logging libraries for Go 2 | 3 | I compared a varity of logging libraries for Go, and performed 2 types of tests 4 | for 2 logging formats. 5 | 6 | Types of test: 7 | 8 | - Positive tests: everything will be logged because the baseline log level is 9 | set to lower or equal the level I am logging with. 10 | - Negative tests: nothing will be logged because I set the baseline log level 11 | to ```ERROR``` but log wih ```INFO```. This is important, because the faster 12 | it bails-out, and the less pressure the library puts on the GC, the better! 13 | 14 | Formats: 15 | 16 | - Text: there are a few minor differences among loggers, but I tried to follow 17 | a ```Time Level Message``` format). 18 | - JSON: few loggers support this but it is still interesting. 19 | 20 | # Running the tests 21 | 22 | On a terminal, just execute: 23 | 24 | ```shell 25 | make 26 | ``` 27 | 28 | # Results 29 | 30 | I ran these tests on Mac OSX 10.11.4 using 1.6 GHz Intel Core i5 Macbook Air 31 | with 8 GB 1600 MHz DDR3 memory. 32 | 33 | Overall, Go kit performed the best, though it has a quirky way of specifying 34 | levels. 35 | 36 | I was surprised with log15 because it seemed not to take advantage of the 2 or 4 37 | goroutines. I believe this is because it probably performs most of its 38 | operations inside some mutex-protected execution path right before flushing the 39 | log to the output stream. 40 | 41 | When it comes to negative tests for JSON, all loggers made too many allocations 42 | for my taste. This is especially bad if you carpet bomb your program with 43 | debug-level log lines but want to disable it in production: it puts too much 44 | unecessary pressure on GC, leads to all sorts of problems including memory 45 | fragmentation. This is something I would like to see improved in future 46 | versions! 47 | 48 | ## Take 2 (September 2017) 49 | 50 | Two years later, same test ran with Go 1.9 on Mac OSX 10.12.6 using 2.7GHz 51 | Intel Core i7 Macbook Pro with 16 GB 2133 MHz LPDDR3 memory. 52 | 53 | Overall, zerolog performed the best by a substantial margin with a constant 54 | 0 allocations for both text and JSON (output is always JSON) with positive and 55 | negative tests. 56 | 57 | ## benchstat 58 | 59 | ### TextPositive 60 | 61 | | test | op time | op alloc sz | op alloc count | 62 | |-------------------------|----------------|--------------|----------------| 63 | | GokitTextPositive-4 | 442ns ± 4% | 256B ± 0% | 4.00 ± 0% | 64 | | GologgingTextPositive-4 | 628ns ± 1% | 920B ± 0% | 17.0 ± 0% | 65 | | Log15TextPositive-4 | 3.60µs ± 3% | 1.12kB ± 0% | 24.0 ± 0% | 66 | | LogrusTextPositive-4 | 665ns ± 2% | 320B ± 0% | 15.0 ± 0% | 67 | | SeelogTextPositive-4 | 2.18µs ± 1% | 440B ± 0% | 11.0 ± 0% | 68 | | ZerologTextPositive-4 | **130ns ± 4%** | **0.00B** | **0.00** | 69 | 70 | ### TextNegative 71 | 72 | | test | op time | op alloc sz | op alloc count | 73 | |-------------------------|-----------------|-------------|----------------| 74 | | GokitTextNegative-4 | 16.7ns ± 1% | 32.0B ± 0% | 1.00 ± 0% | 75 | | GologgingTextNegative-4 | 61.4ns ± 1% | 144B ± 0% | 3.00 ± 0% | 76 | | Log15TextNegative-4 | 142ns ± 3% | 128B ± 0% | 2.00 ± 0% | 77 | | LogrusTextNegative-4 | **0.98ns ± 4%** |**0.00B** | **0.00** | 78 | | SeelogTextNegative-4 | 22.5ns ± 2% | 48.0B ± 0% | 2.00 ± 0% | 79 | | ZerologTextNegative-4 | 4.34ns ± 0% |**0.00B** | **0.00** | 80 | 81 | ### JSONPositive 82 | 83 | | test | op time | op alloc sz | op alloc count | 84 | |-------------------------|----------------|-------------|----------------| 85 | | GokitJSONPositive-4 | 1.42µs ± 4% | 1.55kB ± 0% | 24.0 ± 0% | 86 | | Log15JSONPositive-4 | 6.56µs ± 1% | 2.01kB ± 0% | 30.0 ± 0% | 87 | | LogrusJSONPositive-4 | 1.81µs ± 3% | 2.45kB ± 0% | 33.0 ± 0% | 88 | | ZerologJSONPositive-4 | **195ns ± 3%** |**0.00B** | **0.00** | 89 | 90 | ### JSONNegative 91 | 92 | | test | op time | op alloc sz | op alloc count | 93 | |-------------------------|-----------------|-------------|----------------| 94 | | GokitJSONNegative-4 | 27.3ns ± 2% | 128B ± 0% | 1.00 ± 0% | 95 | | Log15JSONNegative-4 | 189ns ± 2% | 320B ± 0% | 3.00 ± 0% | 96 | | LogrusJSONNegative-4 | 257ns ± 2% | 752B ± 0% | 5.00 ± 0% | 97 | | ZerologJSONNegative-4 | **6.39ns ± 2%** |**0.00B** | **0.00** | 98 | 99 | ## Raw data 100 | 101 | ### TextPositive 102 | 103 | | test | ops | ns/op | bytes/op | allocs/op | 104 | |----------------------------------|----------|---------------|-------------|-----------------| 105 | | BenchmarkGokitTextPositive-4 | 20000000 | 428 ns/op | 256 B/op | 4 allocs/op | 106 | | BenchmarkGologgingTextPositive-4 | 10000000 | 621 ns/op | 920 B/op | 15 allocs/op | 107 | | BenchmarkLog15TextPositive-4 | 2000000 | 3612 ns/op | 1120 B/op | 24 allocs/op | 108 | | BenchmarkLogrusTextPositive-4 | 10000000 | 657 ns/op | 320 B/op | 10 allocs/op | 109 | | BenchmarkSeelogTextPositive-4 | 3000000 | 2197 ns/op | 440 B/op | 11 allocs/op | 110 | | BenchmarkZerologTextPositive-4 | 50000000 | **125 ns/op** | **0 B/op** | **0 allocs/op** | 111 | 112 | ### TextNegative 113 | 114 | | test | ops | ns/op | bytes/op | allocs/op | 115 | |----------------------------------|-------------|----------------|-------------|-----------------| 116 | | BenchmarkGokitTextNegative-4 | 500000000 | 16.7 ns/op | 32 B/op | 1 allocs/op | 117 | | BenchmarkGologgingTextNegative-4 | 100000000 | 60.8 ns/op | 144 B/op | 2 allocs/op | 118 | | BenchmarkLog15TextNegative-4 | 50000000 | 146 ns/op | 128 B/op | 1 allocs/op | 119 | | BenchmarkLogrusTextNegative-4 | 10000000000 | **1.02 ns/op** | 0 B/op | 0 allocs/op | 120 | | BenchmarkSeelogTextNegative-4 | 300000000 | 22.1 ns/op | 48 B/op | 2 allocs/op | 121 | | BenchmarkZerologTextNegative-4 | 2000000000 | 4.34 ns/op | **0 B/op** | **0 allocs/op** | 122 | 123 | ### JSONPositive 124 | 125 | | test | ops | ns/op | bytes/op | allocs/op | 126 | |--------------------------------|----------|---------------|-------------|-----------------| 127 | | BenchmarkGokitJSONPositive-4 | 5000000 | 1398 ns/op | 1552 B/op | 24 allocs/op | 128 | | BenchmarkLog15JSONPositive-4 | 1000000 | 6599 ns/op | 2008 B/op | 30 allocs/op | 129 | | BenchmarkLogrusJSONPositive-4 | 5000000 | 1761 ns/op | 2450 B/op | 33 allocs/op | 130 | | BenchmarkZerologJSONPositive-4 | 30000000 | **195 ns/op** | **0 B/op** | **0 allocs/op** | 131 | 132 | ### JSONNegative 133 | 134 | | test | ops | ns/op | bytes/op | allocs/op | 135 | |--------------------------------|------------|----------------|------------|-----------------| 136 | | BenchmarkGokitJSONNegative-4 | 300000000 | 27.0 ns/op | 128 B/op | 1 allocs/op | 137 | | BenchmarkLog15JSONNegative-4 | 30000000 | 188 ns/op | 320 B/op | 3 allocs/op | 138 | | BenchmarkLogrusJSONNegative-4 | 30000000 | 255 ns/op | 752 B/op | 5 allocs/op | 139 | | BenchmarkZerologJSONNegative-4 | 1000000000 | **6.26 ns/op** | **0 B/op** | **0 allocs/op** | 140 | -------------------------------------------------------------------------------- /fortiolog_test.go: -------------------------------------------------------------------------------- 1 | package bench 2 | 3 | import ( 4 | "testing" 5 | 6 | log "fortio.org/fortio/log" 7 | ) 8 | 9 | func BenchmarkFortiologTextNegative(b *testing.B) { 10 | stream := &blackholeStream{} 11 | log.SetLogLevel(log.Error) 12 | log.SetOutput(stream) 13 | b.ResetTimer() 14 | 15 | b.RunParallel(func(pb *testing.PB) { 16 | for pb.Next() { 17 | log.Infof("The quick brown fox jumps over the lazy dog") 18 | } 19 | }) 20 | 21 | if stream.WriteCount() != uint64(0) { 22 | b.Fatalf("Log write count") 23 | } 24 | } 25 | 26 | func BenchmarkFortiologTextPositive(b *testing.B) { 27 | stream := &blackholeStream{} 28 | log.SetLogLevel(log.Info) 29 | log.SetOutput(stream) 30 | b.ResetTimer() 31 | 32 | b.RunParallel(func(pb *testing.PB) { 33 | for pb.Next() { 34 | log.Infof("The quick brown fox jumps over the lazy dog") 35 | } 36 | }) 37 | 38 | if stream.WriteCount() != uint64(b.N) { 39 | b.Fatalf("Log write count") 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/imkira/go-loggers-bench 2 | 3 | go 1.17 4 | 5 | require ( 6 | fortio.org/fortio v1.20.0 7 | github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 8 | github.com/go-kit/kit v0.12.0 9 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 10 | github.com/rs/zerolog v1.26.1 11 | github.com/sirupsen/logrus v1.8.1 12 | gopkg.in/inconshreveable/log15.v2 v2.0.0-20200109203555-b30bc20e4fd1 13 | ) 14 | 15 | require ( 16 | github.com/go-kit/log v0.2.0 // indirect 17 | github.com/go-logfmt/logfmt v0.5.1 // indirect 18 | github.com/go-stack/stack v1.8.1 // indirect 19 | github.com/mattn/go-colorable v0.1.12 // indirect 20 | github.com/mattn/go-isatty v0.0.14 // indirect 21 | golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect 22 | ) 23 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | fortio.org/fortio v1.20.0 h1:dftxjb6zm4VQsVwU0ztApTtNCcVwOfLfHxgiRZ00sF8= 3 | fortio.org/fortio v1.20.0/go.mod h1:radJAQIynw4V5XXPOQSHlE1V4MxvUkWpd0PW5vbVF2M= 4 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 5 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 6 | github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 h1:kHaBemcxl8o/pQ5VM1c8PVE1PubbNx3mjUr09OqWGCs= 7 | github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575/go.mod h1:9d6lWj8KzO/fd/NrVaLscBKmPigpZpn5YawRPw+e3Yo= 8 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 9 | github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= 10 | github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 11 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 12 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 13 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 14 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 15 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 16 | github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 17 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 18 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 19 | github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= 20 | github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= 21 | github.com/go-kit/log v0.2.0 h1:7i2K3eKTos3Vc0enKCfnVcgHh2olr/MyfboYq7cAcFw= 22 | github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= 23 | github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= 24 | github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= 25 | github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= 26 | github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= 27 | github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 28 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 29 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 30 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 31 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 32 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 33 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 34 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 35 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 36 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 37 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= 38 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 39 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 40 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 41 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 42 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 43 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 44 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 45 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 46 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 47 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 48 | github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 49 | github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= 50 | github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 51 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= 52 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 53 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= 54 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= 55 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 56 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 57 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 58 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 59 | github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= 60 | github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc= 61 | github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc= 62 | github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= 63 | github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= 64 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 65 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 66 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 67 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 68 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 69 | github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 70 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 71 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 72 | golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= 73 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 74 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 75 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 76 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 77 | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 78 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 79 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 80 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 81 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 82 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 83 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 84 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 85 | golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 86 | golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 87 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 88 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 89 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 90 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 91 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 92 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 93 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 94 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 95 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 96 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 97 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 98 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 99 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 100 | golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 101 | golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 102 | golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= 103 | golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 104 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 105 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 106 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 107 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 108 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 109 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 110 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 111 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 112 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 113 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 114 | golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= 115 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 116 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 117 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 118 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 119 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 120 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 121 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 122 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 123 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= 124 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 125 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 126 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= 127 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 128 | google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= 129 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 130 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 131 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 132 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 133 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 134 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 135 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 136 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 137 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 138 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 139 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 140 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 141 | gopkg.in/inconshreveable/log15.v2 v2.0.0-20200109203555-b30bc20e4fd1 h1:iiHuQZCNgYPmFQxd3BBN/Nc5+dAwzZuq5y40s20oQw0= 142 | gopkg.in/inconshreveable/log15.v2 v2.0.0-20200109203555-b30bc20e4fd1/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= 143 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 144 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 145 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 146 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 147 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 148 | -------------------------------------------------------------------------------- /gokit_test.go: -------------------------------------------------------------------------------- 1 | package bench 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | 7 | "github.com/go-kit/kit/log" 8 | ) 9 | 10 | // Go kit's logger has no concept of dynamically mutable levels. The idiom is to 11 | // predeclare your desired level during construction. This is an example helper 12 | // constructor that performs that work. If positive is true, both info and error 13 | // are logged. Otherwise, only error is logged. 14 | func newLeveledLogger(logger log.Logger, positive bool) *leveledLogger { 15 | infoLogger := log.NewNopLogger() 16 | if positive { 17 | infoLogger = log.With(logger, "level", "info") 18 | } 19 | return &leveledLogger{ 20 | Info: infoLogger, 21 | Error: log.With(logger, "level", "error"), 22 | } 23 | } 24 | 25 | type leveledLogger struct { 26 | Info log.Logger 27 | Error log.Logger 28 | } 29 | 30 | // For now, manually synchronize writes to the stream. 31 | type synchronizedStream struct { 32 | mtx sync.Mutex 33 | blackholeStream 34 | } 35 | 36 | func (s *synchronizedStream) Write(p []byte) (int, error) { 37 | s.mtx.Lock() 38 | n, err := s.blackholeStream.Write(p) 39 | s.mtx.Unlock() 40 | return n, err 41 | } 42 | 43 | func BenchmarkGokitJSONPositive(b *testing.B) { 44 | stream := &synchronizedStream{} 45 | logger := log.With(log.NewJSONLogger(stream), "ts", log.DefaultTimestampUTC) 46 | lvllog := newLeveledLogger(logger, true) 47 | 48 | b.ResetTimer() 49 | 50 | b.RunParallel(func(pb *testing.PB) { 51 | for pb.Next() { 52 | lvllog.Info.Log("msg", "The quick brown fox jumps over the lazy dog", "rate", 15, "low", 16, "high", 123.2) 53 | } 54 | }) 55 | 56 | if stream.WriteCount() != uint64(b.N) { 57 | b.Fatalf("Log write count") 58 | } 59 | } 60 | 61 | func BenchmarkGokitJSONNegative(b *testing.B) { 62 | stream := &synchronizedStream{} 63 | logger := log.With(log.NewJSONLogger(stream), "ts", log.DefaultTimestampUTC) 64 | lvllog := newLeveledLogger(logger, false) 65 | 66 | b.ResetTimer() 67 | 68 | b.RunParallel(func(pb *testing.PB) { 69 | for pb.Next() { 70 | lvllog.Info.Log("msg", "The quick brown fox jumps over the lazy dog", "rate", 15, "low", 16, "high", 123.2) 71 | } 72 | }) 73 | 74 | if stream.WriteCount() != uint64(0) { 75 | b.Fatalf("Log write count") 76 | } 77 | } 78 | 79 | func BenchmarkGokitTextPositive(b *testing.B) { 80 | stream := &synchronizedStream{} 81 | logger := log.With(log.NewLogfmtLogger(stream), "ts", log.DefaultTimestampUTC) 82 | lvllog := newLeveledLogger(logger, true) 83 | 84 | b.ResetTimer() 85 | 86 | b.RunParallel(func(pb *testing.PB) { 87 | for pb.Next() { 88 | lvllog.Info.Log("msg", "The quick brown fox jumps over the lazy dog") 89 | } 90 | }) 91 | 92 | if stream.WriteCount() != uint64(b.N) { 93 | b.Fatalf("Log write count") 94 | } 95 | } 96 | 97 | func BenchmarkGokitTextNegative(b *testing.B) { 98 | stream := &synchronizedStream{} 99 | logger := log.With(log.NewLogfmtLogger(stream), "ts", log.DefaultTimestampUTC) 100 | lvllog := newLeveledLogger(logger, false) 101 | 102 | b.ResetTimer() 103 | 104 | b.RunParallel(func(pb *testing.PB) { 105 | for pb.Next() { 106 | lvllog.Info.Log("msg", "The quick brown fox jumps over the lazy dog") 107 | } 108 | }) 109 | 110 | if stream.WriteCount() != uint64(0) { 111 | b.Fatalf("Log write count") 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /gologging_test.go: -------------------------------------------------------------------------------- 1 | package bench 2 | 3 | import ( 4 | "testing" 5 | 6 | log "github.com/op/go-logging" 7 | ) 8 | 9 | func BenchmarkGologgingTextNegative(b *testing.B) { 10 | stream := &blackholeStream{} 11 | logger := log.MustGetLogger("") 12 | subBackend := log.NewLogBackend(stream, "", 0) 13 | formatter := log.MustStringFormatter("%{time:2006-01-02T15:04:05Z07:00} %{level} %{message}") 14 | backend := log.NewBackendFormatter(subBackend, formatter) 15 | leveled := log.AddModuleLevel(backend) 16 | leveled.SetLevel(log.ERROR, "") 17 | logger.SetBackend(leveled) 18 | b.ResetTimer() 19 | 20 | b.RunParallel(func(pb *testing.PB) { 21 | for pb.Next() { 22 | logger.Info("The quick brown fox jumps over the lazy dog") 23 | } 24 | }) 25 | 26 | if stream.WriteCount() != uint64(0) { 27 | b.Fatalf("Log write count") 28 | } 29 | } 30 | 31 | func BenchmarkGologgingTextPositive(b *testing.B) { 32 | stream := &blackholeStream{} 33 | logger := log.MustGetLogger("") 34 | subBackend := log.NewLogBackend(stream, "", 0) 35 | formatter := log.MustStringFormatter("%{time:2006-01-02T15:04:05Z07:00} %{level} %{message}") 36 | backend := log.NewBackendFormatter(subBackend, formatter) 37 | leveled := log.AddModuleLevel(backend) 38 | logger.SetBackend(leveled) 39 | b.ResetTimer() 40 | 41 | b.RunParallel(func(pb *testing.PB) { 42 | for pb.Next() { 43 | logger.Info("The quick brown fox jumps over the lazy dog") 44 | } 45 | }) 46 | 47 | if stream.WriteCount() != uint64(b.N) { 48 | b.Fatalf("Log write count") 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /log15_test.go: -------------------------------------------------------------------------------- 1 | package bench 2 | 3 | import ( 4 | "testing" 5 | 6 | log "gopkg.in/inconshreveable/log15.v2" 7 | ) 8 | 9 | func BenchmarkLog15TextNegative(b *testing.B) { 10 | stream := &blackholeStream{} 11 | logger := log.New() 12 | logger.SetHandler(log.LvlFilterHandler( 13 | log.LvlError, 14 | log.StreamHandler(stream, log.LogfmtFormat())), 15 | ) 16 | b.ResetTimer() 17 | 18 | b.RunParallel(func(pb *testing.PB) { 19 | for pb.Next() { 20 | logger.Info("The quick brown fox jumps over the lazy dog") 21 | } 22 | }) 23 | 24 | if stream.WriteCount() != uint64(0) { 25 | b.Fatalf("Log write count") 26 | } 27 | } 28 | 29 | func BenchmarkLog15TextPositive(b *testing.B) { 30 | stream := &blackholeStream{} 31 | logger := log.New() 32 | logger.SetHandler(log.StreamHandler(stream, log.LogfmtFormat())) 33 | b.ResetTimer() 34 | 35 | b.RunParallel(func(pb *testing.PB) { 36 | for pb.Next() { 37 | logger.Info("The quick brown fox jumps over the lazy dog") 38 | } 39 | }) 40 | 41 | if stream.WriteCount() != uint64(b.N) { 42 | b.Fatalf("Log write count") 43 | } 44 | } 45 | 46 | func BenchmarkLog15JSONNegative(b *testing.B) { 47 | stream := &blackholeStream{} 48 | logger := log.New() 49 | logger.SetHandler(log.LvlFilterHandler( 50 | log.LvlError, 51 | log.StreamHandler(stream, log.JsonFormat())), 52 | ) 53 | b.ResetTimer() 54 | 55 | b.RunParallel(func(pb *testing.PB) { 56 | for pb.Next() { 57 | logger.Info("The quick brown fox jumps over the lazy dog", "rate", 15, "low", 16, "high", 123.2) 58 | } 59 | }) 60 | 61 | if stream.WriteCount() != uint64(0) { 62 | b.Fatalf("Log write count") 63 | } 64 | } 65 | 66 | func BenchmarkLog15JSONPositive(b *testing.B) { 67 | stream := &blackholeStream{} 68 | logger := log.New() 69 | logger.SetHandler(log.StreamHandler(stream, log.JsonFormat())) 70 | b.ResetTimer() 71 | 72 | b.RunParallel(func(pb *testing.PB) { 73 | for pb.Next() { 74 | logger.Info("The quick brown fox jumps over the lazy dog", "rate", 15, "low", 16, "high", 123.2) 75 | } 76 | }) 77 | 78 | if stream.WriteCount() != uint64(b.N) { 79 | b.Fatalf("Log write count") 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /logrus_test.go: -------------------------------------------------------------------------------- 1 | package bench 2 | 3 | import ( 4 | "testing" 5 | 6 | log "github.com/sirupsen/logrus" 7 | ) 8 | 9 | func BenchmarkLogrusTextPositive(b *testing.B) { 10 | stream := &blackholeStream{} 11 | logger := log.New() 12 | logger.Formatter = &log.TextFormatter{ 13 | DisableColors: true, 14 | FullTimestamp: true, 15 | DisableSorting: true, 16 | } 17 | logger.Out = stream 18 | b.ResetTimer() 19 | 20 | b.RunParallel(func(pb *testing.PB) { 21 | for pb.Next() { 22 | logger.Info("The quick brown fox jumps over the lazy dog") 23 | } 24 | }) 25 | 26 | if stream.WriteCount() != uint64(b.N) { 27 | b.Fatalf("Log write count") 28 | } 29 | } 30 | 31 | func BenchmarkLogrusTextNegative(b *testing.B) { 32 | stream := &blackholeStream{} 33 | logger := log.New() 34 | logger.Level = log.ErrorLevel 35 | logger.Formatter = &log.TextFormatter{ 36 | DisableColors: true, 37 | FullTimestamp: true, 38 | DisableSorting: true, 39 | } 40 | logger.Out = stream 41 | b.ResetTimer() 42 | 43 | b.RunParallel(func(pb *testing.PB) { 44 | for pb.Next() { 45 | logger.Info("The quick brown fox jumps over the lazy dog") 46 | } 47 | }) 48 | 49 | if stream.WriteCount() != uint64(0) { 50 | b.Fatalf("Log write count") 51 | } 52 | } 53 | 54 | func BenchmarkLogrusJSONNegative(b *testing.B) { 55 | stream := &blackholeStream{} 56 | logger := log.New() 57 | logger.Level = log.ErrorLevel 58 | logger.Formatter = &log.JSONFormatter{} 59 | logger.Out = stream 60 | b.ResetTimer() 61 | 62 | b.RunParallel(func(pb *testing.PB) { 63 | for pb.Next() { 64 | logger.WithFields(log.Fields{ 65 | "rate": "15", 66 | "low": 16, 67 | "high": 123.2, 68 | }).Info("The quick brown fox jumps over the lazy dog") 69 | } 70 | }) 71 | 72 | if stream.WriteCount() != uint64(0) { 73 | b.Fatalf("Log write count") 74 | } 75 | } 76 | 77 | func BenchmarkLogrusJSONPositive(b *testing.B) { 78 | stream := &blackholeStream{} 79 | logger := log.New() 80 | logger.Formatter = &log.JSONFormatter{} 81 | logger.Out = stream 82 | b.ResetTimer() 83 | 84 | b.RunParallel(func(pb *testing.PB) { 85 | for pb.Next() { 86 | logger.WithFields(log.Fields{ 87 | "rate": "15", 88 | "low": 16, 89 | "high": 123.2, 90 | }).Info("The quick brown fox jumps over the lazy dog") 91 | } 92 | }) 93 | 94 | if stream.WriteCount() != uint64(b.N) { 95 | b.Fatalf("Log write count") 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /seelog_test.go: -------------------------------------------------------------------------------- 1 | package bench 2 | 3 | import ( 4 | "testing" 5 | 6 | log "github.com/cihub/seelog" 7 | ) 8 | 9 | func BenchmarkSeelogTextNegative(b *testing.B) { 10 | stream := &blackholeStream{} 11 | logger, err := log.LoggerFromWriterWithMinLevelAndFormat(stream, log.ErrorLvl, "%Time %Level %Msg") 12 | if err != nil { 13 | b.Fatal(err) 14 | } 15 | b.ResetTimer() 16 | 17 | b.RunParallel(func(pb *testing.PB) { 18 | defer logger.Flush() 19 | for pb.Next() { 20 | logger.Info("The quick brown fox jumps over the lazy dog") 21 | } 22 | }) 23 | 24 | if stream.WriteCount() != uint64(0) { 25 | b.Fatalf("Log write count") 26 | } 27 | } 28 | 29 | func BenchmarkSeelogTextPositive(b *testing.B) { 30 | stream := &blackholeStream{} 31 | logger, err := log.LoggerFromWriterWithMinLevelAndFormat(stream, log.TraceLvl, "%Time %Level %Msg") 32 | if err != nil { 33 | b.Fatal(err) 34 | } 35 | b.ResetTimer() 36 | 37 | b.RunParallel(func(pb *testing.PB) { 38 | defer logger.Flush() 39 | for pb.Next() { 40 | logger.Info("The quick brown fox jumps over the lazy dog") 41 | } 42 | }) 43 | 44 | if stream.WriteCount() != uint64(b.N) { 45 | b.Fatalf("Log write count") 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /support_test.go: -------------------------------------------------------------------------------- 1 | package bench 2 | 3 | import "sync/atomic" 4 | 5 | type blackholeStream struct { 6 | writeCount uint64 7 | } 8 | 9 | func (s *blackholeStream) WriteCount() uint64 { 10 | return atomic.LoadUint64(&s.writeCount) 11 | } 12 | 13 | func (s *blackholeStream) Write(p []byte) (int, error) { 14 | atomic.AddUint64(&s.writeCount, 1) 15 | return len(p), nil 16 | } 17 | -------------------------------------------------------------------------------- /zerolog_test.go: -------------------------------------------------------------------------------- 1 | package bench 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/rs/zerolog" 7 | ) 8 | 9 | func BenchmarkZerologTextPositive(b *testing.B) { 10 | stream := &blackholeStream{} 11 | logger := zerolog.New(stream).With().Timestamp().Logger() 12 | b.ResetTimer() 13 | 14 | b.RunParallel(func(pb *testing.PB) { 15 | for pb.Next() { 16 | logger.Info().Msg("The quick brown fox jumps over the lazy dog") 17 | } 18 | }) 19 | 20 | if stream.WriteCount() != uint64(b.N) { 21 | b.Fatalf("Log write count") 22 | } 23 | } 24 | 25 | func BenchmarkZerologTextNegative(b *testing.B) { 26 | stream := &blackholeStream{} 27 | logger := zerolog.New(stream). 28 | Level(zerolog.ErrorLevel). 29 | With().Timestamp().Logger() 30 | b.ResetTimer() 31 | 32 | b.RunParallel(func(pb *testing.PB) { 33 | for pb.Next() { 34 | logger.Info().Msg("The quick brown fox jumps over the lazy dog") 35 | } 36 | }) 37 | 38 | if stream.WriteCount() != uint64(0) { 39 | b.Fatalf("Log write count") 40 | } 41 | } 42 | 43 | func BenchmarkZerologJSONNegative(b *testing.B) { 44 | stream := &blackholeStream{} 45 | logger := zerolog.New(stream). 46 | Level(zerolog.ErrorLevel). 47 | With().Timestamp().Logger() 48 | b.ResetTimer() 49 | 50 | b.RunParallel(func(pb *testing.PB) { 51 | for pb.Next() { 52 | logger.Info(). 53 | Str("rate", "15"). 54 | Int("low", 16). 55 | Float32("high", 123.2). 56 | Msg("The quick brown fox jumps over the lazy dog") 57 | } 58 | }) 59 | 60 | if stream.WriteCount() != uint64(0) { 61 | b.Fatalf("Log write count") 62 | } 63 | } 64 | 65 | func BenchmarkZerologJSONPositive(b *testing.B) { 66 | stream := &blackholeStream{} 67 | logger := zerolog.New(stream).With().Timestamp().Logger() 68 | b.ResetTimer() 69 | 70 | b.RunParallel(func(pb *testing.PB) { 71 | for pb.Next() { 72 | logger.Info(). 73 | Str("rate", "15"). 74 | Int("low", 16). 75 | Float32("high", 123.2). 76 | Msg("The quick brown fox jumps over the lazy dog") 77 | } 78 | }) 79 | 80 | if stream.WriteCount() != uint64(b.N) { 81 | b.Fatalf("Log write count") 82 | } 83 | } 84 | --------------------------------------------------------------------------------