From 8c9a2b022b37aeec0a9ad405a3406e37f970cbd2 Mon Sep 17 00:00:00 2001 From: yusing Date: Fri, 28 Mar 2025 07:55:43 +0800 Subject: [PATCH] feat: agent health monitor --- .../watcher/health/monitor/agent_proxied.go | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 internal/watcher/health/monitor/agent_proxied.go diff --git a/internal/watcher/health/monitor/agent_proxied.go b/internal/watcher/health/monitor/agent_proxied.go new file mode 100644 index 00000000..82ca0aa3 --- /dev/null +++ b/internal/watcher/health/monitor/agent_proxied.go @@ -0,0 +1,75 @@ +package monitor + +import ( + "encoding/json" + "errors" + "net/http" + "net/url" + + agentPkg "github.com/yusing/go-proxy/agent/pkg/agent" + "github.com/yusing/go-proxy/internal/net/types" + "github.com/yusing/go-proxy/internal/watcher/health" +) + +type ( + AgentProxiedMonitor struct { + agent *agentPkg.AgentConfig + endpointURL string + *monitor + } + AgentCheckHealthTarget struct { + Scheme string + Host string + Path string + } +) + +func AgentTargetFromURL(url *types.URL) *AgentCheckHealthTarget { + return &AgentCheckHealthTarget{ + Scheme: url.Scheme, + Host: url.Host, + Path: url.Path, + } +} + +func (target *AgentCheckHealthTarget) buildQuery() string { + query := make(url.Values, 3) + query.Set("scheme", target.Scheme) + query.Set("host", target.Host) + query.Set("path", target.Path) + return query.Encode() +} + +func (target *AgentCheckHealthTarget) displayURL() *types.URL { + return types.NewURL(&url.URL{ + Scheme: target.Scheme, + Host: target.Host, + Path: target.Path, + }) +} + +func NewAgentProxiedMonitor(agent *agentPkg.AgentConfig, config *health.HealthCheckConfig, target *AgentCheckHealthTarget) *AgentProxiedMonitor { + mon := &AgentProxiedMonitor{ + agent: agent, + endpointURL: agentPkg.EndpointHealth + "?" + target.buildQuery(), + } + mon.monitor = newMonitor(target.displayURL(), config, mon.CheckHealth) + return mon +} + +func (mon *AgentProxiedMonitor) CheckHealth() (result *health.HealthCheckResult, err error) { + result = new(health.HealthCheckResult) + ctx, cancel := mon.ContextWithTimeout("timeout querying agent") + defer cancel() + data, status, err := mon.agent.Fetch(ctx, mon.endpointURL) + if err != nil { + return result, err + } + switch status { + case http.StatusOK: + err = json.Unmarshal(data, result) + default: + err = errors.New(string(data)) + } + return +}