diff --git a/fablednetmon/dashboard/routes.py b/fablednetmon/dashboard/routes.py index 7085aef..95b5472 100644 --- a/fablednetmon/dashboard/routes.py +++ b/fablednetmon/dashboard/routes.py @@ -1,6 +1,10 @@ -from quart import Blueprint, render_template +from __future__ import annotations +from quart import Blueprint, render_template, current_app +from sqlalchemy import select, func from fablednetmon.auth.middleware import require_role from fablednetmon.models.users import UserRole +from fablednetmon.models.hosts import Host +from fablednetmon.models.monitors import PingResult, DnsResult dashboard_bp = Blueprint("dashboard", __name__) @@ -8,4 +12,51 @@ dashboard_bp = Blueprint("dashboard", __name__) @dashboard_bp.get("/") @require_role(UserRole.viewer) async def index(): - return await render_template("dashboard/index.html") + async with current_app.db_sessionmaker() as db: + # Latest ping per host + latest_ping_subq = ( + select(PingResult.host_id, func.max(PingResult.probed_at).label("max_at")) + .group_by(PingResult.host_id) + .subquery() + ) + pr = await db.execute( + select(PingResult).join( + latest_ping_subq, + (PingResult.host_id == latest_ping_subq.c.host_id) + & (PingResult.probed_at == latest_ping_subq.c.max_at), + ) + ) + latest_pings = list(pr.scalars()) + ping_up = sum(1 for p in latest_pings if p.status.value == "up") + ping_down = sum(1 for p in latest_pings if p.status.value == "down") + + # Latest DNS per host + latest_dns_subq = ( + select(DnsResult.host_id, func.max(DnsResult.resolved_at).label("max_at")) + .group_by(DnsResult.host_id) + .subquery() + ) + dr = await db.execute( + select(DnsResult).join( + latest_dns_subq, + (DnsResult.host_id == latest_dns_subq.c.host_id) + & (DnsResult.resolved_at == latest_dns_subq.c.max_at), + ) + ) + latest_dns = list(dr.scalars()) + dns_ok = sum(1 for d in latest_dns if d.status.value == "resolved") + dns_fail = sum(1 for d in latest_dns if d.status.value != "resolved") + + total_hosts = (await db.execute(select(func.count()).select_from(Host))).scalar() + + poll_interval = current_app.config.get("MONITORS_POLL_INTERVAL", 60) + + return await render_template( + "dashboard/index.html", + ping_up=ping_up, + ping_down=ping_down, + dns_ok=dns_ok, + dns_fail=dns_fail, + total_hosts=total_hosts, + poll_interval=poll_interval, + ) diff --git a/fablednetmon/hosts/routes.py b/fablednetmon/hosts/routes.py index 9c816fe..3eccfbb 100644 --- a/fablednetmon/hosts/routes.py +++ b/fablednetmon/hosts/routes.py @@ -1,8 +1,9 @@ from __future__ import annotations from quart import Blueprint, render_template, request, redirect, url_for, current_app -from sqlalchemy import select +from sqlalchemy import select, func from fablednetmon.auth.middleware import require_role from fablednetmon.models.hosts import Host, ProbeType +from fablednetmon.models.monitors import PingResult, DnsResult from fablednetmon.models.users import UserRole hosts_bp = Blueprint("hosts", __name__, url_prefix="/hosts") @@ -14,7 +15,43 @@ async def list_hosts(): async with current_app.db_sessionmaker() as db: result = await db.execute(select(Host).order_by(Host.name)) hosts = result.scalars().all() - return await render_template("hosts/list.html", hosts=hosts) + + # Latest ping result per host + latest_ping_subq = ( + select(PingResult.host_id, func.max(PingResult.probed_at).label("max_at")) + .group_by(PingResult.host_id) + .subquery() + ) + pr = await db.execute( + select(PingResult).join( + latest_ping_subq, + (PingResult.host_id == latest_ping_subq.c.host_id) + & (PingResult.probed_at == latest_ping_subq.c.max_at), + ) + ) + latest_pings = {r.host_id: r for r in pr.scalars()} + + # Latest DNS result per host + latest_dns_subq = ( + select(DnsResult.host_id, func.max(DnsResult.resolved_at).label("max_at")) + .group_by(DnsResult.host_id) + .subquery() + ) + dr = await db.execute( + select(DnsResult).join( + latest_dns_subq, + (DnsResult.host_id == latest_dns_subq.c.host_id) + & (DnsResult.resolved_at == latest_dns_subq.c.max_at), + ) + ) + latest_dns = {r.host_id: r for r in dr.scalars()} + + return await render_template( + "hosts/list.html", + hosts=hosts, + latest_pings=latest_pings, + latest_dns=latest_dns, + ) @hosts_bp.get("/new") diff --git a/fablednetmon/templates/dashboard/index.html b/fablednetmon/templates/dashboard/index.html index 255b8f8..3987105 100644 --- a/fablednetmon/templates/dashboard/index.html +++ b/fablednetmon/templates/dashboard/index.html @@ -2,31 +2,60 @@ {% block title %}Dashboard — FabledNetMon{% endblock %} {% block content %}
- Manage hosts to begin monitoring. -
+Add hosts to begin monitoring.
+ {% else %} +every {{ poll_interval }}s — view all
+ {% endif %}- Enable DNS monitoring on a host. -
+Enable DNS monitoring on a host.
+ {% else %} +- Browse playbooks or view - run history. -
+Configure alert rules against any metric.