Decides whether a bucket of a metric time series is abnormal, and can explain why in one sentence. Immutable and stateless once built, so one instance can be reused across tenants and series. The baseline is not a fitted model: comparable earlier buckets are selected by a BaselinePhase - for daily buckets, the same weekday; for hourly buckets, the same hour of the same weekday - and the observation is compared against the median of those, with the spread measured as a median absolute deviation. Both statistics are robust, which matters because the history being compared against already contains the previous outliers; a mean and standard deviation would be inflated by them and would hide the next one. The score is the Iglewicz-Hoaglin modified z-score. Alarming on it alone is not viable, so an AnomalyThreshold adds a proportional gate and an absolute-change floor and requires all three to agree. Two rules matter more than the statistics: only closed buckets are evaluated, because a bucket still accepting data is always short of its eventual total and would report a collapse on every scan; and a thin baseline yields an INSUFFICIENT_BASELINE verdict rather than a guess, because a detector that fires during its own cold start teaches its audience to ignore it.


Properties

PropertyReturnsDescription
baselineSamplesintHow many comparable buckets this detector wants to draw a baseline from.
intervalBucketIntervalThe bucket size this detector works in.
minBaselineSamplesintThe fewest comparable buckets a baseline can be judged from before the detector will give a verdict at all.
phaseBaselinePhaseHow earlier buckets are selected as comparable for the baseline.
thresholdAnomalyThresholdThe gates a bucket must fail every one of to be called anomalous.

Methods

getInterval() · getPhase() · getThreshold() · getBaselineSamples() · getMinBaselineSamples() · evaluateLastClosedBucket(List<AnomalyDataPoint> series, Date now) · evaluate(List<AnomalyDataPoint> series, Date bucketDate) · evaluateSeries(List<AnomalyDataPoint> series, Date now) · findBaselineForLastClosedBucket(List<AnomalyDataPoint> series, Date now)

getInterval()

Returns: BucketInterval

The bucket size this detector works in.

getPhase()

Returns: BaselinePhase

How earlier buckets are selected as comparable for the baseline.

getThreshold()

Returns: AnomalyThreshold

The gates a bucket must fail every one of to be called anomalous.

getBaselineSamples()

Returns: int

How many comparable buckets this detector wants to draw a baseline from.

getMinBaselineSamples()

Returns: int

The fewest comparable buckets a baseline can be judged from before the detector will give a verdict at all.

evaluateLastClosedBucket(List<AnomalyDataPoint> series, Date now)

Returns: AnomalyResult

Evaluate the most recent bucket that has finished - the normal entry point for a scan. Returns a result in every case, including when there is nothing to evaluate, so a caller never has to null-check. Read the result's status to tell the cases apart.

ParameterDescription
seriesthe metric time series, in any order, possibly including a bucket that is still filling. Must not be null
nowthe instant to judge closure against, normally the current time. Must not be null

evaluate(List<AnomalyDataPoint> series, Date bucketDate)

Returns: AnomalyResult

Evaluate one named bucket. Mainly for replaying history and for tests, where the bucket of interest is known and closure has already been established.

ParameterDescription
seriesthe metric time series, in any order. Must not be null
bucketDatethe first instant of the bucket to evaluate. Must be present in the series

evaluateSeries(List<AnomalyDataPoint> series, Date now)

Returns: List<AnomalyResult>

Evaluate every closed bucket in the series, oldest first. This is how a detector is judged before it is trusted: run it over real recorded history and count what it would have said. It is also how a new detector's screen is populated with something to look at on day one.

ParameterDescription
seriesthe metric time series, in any order. Must not be null
nowthe instant to judge closure against. Must not be null

findBaselineForLastClosedBucket(List<AnomalyDataPoint> series, Date now)

Returns: List<AnomalyDataPoint>

The buckets the newest closed bucket is being compared against - the sample behind the result's expected value. Exists so a verdict can be shown with its working. "Expected 40, observed 12" is not reviewable on its own; the four Thursdays that produced the 40 are, and seeing them is what tells someone whether a detector is badly tuned or the metric really did move.

ParameterDescription
seriesthe metric time series, in any order, possibly including a bucket that is still filling. Must not be null
nowthe instant to judge closure against, normally the current time. Must not be null
To get full access to the Kademi Hub existing customers can login here, or new customers can register here.