fix(traefik): a router fails on 5xx only once it answered a few server errors (#5865)
CI / lint (push) Successful in 2s
CI / unit (push) Successful in 1m28s
CI / integration (push) Successful in 1m34s
CI / publish (push) Successful in 1m10s

One 502 among about 70 requests read steward@swarm critical at 1.4%:
past the 30-request minimum and far past the 0.1% cutoff, yet one
error. A new Settings → Thresholds field, "Fewest server errors to
fail" (traefik.threshold.min_5xx, default 3), must also be reached in
the 15-minute window; the 0.1% cutoff still catches a busy router.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-15 15:49:51 -04:00
co-authored by Claude Opus 5.5
parent c625528191
commit a24b9da69d
6 changed files with 35 additions and 4 deletions
+6
View File
@@ -100,6 +100,9 @@ DEFAULTS: dict[str, Any] = {
# A router's 4xx share over fewer requests than this in 15 minutes isn't
# graded, on the page or for anomalies: one 404 of three is 33% (#5741).
"traefik.threshold.min_requests": 30,
# ...and a 5xx share past its cutoff is failing only once this many 5xx
# were answered in those 15 minutes: one 502 of 70 is 1.4% (#5865).
"traefik.threshold.min_5xx": 3,
# The smallest departure from a metric's normal worth calling an anomaly
# (#5742), on top of being a quarter over its usual hold: a share's floor
# is in percentage points, a response time's in ms. 5 points is the
@@ -553,6 +556,9 @@ def to_thresholds_cfg(settings: dict[str, Any]) -> dict:
# Fewer requests than this in 15 minutes and a router's 4xx share isn't graded.
"router_requests": {"warn": g("traefik.threshold.min_requests", 30),
"crit": g("traefik.threshold.min_requests", 30), "dir": "low"},
# Fewer 5xx than this in 15 minutes and a router isn't failing, whatever the share.
"router_5xx": {"warn": g("traefik.threshold.min_5xx", 3),
"crit": g("traefik.threshold.min_5xx", 3), "dir": "low"},
# Not a cutoff: each normal's floor (norms.floor.*), read by floor_of().
"floors": {name: float(g(f"norms.floor.{name}", DEFAULTS[f"norms.floor.{name}"]))
for name in NORM_FLOORS},