1
0
mirror of https://github.com/taigrr/log-socket synced 2026-03-20 16:02:28 -07:00

2 Commits

Author SHA1 Message Date
4d74b0a950 test: add comprehensive benchmark suite
Adds benchmarks for all log levels (Trace, Debug, Info, Warn, Error),
formatted logging, multiple client fan-out, parallel writes, namespace
filtering, and component-level benchmarks (fileInfo, entry creation).

Uses isolated namespaces to avoid interference with the stderr client.

Fixes #6
2026-02-17 08:04:08 +00:00
93dd230be0 update test version 2025-11-10 16:08:40 -05:00
2 changed files with 172 additions and 1 deletions

View File

@@ -11,7 +11,7 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v4 uses: actions/setup-go@v4
with: with:
go-version: "1.21" go-version: "1.25"
- name: Install dependencies - name: Install dependencies
run: go get . run: go get .

171
log/bench_test.go Normal file
View File

@@ -0,0 +1,171 @@
package log
import (
"fmt"
"testing"
)
const benchNS = "bench-isolated-ns"
// benchClient creates a client with a continuous drain goroutine.
// Returns the client and a stop function to call after b.StopTimer().
func benchClient(ns string) (*Client, func()) {
c := CreateClient(ns)
c.SetLogLevel(LTrace)
done := make(chan struct{})
go func() {
for {
select {
case <-done:
return
case <-c.writer:
}
}
}()
return c, func() {
close(done)
c.Destroy()
}
}
// BenchmarkCreateClient measures client creation overhead.
func BenchmarkCreateClient(b *testing.B) {
for i := 0; i < b.N; i++ {
c := CreateClient("bench")
c.Destroy()
}
}
// BenchmarkTrace benchmarks Logger.Trace.
func BenchmarkTrace(b *testing.B) {
l := NewLogger(benchNS)
_, stop := benchClient(benchNS)
defer stop()
b.ResetTimer()
for i := 0; i < b.N; i++ {
l.Trace("benchmark trace message")
}
}
// BenchmarkTracef benchmarks formatted Logger.Tracef.
func BenchmarkTracef(b *testing.B) {
l := NewLogger(benchNS)
_, stop := benchClient(benchNS)
defer stop()
b.ResetTimer()
for i := 0; i < b.N; i++ {
l.Tracef("benchmark trace message %d", i)
}
}
// BenchmarkDebug benchmarks Logger.Debug.
func BenchmarkDebug(b *testing.B) {
l := NewLogger(benchNS)
_, stop := benchClient(benchNS)
defer stop()
b.ResetTimer()
for i := 0; i < b.N; i++ {
l.Debug("benchmark debug message")
}
}
// BenchmarkInfo benchmarks Logger.Info.
func BenchmarkInfo(b *testing.B) {
l := NewLogger(benchNS)
_, stop := benchClient(benchNS)
defer stop()
b.ResetTimer()
for i := 0; i < b.N; i++ {
l.Info("benchmark info message")
}
}
// BenchmarkInfof benchmarks Logger.Infof with formatting.
func BenchmarkInfof(b *testing.B) {
l := NewLogger(benchNS)
_, stop := benchClient(benchNS)
defer stop()
b.ResetTimer()
for i := 0; i < b.N; i++ {
l.Infof("user %s performed action %d", "testuser", i)
}
}
// BenchmarkWarn benchmarks Logger.Warn.
func BenchmarkWarn(b *testing.B) {
l := NewLogger(benchNS)
_, stop := benchClient(benchNS)
defer stop()
b.ResetTimer()
for i := 0; i < b.N; i++ {
l.Warn("benchmark warn message")
}
}
// BenchmarkError benchmarks Logger.Error.
func BenchmarkError(b *testing.B) {
l := NewLogger(benchNS)
_, stop := benchClient(benchNS)
defer stop()
b.ResetTimer()
for i := 0; i < b.N; i++ {
l.Error("benchmark error message")
}
}
// BenchmarkMultipleClients measures fan-out to multiple consumers.
func BenchmarkMultipleClients(b *testing.B) {
const numClients = 5
l := NewLogger(benchNS)
stops := make([]func(), numClients)
for i := range stops {
_, stops[i] = benchClient(benchNS)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
l.Info("benchmark multi-client")
}
b.StopTimer()
for _, stop := range stops {
stop()
}
}
// BenchmarkParallelInfo benchmarks concurrent Info calls from multiple goroutines.
func BenchmarkParallelInfo(b *testing.B) {
l := NewLogger(benchNS)
_, stop := benchClient(benchNS)
defer stop()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
l.Info("parallel benchmark info")
}
})
}
// BenchmarkNamespaceFiltering benchmarks logging when the consumer
// filters by a different namespace (messages are not delivered).
func BenchmarkNamespaceFiltering(b *testing.B) {
l := NewLogger(benchNS)
_, stop := benchClient("completely-different-ns")
defer stop()
b.ResetTimer()
for i := 0; i < b.N; i++ {
l.Info("filtered out message")
}
}
// BenchmarkFileInfo measures the cost of runtime.Caller for file info.
func BenchmarkFileInfo(b *testing.B) {
for i := 0; i < b.N; i++ {
fileInfo(1)
}
}
// BenchmarkEntryCreation measures raw fmt.Sprint overhead (baseline).
func BenchmarkEntryCreation(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = fmt.Sprint("benchmark message ", i)
}
}