fix
This commit is contained in:
1 parent
645f923175
commit
2cf2cebf5c
20 files changed
+481
-51
No files matched your search
@@ -128,3 +128,38 @@ func TestTelegramTruncates(t *testing.T) {
|
||||
t.Fatalf("message too long: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func TestScannerClientIsMutedEntirely(t *testing.T) {
|
||||
at := time.Date(2026, 9, 20, 12, 0, 0, 0, time.UTC)
|
||||
cur := at.Add(-2 * time.Minute)
|
||||
scanner := func(route string, n int) []features.Event {
|
||||
ev := burst("p-"+route, n, cur, 503, route)
|
||||
for i := range ev {
|
||||
ev[i].ClientIP = "198.51.100.9"
|
||||
}
|
||||
return ev
|
||||
}
|
||||
var events []features.Event
|
||||
for _, r := range []string{"/.env", "/.cursorrules", "/.codex/auth.json"} {
|
||||
events = append(events, scanner(r, 4)...)
|
||||
}
|
||||
events = append(events, scanner("/", 12)...) // the scanner's innocent-looking root request
|
||||
if got := DetectAlerts(events, at, features.SpikeConfig{Window: 5 * time.Minute, BaselineWindows: 12, MinExcess: 5}); len(got) != 0 {
|
||||
t.Fatalf("scanner traffic alerted: %+v", got)
|
||||
}
|
||||
// a different client with the same 503 on "/" still alerts
|
||||
other := burst("real-503", 12, cur, 503, "/")
|
||||
if got := DetectAlerts(other, at, features.SpikeConfig{Window: 5 * time.Minute, BaselineWindows: 12, MinExcess: 5}); len(got) != 1 {
|
||||
t.Fatalf("real failure was muted: %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMinExcessAppliesAfterTriage(t *testing.T) {
|
||||
at := time.Date(2026, 9, 20, 12, 0, 0, 0, time.UTC)
|
||||
cur := at.Add(-2 * time.Minute)
|
||||
// 200 probe errors + 6 real ones: total excess is large, actionable excess is 6 < 10
|
||||
events := append(burst("probe", 200, cur, 404, "/.env"), burst("real", 6, cur, 503, "/api")...)
|
||||
if got := DetectAlerts(events, at, features.SpikeConfig{Window: 5 * time.Minute, BaselineWindows: 12, MinExcess: 10}); len(got) != 0 {
|
||||
t.Fatalf("paged on excess that was mostly probes: %+v", got)
|
||||
}
|
||||
}
|
||||
@@ -198,7 +198,21 @@ func (r *Runner) Tick(ctx context.Context, now time.Time) {
|
||||
// DetectAlerts is the detection half of a tick: spikes reduced to actionable
|
||||
// patterns. Exported so the CLI and the runner cannot drift apart.
|
||||
func DetectAlerts(events []features.Event, at time.Time, cfg features.SpikeConfig) []features.Spike {
|
||||
return FilterActionable(features.DetectSpikes(events, at, cfg), false, nil)
|
||||
// Scanners, route enumerators and crawlers getting 4xx are noise for paging.
|
||||
features.MarkBadActors(events, features.BadActorConfig{})
|
||||
minExcess := cfg.MinExcess
|
||||
if minExcess <= 0 {
|
||||
minExcess = features.DefaultSpikeConfig().MinExcess
|
||||
}
|
||||
var out []features.Spike
|
||||
// The excess threshold is applied after triage: a service whose total
|
||||
// excess is mostly probes must not page on the little that is left.
|
||||
for _, sp := range FilterActionable(features.DetectSpikes(events, at, cfg), false, nil) {
|
||||
if sp.Excess >= float64(minExcess) {
|
||||
out = append(out, sp)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (r *Runner) deliver(ctx context.Context, a Alert) {
|
||||
|
||||
Reference in new issue
Block a user