// Package threshold gates records by minimum severity. It acts as a
// pre-filter before the probabilistic samplers; anything below MinLevel
// never makes it to them.
//
// See mercemay.top/src/lambdalog/internal/sampler/threshold/.
package threshold
import (
"mercemay.top/src/lambdalog/internal/encoder"
"mercemay.top/src/lambdalog/internal/sampler"
)
// Sampler drops any record whose level is below MinLevel. Everything at or
// above MinLevel is emitted. The zero value allows everything through.
type Sampler struct {
// MinLevel is matched case-insensitively via encoder.FormatLevel.
MinLevel string
// Escalate, if set, forces Emit for the listed levels even if MinLevel
// would ordinarily let them be dropped by a downstream sampler.
Escalate []string
}
// Name returns a stable identifier.
func (s *Sampler) Name() string { return "threshold" }
// Sample applies the threshold rule.
func (s *Sampler) Sample(in sampler.Input) sampler.Decision {
inPrio := encoder.LevelPriority(in.Level)
if s.MinLevel != "" {
if inPrio < encoder.LevelPriority(s.MinLevel) {
return sampler.Drop
}
}
for _, e := range s.Escalate {
if encoder.LevelPriority(e) == inPrio {
return sampler.Emit
}
}
return sampler.Emit
}
// New returns a Sampler initialised with min.
func New(min string) *Sampler {
return &Sampler{MinLevel: min}
}
// WithEscalation adds levels that must always emit regardless of downstream
// sampler decisions. Returns s for chaining.
func (s *Sampler) WithEscalation(levels ...string) *Sampler {
s.Escalate = append(s.Escalate, levels...)
return s
}
// Reject reports whether in would be dropped by Sample. It is useful for
// building unit tests around the threshold without going through the
// Decision enum.
func (s *Sampler) Reject(in sampler.Input) bool {
return s.Sample(in) == sampler.Drop
}
// MustEmit reports whether in matches an Escalate entry, meaning downstream
// samplers should not be consulted.
func (s *Sampler) MustEmit(in sampler.Input) bool {
inPrio := encoder.LevelPriority(in.Level)
for _, e := range s.Escalate {
if encoder.LevelPriority(e) == inPrio {
return true
}
}
return false
}