starlog/sample_dedup_test.go
2026-03-19 16:37:57 +08:00

110 lines
2.8 KiB
Go

package starlog
import (
"bytes"
"sync/atomic"
"testing"
"time"
)
func TestSamplingRateDeterministic(t *testing.T) {
var buf bytes.Buffer
logger := newStructuredTestLogger(&buf)
logger.SetSamplingConfig(SamplingConfig{
Enable: true,
Levels: []int{LvInfo},
Rate: 0.5,
Scope: SamplingScopeGlobal,
})
for idx := 0; idx < 5; idx++ {
logger.Infoln("sample")
}
stats := logger.GetSamplingStats()
if stats.Allowed != 3 || stats.Dropped != 2 {
t.Fatalf("unexpected sampling stats: %+v", stats)
}
if got := bytes.Count(buf.Bytes(), []byte("sample")); got != 3 {
t.Fatalf("expected 3 sampled logs in output, got %d", got)
}
}
func TestSamplingDropCallback(t *testing.T) {
logger := newStructuredTestLogger(&bytes.Buffer{})
var callbackCount uint64
logger.SetSamplingConfig(SamplingConfig{
Enable: true,
Levels: []int{LvInfo},
Rate: 0,
Scope: SamplingScopeGlobal,
OnDrop: func(data SamplingDropData) {
if data.Reason == "" {
t.Errorf("drop callback reason should not be empty")
}
atomic.AddUint64(&callbackCount, 1)
},
})
logger.Infoln("drop-all")
logger.Infoln("drop-all")
if atomic.LoadUint64(&callbackCount) != 2 {
t.Fatalf("sampling drop callback should be called twice, got %d", callbackCount)
}
}
func TestDedupWindow(t *testing.T) {
var buf bytes.Buffer
logger := newStructuredTestLogger(&buf)
logger.SetDedupConfig(DedupConfig{
Enable: true,
Levels: []int{LvInfo},
Window: time.Hour,
Scope: DedupScopeByKey,
})
logger.Infoln("dup")
logger.Infoln("dup")
logger.Infoln("dup")
logger.Infoln("other")
stats := logger.GetDedupStats()
if stats.Allowed != 2 || stats.Dropped != 2 {
t.Fatalf("unexpected dedup stats: %+v", stats)
}
if got := bytes.Count(buf.Bytes(), []byte("dup")); got != 1 {
t.Fatalf("expected one deduped dup log in output, got %d", got)
}
if got := bytes.Count(buf.Bytes(), []byte("other")); got != 1 {
t.Fatalf("expected one other log in output, got %d", got)
}
}
func TestSamplingDedupConfigSnapshotApply(t *testing.T) {
logger := newStructuredTestLogger(&bytes.Buffer{})
cfg := logger.GetConfig()
cfg.Sampling = SamplingConfig{
Enable: true,
Levels: []int{LvInfo},
Rate: 0.25,
Scope: SamplingScopeByKey,
}
cfg.Dedup = DedupConfig{
Enable: true,
Levels: []int{LvWarning},
Window: 3 * time.Second,
Scope: DedupScopeByKey,
}
logger.ApplyConfig(cfg)
samplingCfg := logger.GetSamplingConfig()
if !samplingCfg.Enable || samplingCfg.Rate != 0.25 || samplingCfg.Scope != SamplingScopeByKey {
t.Fatalf("unexpected sampling config after ApplyConfig: %+v", samplingCfg)
}
dedupCfg := logger.GetDedupConfig()
if !dedupCfg.Enable || dedupCfg.Window != 3*time.Second || dedupCfg.Scope != DedupScopeByKey {
t.Fatalf("unexpected dedup config after ApplyConfig: %+v", dedupCfg)
}
}