Documentation
¶
Overview ¶
Package stats holds the shared, dependency-free numeric primitives every signal brain in the suite folds its baseline through: an exponentially-weighted mean/variance estimator, the z-score with a spread floor, an outlier-reject predicate, and the hour-of-day / hour-of-week seasonal bucketing. It lives in the OSS tree so the OSS log brain and the enterprise metric/trace brains share ONE implementation of the fold — the enterprise module imports this package one-way; this package imports nothing from the suite.
All math is local and deterministic (no LLM, no I/O), so a verdict computed from these functions is fully reconstructable from the stored numbers.
Index ¶
Constants ¶
const ( HoursPerDay = 24 HoursPerWeek = 7 * 24 )
HoursPerDay and HoursPerWeek are the two seasonal periods the suite uses: hour-of-day (a daily cycle — batch jobs, business hours) and hour-of-week (adds a weekly cycle — weekend-only jobs).
Variables ¶
This section is empty.
Functions ¶
func Expected ¶
func Expected(global EWMA, seasonal []EWMA, ts time.Time, period, minBucketSamples, minGlobalSamples int) (mean, std float64, confident bool)
Expected returns the mean/std to score against at ts and whether the model is confident enough to score at all. It uses the current seasonal bucket once that bucket has at least minBucketSamples observations, otherwise it falls back to the global level — so a sparse bucket never produces a spurious verdict. confident stays false until the global level has at least minGlobalSamples observations (the warmup gate). A period of zero (or a seasonal slice that is not exactly period long) skips the seasonal lookup and scores against the global level.
func SeasonalIndex ¶
SeasonalIndex maps ts to its seasonal bucket in [0, period). period 24 is hour-of-day; period 168 is hour-of-week (weekday*24 + hour). Any other positive period buckets the hour-of-week index modulo period; a period of zero or less returns 0 (no seasonality). Bucketing is done in UTC so the mapping is host-timezone- and DST-stable and therefore deterministic.
func ShouldReject ¶
ShouldReject reports whether value is a strong enough outlier to be held OUT of the fold so a single burst can't drag the baseline off the typical sample. It fires only once the estimator is confident (|z| >= rejectZ); during cold start it always returns false so the level can form. A rejectZ of zero or less disables rejection (every sample folds).
Types ¶
type EWMA ¶
type EWMA struct {
Mean float64 `json:"mean"`
Variance float64 `json:"variance"`
Count int `json:"count"`
}
EWMA is an exponentially-weighted running mean and variance in West's incremental form. It is O(1) in time and space: each fold updates the mean and the running variance from the new sample alone, weighting recent samples by alpha. Std is sqrt(Variance).
The JSON tags are the persisted wire shape shared with the enterprise typed baseline tables (the `seasonal` JSONB array and the global stat columns), so they must not change without a migration.