feat(traefik): a 4xx share is worth a look only once it is a lot of 4xx (#6105)
Three 404s on a quiet router read 7.5% and were raised as an anomaly; most of the 4xx anomalies on review stood for 3 to 7 errors in 15 minutes. A new Settings → Thresholds minimum, traefik.threshold.min_4xx (default 20, more than one a minute held for the window), applies to both the router's grade on its page and to anomaly detection, as min_5xx does for 5xx. learn_normal takes `fewest`: for a share gated on a per-second rate, the fewest events (rate × window × share) it must stand for to be judged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -38,11 +38,18 @@ MARKS = (NORMAL, REAL)
|
||||
|
||||
def _gate_open(learned, key: tuple[str, str, str], reported: dict) -> bool:
|
||||
"""Whether `key` may be judged: ungated, or its resource's gate metric
|
||||
averaged at least the gate's least over the window."""
|
||||
averaged at least the gate's least over the window, and the share stands
|
||||
for at least `fewest` events in it."""
|
||||
if learned.gate is None:
|
||||
return True
|
||||
metric, least = learned.gate
|
||||
return reported.get((key[0], key[1], metric), 0.0) >= (least() if callable(least) else least)
|
||||
rate = reported.get((key[0], key[1], metric), 0.0)
|
||||
if rate < (least() if callable(least) else least):
|
||||
return False
|
||||
if learned.fewest is None:
|
||||
return True
|
||||
fewest = learned.fewest() if callable(learned.fewest) else learned.fewest
|
||||
return rate * WINDOW.total_seconds() * reported.get(key, 0.0) / 100.0 >= fewest
|
||||
|
||||
|
||||
def departs(level: float, norm: Norm, floor: float) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user