feat: add network probes (ICMP/TCP/HTTP) with latency and packet loss monitoring#1911
Open
XiaoMiku01 wants to merge 21 commits intohenrygd:mainfrom
Open
feat: add network probes (ICMP/TCP/HTTP) with latency and packet loss monitoring#1911XiaoMiku01 wants to merge 21 commits intohenrygd:mainfrom
XiaoMiku01 wants to merge 21 commits intohenrygd:mainfrom
Conversation
Implements the core probe execution engine (ProbeManager) that runs network probes on configurable intervals, collects latency samples, and aggregates results over a 60s sliding window. Adds two new WebSocket handlers (SyncNetworkProbes, GetNetworkProbeResults) for hub-agent communication and integrates probe lifecycle into the agent. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add TypeScript interfaces for the network probes feature API responses. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dialog component for adding ICMP/TCP/HTTP network probes with protocol selection, target, port, interval, and name fields. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Displays probe list with protocol badges, latency/loss stats, and delete functionality. Includes a latency line chart using ChartCard with data sourced from the network-probe-stats API. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Lazy-load the NetworkProbes component in both default and tabbed layouts so the probes table and latency chart appear on the system detail page. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Rename setInterval to setProbeInterval to avoid shadowing global - Move probeKey function outside component (pure function) - Fix probes.length dependency to use probes directly - Use proper type for stats fetch instead of any - Fix name column fallback to show target instead of dash Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Stats records in the DB contain historical data for all probes including deleted ones. Now filters stats by active probe keys and clears state when all probes are removed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Include probe results in the 1-second realtime WebSocket broadcast so the frontend can update probe latency/loss every second, matching the behavior of system and container metrics. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Existing databases from main branch lack the network_probes and network_probe_stats collections, which were only in the initial snapshot. This separate migration ensures they are created on upgrade. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use shared http.Client in ProbeManager to avoid connection/transport leak - Skip probe goroutine and agent request when system has no enabled probes - Validate HTTP probe target URL scheme (http:// or https://) on creation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pass system record to NetworkProbes component and use it as a dependency in the non-realtime fetch effect, matching the pattern used by system_stats and container_stats in use-system-data.ts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Apply appendData() for gap detection in both realtime and non-realtime modes, so the latency chart shows breaks instead of smooth lines when data is missing during service interruptions - Handle null stats in gap marker entries to prevent runtime crashes - Fix color assignment: use CSS variables (--chart-1..5) for ≤5 probes, switch to dynamic HSL distribution for >5 probes so all lines are visible with distinct colors Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the ping-command-only implementation with a three-tier approach using golang.org/x/net/icmp: 1. Raw socket (ip4:icmp) — works with root or CAP_NET_RAW 2. Unprivileged datagram socket (udp4) — works on Linux/macOS without special privileges 3. System ping command — fallback when neither socket works The method is auto-detected on first probe and cached for all subsequent calls, avoiding repeated failed attempts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolve the target hostname before starting the timer so the measurement reflects pure TCP handshake time only. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Owner
|
Thank you for your work on this. I've wanted to add this feature but haven't had the time. The implementation seems very similar to what I envisioned. I can't review immediately but will get back to you soon. |
Resolved conflict in internal/records/records.go: - Upstream refactor moved deletion code to records_deletion.go and switched averaging functions from package-level globals to local variables (var row StatsRecord / params := make(dbx.Params, 1)). - Kept AverageProbeStats and rewrote it to match the new local-variable pattern. - Dropped duplicated deletion helpers from records.go (they now live in records_deletion.go). - Added "network_probe_stats" to the collections list in records_deletion.go:deleteOldSystemStats so probe stats keep the same retention policy.
# Conflicts: # agent/connection_manager.go
Owner
|
Working on this now. No need to merge any updates to main going forward 👍 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📃 Description
Add network probes (ICMP/TCP/HTTP) to Beszel, allowing users to monitor latency and packet loss from any monitored agent to arbitrary targets. Probes are configured per-system via the UI, executed on the agent side with results aggregated over a 60-second sliding window, and displayed as a table + latency chart on the system detail page. Realtime mode is also supported.
📖 Documentation
N/A
🪵 Changelog
➕ Added
SyncNetworkProbesandGetNetworkProbeResultsWebSocket action types for hub-agent communicationConfig,Result) ininternal/entities/probe/ProbeManagerwith ICMP (unprivileged ping), TCP, and HTTP probe execution on configurable intervals/api/beszel/network-probes,/api/beszel/network-probe-stats) for CRUD and stats retrievalnetwork_probesandnetwork_probe_statsPocketBase collections (initial snapshot + upgrade migration)NetworkProbeRecordandNetworkProbeStatsRecordTypeScript typesChartCardwith historical stats dataNetworkProbescomponent integrated into both default and tabbed system detail layouts✏️ Changed
use-system-data.tsupdated to pass system record as a dependency for probe stats auto-refresh🔧 Fixed
http.ClientinProbeManagerto avoid connection/transport leakshttp://orhttps://) on creationsetIntervaltosetProbeIntervalto avoid shadowing the globalprobeKeyfunction outside component (pure function, no closure needed)probes.lengthdependency to useprobesdirectly in effect depsany🗑️ Removed
📷 Screenshots