package bench_test
import (
"io"
"testing"
"time"
"mercemay.top/src/lambdalog/internal/encoder"
logjson "mercemay.top/src/lambdalog/internal/encoder/json"
"mercemay.top/src/lambdalog/internal/sampler"
"mercemay.top/src/lambdalog/internal/sampler/adaptive"
"mercemay.top/src/lambdalog/internal/sampler/threshold"
)
// pipeline simulates the minimum path a log call goes through: threshold,
// adaptive sampler, JSON encoder, io.Discard. It does not exercise the
// Logger type itself, which is in the root package.
func pipeline(enc logjson.Encoder, thr *threshold.Sampler, adp *adaptive.Sampler, rec encoder.Record, now time.Time) {
in := sampler.Input{Level: rec.Level, Now: now}
if thr.Sample(in) == sampler.Drop {
return
}
if adp.Sample(in) == sampler.Drop {
return
}
_ = enc.Encode(io.Discard, rec)
}
func BenchmarkEndToEnd_HappyPath(b *testing.B) {
enc := logjson.Encoder{}
thr := threshold.New("info")
adp := adaptive.New(1000)
adp.SeedFixed(1)
rec := makeRecord(5)
now := time.Unix(0, 0)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
pipeline(enc, thr, adp, rec, now.Add(time.Duration(i)*time.Microsecond))
}
}
func BenchmarkEndToEnd_ThresholdDrops(b *testing.B) {
enc := logjson.Encoder{}
thr := threshold.New("error") // message is info, so always dropped
adp := adaptive.New(1000)
rec := makeRecord(5)
now := time.Unix(0, 0)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
pipeline(enc, thr, adp, rec, now)
}
}
func BenchmarkEndToEnd_HighVolumeThrottled(b *testing.B) {
enc := logjson.Encoder{}
thr := threshold.New("info")
adp := adaptive.New(10) // aggressive
adp.SeedFixed(2)
rec := makeRecord(5)
now := time.Unix(0, 0)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
pipeline(enc, thr, adp, rec, now.Add(time.Duration(i)*time.Nanosecond))
}
}
func BenchmarkEndToEnd_Parallel(b *testing.B) {
enc := logjson.Encoder{}
thr := threshold.New("info")
adp := adaptive.New(5000)
adp.SeedFixed(3)
rec := makeRecord(5)
b.ReportAllocs()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
now := time.Unix(0, 0)
for pb.Next() {
pipeline(enc, thr, adp, rec, now)
}
})
}