feat(dashboard): Monitors widget carries uptime; Uptime / SLA retired (#5250)
The Monitors widget opens with a verdict ("1 of 5 monitors down."), then one
row per monitor under a single header: latency and uptime over 24h, 7d and
30d, down monitors first with why and since when, the name linking to the
monitor. Counts follow the type filter. Problems always show; the limit
trims only the healthy rest ("+N more up").
Uptime / SLA (uptime_summary) repeated those numbers per host; migration
0033 moves dashboards onto Monitors. Shared widget styles (.w-verdict,
.w-table, .w-sub, .w-more) carry the widget-shape ruling for the widgets
that follow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -35,11 +35,9 @@ def test_the_recommended_layout_fills_rows_without_overlap():
|
||||
|
||||
|
||||
def test_the_recommended_layout_skips_what_is_not_enabled():
|
||||
keys = [i["key"] for i in recommended_layout({})]
|
||||
assert keys == ["status_overview", "hosts_overview", "monitors", "uptime_summary"]
|
||||
# uptime no longer fits beside the monitors, so it starts the next row
|
||||
items = recommended_layout({})
|
||||
assert (items[3]["x"], items[3]["y"]) == (0, 10)
|
||||
assert [i["key"] for i in items] == ["status_overview", "hosts_overview", "monitors"]
|
||||
assert [(i["x"], i["y"]) for i in items] == [(0, 0), (0, 3), (6, 3)]
|
||||
|
||||
|
||||
def test_overview_alerts_put_the_breaching_first():
|
||||
@@ -96,9 +94,9 @@ async def test_the_hosts_widget_shows_load(app):
|
||||
|
||||
|
||||
async def test_a_widget_polls_at_its_own_pace(app):
|
||||
defn = {**WIDGET_REGISTRY["uptime_summary"]}
|
||||
defn = {"poll": True, "poll_seconds": 300, "detail_url": "/x"}
|
||||
item = SimpleNamespace(db=SimpleNamespace(id=7, grid_x=0, grid_y=0, grid_w=6, grid_h=5),
|
||||
title="Uptime", defn=defn, hx_url="/uptime/widget")
|
||||
title="Slow", defn=defn, hx_url="/slow/widget")
|
||||
async with app.test_request_context("/"):
|
||||
page = await render_template("dashboard/_grid_item.html", item=item, can_edit=False, poll_interval=30)
|
||||
assert "every 300s" in page
|
||||
|
||||
@@ -137,3 +137,36 @@ async def test_a_down_monitor_says_since_when_and_why_in_the_list(app):
|
||||
range_key="24h")
|
||||
page = " ".join(page.split())
|
||||
assert re.search(r'Down <time [^>]*>12m</time> · connection refused', page), page
|
||||
|
||||
|
||||
async def _widget(app, problems, rest, more=0, counts=None):
|
||||
counts = counts or {"up": len(rest), "degraded": 0, "down": len(problems), "pending": 0, "paused": 0}
|
||||
async with app.test_request_context("/monitors/widget"):
|
||||
session["user_id"] = "u1"
|
||||
return await render_template("monitors/widget.html", problems=problems, rest=rest, more=more,
|
||||
counts=counts, total=len(problems) + len(rest) + more,
|
||||
show_down_only=False, widget_id="1")
|
||||
|
||||
|
||||
async def test_the_widget_gives_a_verdict_then_problems_with_uptime_columns(app):
|
||||
"""#5250: one home for uptime. A verdict, the down monitor first with why
|
||||
and since when, then each monitor's latency and 24h/7d/30d under one header."""
|
||||
down = {**_row(_mon("api", mid="m2"), "down", _check(False)),
|
||||
"uptime": {"24h": 90.0, "7d": 97.5, "30d": 99.12},
|
||||
"down_since": NOW - timedelta(minutes=12), "down_reason": "HTTP 503"}
|
||||
up = {**_row(_mon("web", mid="m1"), "up", _check(ms=31)), "uptime": {"24h": 100.0, "7d": 99.96}}
|
||||
page = await _widget(app, [down], [up], more=3)
|
||||
assert "1 of 5 monitors down." in page
|
||||
assert page.index(">api<") < page.index(">web<")
|
||||
assert 'href="/monitors/m2"' in page and "went down" in page and "12m ago" in page and "HTTP 503" in page
|
||||
assert page.count("<th>") == 5 and "<th>30d</th>" in page
|
||||
assert "99.96%" in page and "31 ms" in page
|
||||
assert ">—<" in page # web has no 30d yet: a dash, not 0
|
||||
assert "+3 more up" in page
|
||||
assert not hex_colours(page), hex_colours(page)
|
||||
|
||||
|
||||
async def test_the_widget_says_when_all_is_well(app):
|
||||
up = {**_row(_mon("web", mid="m1"), "up", _check()), "uptime": {"24h": 100.0}}
|
||||
page = await _widget(app, [], [up])
|
||||
assert "All 1 monitor up." in page and "tone-ok" in page
|
||||
|
||||
Reference in New Issue
Block a user