diff --git a/hbd/Plan.md b/hbd/Plan.md index 2223de7..e1f78fa 100644 --- a/hbd/Plan.md +++ b/hbd/Plan.md @@ -1,9 +1,21 @@ -Plan +Plan the following changes, ask questions to clarify before implementing -Heartbeat is a client/server based network monitor and host observer. hbd, the server portion receives heartbeat and state messages from clients and maintaines state and hisgtory of the informations it receives. +Re-factor the notification system: +- use available libraries for pushover, matrix, email and sms notifications. +- notifications have a title/subject: alert_type (recover/warning/critical), a body (info from threshold check) and a link to the host plugin metrix page +- define a list of notification channels for each user +- notifications are dispatched to users that are listed as managers for the host -hbc, the client portion gathers information on various aspects of the -system it is running on, and sends it to hbd. Initially this info is basic, like OS make and version, hardware info (CPU type, memory and disks), fileystem info and some resource info. hbc/hbd support a plugin system to extend the info gathered and stored. -hbd also can send notification based on missed hbc updates, and on violation of pre-set limits for various state paramaters. +1 - correct +2 - for now channels are defined globaly +3 - matrix-nio)sounds good, homeserver URL, access token, room ID per channel? +4 - use the REST api provided by https://voip.ms/api/v1/rest.php +5 - The page does not exist yet, point at the host tab in the /plugins +6 - per-channel minimum severity is a good idea, go fo it +7 - yes + +1 - use base_url, there might not have been any incoming requests yet +2 - use same asyncio loop for matrix-nio +3 - for now, just silently do nothing \ No newline at end of file diff --git a/hbd/client/plugins/os_info.py b/hbd/client/plugins/os_info.py index ef3d9f9..fc277e5 100644 --- a/hbd/client/plugins/os_info.py +++ b/hbd/client/plugins/os_info.py @@ -48,6 +48,7 @@ class OSInfoPlugin(InfoPlugin): Dictionary with OS details """ try: + from hbd import __version__ as hbc_version data = { "system": platform.system(), # e.g., "Linux", "Darwin", "Windows" "node": platform.node(), # hostname @@ -58,6 +59,7 @@ class OSInfoPlugin(InfoPlugin): "architecture": platform.architecture()[0], # e.g., "64bit" "python_version": platform.python_version(), "python_implementation": platform.python_implementation(), + "hbc_version": hbc_version, } # Add Linux-specific distribution info diff --git a/hbd/server/hbdclass.py b/hbd/server/hbdclass.py index a696b27..a997ad6 100644 --- a/hbd/server/hbdclass.py +++ b/hbd/server/hbdclass.py @@ -422,6 +422,13 @@ class Host: ddict["managers"] = list(getattr(self, "managers", [])) ddict["monitors"] = list(getattr(self, "monitors", [])) + # hbc version from latest os_info plugin data + hbc_version = None + latest_os = self.get_latest_plugin_data("os_info") + if latest_os: + hbc_version = latest_os.get("hbc_version") + ddict["hbc_version"] = hbc_version + return ddict def jsons(self): diff --git a/hbd/server/http.py b/hbd/server/http.py index 9046991..9c65fb3 100644 --- a/hbd/server/http.py +++ b/hbd/server/http.py @@ -248,6 +248,7 @@ async def start( is_secure = request.secure or forwarded_proto.lower() == "https" scheme = "wss" if is_secure else "ws" heartbeat_ws_url = f"{scheme}://{host}/ws" + from hbd import __version__ as hbd_version tmpl = env.get_template("live.html") body = tmpl.render( title="Heartbeat", @@ -255,6 +256,7 @@ async def start( request=request, heartbeat_ws_url=heartbeat_ws_url, extra_scripts=extra_scripts, + hbd_version=hbd_version, hosts=[ hbdclass.Host.hosts[h].stateinfo() for h in sorted(hbdclass.Host.hosts) ], diff --git a/sorttable.js b/hbd/server/static/sorttable.js similarity index 100% rename from sorttable.js rename to hbd/server/static/sorttable.js diff --git a/hbd/server/static/style.css b/hbd/server/static/style.css index c9cf165..649d705 100644 --- a/hbd/server/static/style.css +++ b/hbd/server/static/style.css @@ -140,4 +140,68 @@ float: left; } +/* ── Responsive / mobile ── */ +/* Suppress the global transition on mobile to avoid sluggish feel */ +@media (max-width: 640px) { + * { transition: none !important; } + + html, body { + overflow: auto; + height: auto; + font-size: 16px; /* prevent iOS auto-zoom on inputs */ + } + + /* Pages that use flex-column full-viewport layout need to relax on mobile */ + body[style*="height: 100vh"], + body { + height: auto !important; + min-height: 100vh; + } + + /* Containers: full width, no fixed heights */ + .container { + max-width: 100% !important; + max-height: none !important; + overflow: visible !important; + padding: 8px !important; + } + + /* Log section: fixed reasonable height instead of flex-grow */ + .log-section { + flex: none !important; + max-height: 40vh !important; + overflow-y: auto !important; + } + + /* Table section: allow vertical scroll, cap height */ + .table-section { + max-height: 55vh !important; + overflow-y: auto !important; + overflow-x: auto !important; + padding: 8px !important; + } + + /* Slightly larger tap targets in tables */ + #ntable td, #ntable th { + padding: 4px 6px !important; + font-size: 0.82em !important; + } + + /* Cards on plugin/alerts pages */ + .host-card, .alert-card, .card { + padding: 10px !important; + margin-bottom: 8px !important; + } + + /* Settings page tables */ + table { width: 100%; } + + h1 { font-size: 1.2em !important; } + h2 { font-size: 1em !important; } +} + +/* Suppress nav-username text on very narrow screens — avatar/initials is enough */ +@media (max-width: 400px) { + .nav-username { display: none; } +} diff --git a/hbd/server/templates/alerts.html b/hbd/server/templates/alerts.html index 7deb67f..9cfe400 100644 --- a/hbd/server/templates/alerts.html +++ b/hbd/server/templates/alerts.html @@ -24,55 +24,40 @@ } .summary-cards { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: 20px; - margin-bottom: 30px; + display: flex; + flex-wrap: wrap; + gap: 10px; + margin-bottom: 16px; } .summary-card { background: white; - border-radius: 8px; - padding: 20px; - box-shadow: 0 2px 8px rgba(0,0,0,0.1); - text-align: center; + border-radius: 6px; + padding: 6px 14px; + box-shadow: 0 1px 4px rgba(0,0,0,0.1); + display: flex; + align-items: center; + gap: 8px; + border-left: 4px solid #ddd; } - .summary-card.critical { - border-left: 5px solid #f44336; - } - - .summary-card.warning { - border-left: 5px solid #ff9800; - } - - .summary-card.ok { - border-left: 5px solid #4caf50; - } + .summary-card.critical { border-left-color: #f44336; } + .summary-card.warning { border-left-color: #ff9800; } + .summary-card.ok { border-left-color: #4caf50; } .summary-number { - font-size: 3em; + font-size: 1.4em; font-weight: bold; - margin: 10px 0; + line-height: 1; } - .summary-number.critical { - color: #f44336; - } - - .summary-number.warning { - color: #ff9800; - } - - .summary-number.ok { - color: #4caf50; - } + .summary-number.critical { color: #f44336; } + .summary-number.warning { color: #ff9800; } + .summary-number.ok { color: #4caf50; } .summary-label { color: #666; - text-transform: uppercase; - font-size: 0.9em; - letter-spacing: 1px; + font-size: 0.85em; } .filters { diff --git a/hbd/server/templates/head.html b/hbd/server/templates/head.html index 8136c7d..db8b1eb 100644 --- a/hbd/server/templates/head.html +++ b/hbd/server/templates/head.html @@ -1,5 +1,6 @@
+