fix(traefik): a router's 5xx share is judged only over enough requests, like its 4xx share (#5859)
CI / lint (push) Successful in 1s
CI / unit (push) Successful in 1m27s
CI / integration (push) Successful in 1m33s
CI / publish (push) Successful in 1m15s

Two 500s of about sixteen requests graded roundtable@swarm critical at
9.1%. The Settings → Thresholds minimum of requests in 15 minutes (30 by
default) now guards both shares; the 5xx share still keeps its fixed
cutoff whatever the router's history.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-15 15:35:57 -04:00
co-authored by Claude Opus 5.5
parent bf017e65c2
commit 80674603bc
6 changed files with 25 additions and 18 deletions
+8 -5
View File
@@ -1,8 +1,8 @@
"""A router's 4xx share and p95 are graded against its own normal once it has
one (#5741, System 182): a router over the fixed cutoff but inside its normal
is healthy and says so; one out of its normal is a warning that says what is
usual. The 5xx share keeps its fixed cutoff, and a 4xx share over too few
requests isn't graded."""
usual. The 5xx share keeps its fixed cutoff, and neither share over too few
requests is graded."""
from types import SimpleNamespace as NS
from plugins.traefik.routes import STATE_WINDOW_WORDS, grade_routers, router_state
@@ -60,15 +60,18 @@ def test_without_a_normal_the_fixed_cutoffs_still_apply():
assert router_state(_window(p95=450.0), TH, "")[0] == "warn"
def test_5xx_keeps_its_cutoff_whatever_the_history_or_traffic():
def test_5xx_keeps_its_cutoff_whatever_the_history():
usual_5xx = {"error_rate_4xx_pct": _norm(50.0)}
assert router_state(_window(e5=40.0), TH, "", usual_5xx)[0] == "crit"
assert router_state(_window(e5=40.0, requests=4.0), TH, "")[0] == "crit"
assert router_state(_window(e5=40.0, requests=300.0), TH, "", usual_5xx)[0] == "crit"
def test_a_4xx_share_over_a_handful_of_requests_is_not_graded():
def test_a_share_over_a_handful_of_requests_is_not_graded():
assert router_state(_window(e4=33.0, requests=3.0), TH, "") == ("ok", None)
assert router_state(_window(e4=33.0, requests=300.0), TH, "")[0] == "warn"
# roundtable@swarm on 2026-10-15: two 500s of about sixteen requests (#5859)
assert router_state(_window(e5=12.5, requests=16.0), TH, "") == ("ok", None)
assert router_state(_window(e5=12.5, requests=30.0), TH, "")[0] == "crit"
def test_grade_routers_hands_each_router_its_own_normals():