Send history messages newest-first from the server, tagged with
history=True so the client appends rather than prepends them, avoiding
reverse-chronological display on initial load.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds structured form fields for nsupdate_bin, rndc_key, and dyndomains
(comma-separated list). Wires list-type editable fields through the
generic stageFormSection path and adds DNS support to
apply_structured_section in configio.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the 5 native <select multiple> fields (Managers, Monitors,
Threshold config, Channels in Hosts; Channels in Users) with a compact
picker widget: a truncated pill display with tooltip, and a click-to-open
panel split into Available / Selected columns for moving items between sides.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Shows an orange "Publish Config" button to the left of the alert-pie
for admin users when there are staged config changes. Uses localStorage
to persist staged changes across page navigations so the button appears
on any page, not just settings.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
threshold_config in .hb.yaml can be a list (e.g. [local, zrepl]).
The hosts table was treating it as a single string, so the pre-selected
value never matched. Normalize to a list in settings.py, switch the
select to multiple, and fix the JS to collect all selected options.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Settings > Hosts now renders a table with per-column controls
(watch, dyndns, owner, managers/monitors multi-select, threshold
config, notification channels) instead of a raw YAML textarea.
Changes stage via the existing Publish flow like other form sections.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The per-user notification channel selector in the admin settings Users
section was a column of checkboxes; replaced with a <select multiple>
for consistency with the profile chip picker and to reduce table width.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Notification channels are now managed through a proper web form instead
of a raw YAML textarea. Any authenticated user can create channels; private
channels (owner-scoped) are hidden from other users. The user profile
channel selector becomes a tag/chip picker with a "My Channels" CRUD section.
- settings.py: add CHANNEL_TYPE_SCHEMAS for all 6 notifier types; channel
section switches to section_mode="channels"; cards include owner/private/min_level
- configio.py: add apply_channel() and delete_channel() for per-entry CRUD
- notify.py: strip owner/private metadata before dispatching to drivers
- http.py: add GET/POST /api/0/notification_channels, PUT/DELETE /{name},
GET /api/0/notification_channel_types; visibility helper filters private
channels per user; PUT /api/0/users/me validates against visible channels
- settings.html: card grid with edit/delete per channel; add/edit modal
with type dropdown and dynamically rendered type-specific fields
- profile.html: chip picker replaces checkbox list; My Channels section
for creating/editing/deleting user-owned channels
- tests: update test_settings_sections, test_http_users_me; add
test_notification_channels_api (16 new tests, 46 total passing)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fetchHostGlance was only called for the initially expanded host, leaving
all other hosts showing "—" until manually expanded. Now fetches glance
for every host-card on DOMContentLoaded and refreshes all (not just
expanded) on the 30s auto-refresh interval.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
DOMContentLoaded was calling fetchHostGlance but not fetchHostInfo,
leaving the info-meta section stuck on "Loading…". Both the URL-hash
and default first-host paths now call fetchHostInfo and populate
infoCache on load.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add regex filter input to the Alerts dashboard that filters displayed
hosts on every keystroke; invalid regex turns the border red
- Initialise the filter from ?filter= in the URL query string
- Change _build_url() to produce /alerts?filter=<hostname> so
notification links (Pushover, email, Matrix, etc.) land on the
alerts page pre-filtered to the alerting host
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Store owner in data-owner attribute; updateHostHeader always prepends it
so it survives innerHTML replacement. Render it immediately on page load
before JS fetches plugin data.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- owner: optional top-level config key in ~/.hbc.yaml / ~/.hbc.json
- Propagated into plugin configs at load time so os_info can include it
- os_info PLG data carries owner field when set
- udp: sets host.owner from os_info if not already configured server-side
- live.html: format event log timestamps as YYYY-MM-DD HH:MM:SS (24-hour)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- eventlog() now stores {ts, host, level, service, message} dicts instead of strings
- WebSocket sends/broadcasts filter event log messages by the user's managed hosts
- live.html renders structured log entries with level-coloured spans
- Swiss railway clock minute hand now holds until second hand reaches 12, then steps
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Alerts page: move metric name into the header row alongside hostname.
Notifications: include metric name in title (hostname metric) and
strip the metric prefix from the body so it contains only value/detail.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add ComparisonOperator.NAGIOS ("nagios") that maps Nagios exit codes
directly to alert levels (0=OK 1=WARNING 2=CRITICAL 3=UNKNOWN) without
requiring numeric warning/critical thresholds. Hysteresis is bypassed for
discrete codes. Display template defaults to "{check_name}: {output}".
_format_display() handles None threshold_value gracefully.
Add nagios_runner.status_code as a built-in default threshold config so
nagios checks alert out of the box.
Also: fix alerts.html scrolling (override html,body), make hostname a link
to /plugins#<hostname>, remove overall_status/overall_status_code/plugin_count
from nagios_runner and hbc_mini, replace with computed worst-status in
plugins.html via nagiosWorstStatus() helper.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- nagios_runner: remove overall_status/overall_status_code/plugin_count fields;
each command still reports its own <name>_status and <name>_status_code
- threshold: expose {output} and {status} aliases in display templates for
nagios_runner generic matches (mapped from <check_name>_output/status)
- alerts.html: fix scrolling by overriding html,body height/overflow (style.css
sets both); make hostname a link to /plugins/<hostname>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The 10% default hysteresis created an unreasonably wide recovery band:
a 95% threshold would only clear once the value dropped below 85.5%,
causing alerts to linger long after the metric was well below the
trigger level.
Change default hysteresis to 2% across all threshold parsers (plugin
metrics, partitions, RTT). For a 95% threshold, recovery is now at
93.1% instead of 85.5%.
Add AlertState.hysteresis field (set on every check, cleared on OK) and
expose recovery_threshold in to_dict() so the Alerts dashboard can
display "recovers < 93.1" alongside the trigger threshold, making the
hysteresis band visible to the user. Pickle backward-compatible via
__setstate__.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace href navigation with fetch() so the server response is captured
and displayed in a slide-up toast at the bottom of the page. Delete also
removes the host card from the DOM on success without a page reload.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Host Overview (plugins.html): show Update and Delete buttons in the
host-right zone when the logged-in user is the host owner (or admin /
unauthenticated mode). Buttons link to /u?h=<host> and /d?h=<host>
with stopPropagation so they don't toggle the accordion; Delete prompts
for confirmation first.
ThresholdChecker.purge_stale_alerts(): removes alert states whose
metric_path has no matching threshold in the current config. Called
after startup pickle restore and after every SIGHUP config reload so
alerts orphaned by upgrades or config changes do not persist
indefinitely.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Override the global style.css body height/overflow that locks all pages
to the viewport height (a remnant of the old drawer-menu layout).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Show a colour-coded pie chart (red=critical, yellow=warning, green=ok)
to the left of the clock in the nav bar. Backed by a new
GET /api/0/alert_summary endpoint that counts hosts per alert level
for the current user's visible hosts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- threshold.py: add _find_threshold() with suffix fallback so thresholds
like ping_monitor.rtt_avg match ping_monitor.8_8_8_8_rtt_avg etc.;
each pinged host keeps its own alert state
- hbdclass.py: format RTT as integer ms (round())
- live.html: JS RTT display rounded to nearest ms (Math.round)
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Hostnames in the live dashboard table are now links to /plugins#hostname,
which expands and scrolls to that host's card in the Host Overview page.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Add renderZfsTables() to plugins.html with health/capacity/frag/dedup
table and cumulative I/O table; colour-code health and capacity thresholds;
add zfs_monitor to plugin_order and summary/render dispatch.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- fix: matrix/sms_voipms notifications blocked the event loop on timeout;
make send_notification async, dispatch all channel drivers as non-blocking
tasks (asyncio.to_thread for sync drivers, asyncio.wait_for for async);
update all call sites to fire-and-forget via create_task
- feat: add /about page with version, runtime, uptime counter, and repo link
- fix: hbc_mini plugin data format now matches full hbc client so Host
Overview displays memory, disk, and network metrics correctly
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Replace pill-tab plugin view with an accordion layout that shows key
metrics (CPU%, MEM%, top disk%, net delta, nagios status) at a glance
in each host card header. Plugin sections expand as structured tables.
- Rename page to "Host Overview" (URL /plugins unchanged)
- Three-wave parallel data loading: glance plugins on host expand,
on-demand fetch for filesystem_info and extras
- Per-plugin table renderers with inline percent bars and threshold
colour coding
- Add escHtml() for XSS-safe rendering of all field values
- Remove stale planning docs (REFACTORING.md, hbd/Plan.md)
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>