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.
- 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>
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>
- move hub's GetEnv function to new utils package to more easily share
across different hub packages
- change System.HasUser to take core.Record instead of user ID string
- add tests
- Validate the user is assigned to system in authenticated routes where
the user passes in system ID. This protects against a somewhat
impractical scenario where an authenticated user cracks a random 15
character alphanumeric ID of a system that doesn't belong to them via
web API.
- Validate that systemd service exists in database before requesting
service details from agent. This protects against authenticated users
getting unit properties of services that aren't explicitly monitored.
- Refactor responses in authenticated routes to prevent enumeration of
other users' random 15 char system IDs.
- Update smartFetchMap expiration when agent smart interval changes
- Prevent background SMART fetching before initial system details are
loaded
- Add buffer to SMART fetch timing check
- Get rid of unnecessary pointers in expirymap
Move tracking of the last SMART data fetch from individual System
instances to the SystemManager using a TTL-based ExpiryMap.
This ensures that the SMART_INTERVAL is respected even if an
agent connection is dropped and re-established, preventing
redundant data collection on every reconnect.
* feat: add outbound heartbeat monitoring to external endpoints
Allow Beszel hub to periodically ping an external monitoring service
(e.g. BetterStack, Uptime Kuma, Healthchecks.io) with system status
summaries, enabling monitoring without exposing Beszel to the internet.
Configuration via environment variables:
- BESZEL_HUB_HEARTBEAT_URL: endpoint to ping (required to enable)
- BESZEL_HUB_HEARTBEAT_INTERVAL: seconds between pings (default: 60)
- BESZEL_HUB_HEARTBEAT_METHOD: HTTP method - POST/GET/HEAD (default: POST)