diff --git a/agent/probe.go b/agent/probe.go index b50735ea..05f6d7c5 100644 --- a/agent/probe.go +++ b/agent/probe.go @@ -14,8 +14,9 @@ import ( // ProbeManager manages network probe tasks. type ProbeManager struct { - mu sync.RWMutex - probes map[string]*probeTask // key = probe.Config.Key() + mu sync.RWMutex + probes map[string]*probeTask // key = probe.Config.Key() + httpClient *http.Client } type probeTask struct { @@ -33,6 +34,7 @@ type probeSample struct { func newProbeManager() *ProbeManager { return &ProbeManager{ probes: make(map[string]*probeTask), + httpClient: &http.Client{Timeout: 10 * time.Second}, } } @@ -168,7 +170,7 @@ func (pm *ProbeManager) executeProbe(task *probeTask) { case "tcp": latencyMs = probeTCP(task.config.Target, task.config.Port) case "http": - latencyMs = probeHTTP(task.config.Target) + latencyMs = probeHTTP(pm.httpClient, task.config.Target) default: slog.Warn("unknown probe protocol", "protocol", task.config.Protocol) return @@ -212,8 +214,7 @@ func probeTCP(target string, port uint16) float64 { } // probeHTTP measures HTTP GET request latency. Returns -1 on failure. -func probeHTTP(url string) float64 { - client := &http.Client{Timeout: 10 * time.Second} +func probeHTTP(client *http.Client, url string) float64 { start := time.Now() resp, err := client.Get(url) if err != nil { diff --git a/internal/hub/api_probes.go b/internal/hub/api_probes.go index 615daa41..51e0a9de 100644 --- a/internal/hub/api_probes.go +++ b/internal/hub/api_probes.go @@ -3,6 +3,7 @@ package hub import ( "encoding/json" "net/http" + "strings" "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase/core" @@ -75,6 +76,9 @@ func (h *Hub) createNetworkProbe(e *core.RequestEvent) error { if req.Protocol != "icmp" && req.Protocol != "tcp" && req.Protocol != "http" { return e.BadRequestError("protocol must be icmp, tcp, or http", nil) } + if req.Protocol == "http" && !strings.HasPrefix(req.Target, "http://") && !strings.HasPrefix(req.Target, "https://") { + return e.BadRequestError("http probe target must start with http:// or https://", nil) + } if req.Interval <= 0 { req.Interval = 10 } diff --git a/internal/hub/systems/system.go b/internal/hub/systems/system.go index df54e4cf..6156008c 100644 --- a/internal/hub/systems/system.go +++ b/internal/hub/systems/system.go @@ -169,7 +169,9 @@ func (sys *System) update() error { } // Fetch and save network probe results - go sys.fetchAndSaveProbeResults() + if sys.hasEnabledProbes() { + go sys.fetchAndSaveProbeResults() + } return err } diff --git a/internal/hub/systems/system_probes.go b/internal/hub/systems/system_probes.go index 4a71a458..b5a6aa63 100644 --- a/internal/hub/systems/system_probes.go +++ b/internal/hub/systems/system_probes.go @@ -27,17 +27,17 @@ func (sys *System) FetchNetworkProbeResults() (map[string]probe.Result, error) { return results, err } +// hasEnabledProbes returns true if this system has any enabled network probes. +func (sys *System) hasEnabledProbes() bool { + count, err := sys.manager.hub.CountRecords("network_probes", + dbx.NewExp("system = {:system} AND enabled = true", dbx.Params{"system": sys.Id})) + return err == nil && count > 0 +} + // fetchAndSaveProbeResults fetches probe results and saves them to the database. func (sys *System) fetchAndSaveProbeResults() { hub := sys.manager.hub - // Check if this system has any probes - count, err := hub.CountRecords("network_probes", - dbx.NewExp("system = {:system} AND enabled = true", dbx.Params{"system": sys.Id})) - if err != nil || count == 0 { - return - } - results, err := sys.FetchNetworkProbeResults() if err != nil || len(results) == 0 { return diff --git a/internal/hub/systems/system_realtime.go b/internal/hub/systems/system_realtime.go index de74fd77..729feff1 100644 --- a/internal/hub/systems/system_realtime.go +++ b/internal/hub/systems/system_realtime.go @@ -168,8 +168,10 @@ func (sm *SystemManager) fetchRealtimeDataAndNotify() { Containers: data.Containers, } // Fetch network probe results (lightweight in-memory read on agent) - if probes, err := sys.FetchNetworkProbeResults(); err == nil && len(probes) > 0 { - payload.Probes = probes + if sys.hasEnabledProbes() { + if probes, err := sys.FetchNetworkProbeResults(); err == nil && len(probes) > 0 { + payload.Probes = probes + } } bytes, err := json.Marshal(payload) if err == nil {