diff --git a/agent/pkg/handler/check_health.go b/agent/pkg/handler/check_health.go index f656453..5f9c954 100644 --- a/agent/pkg/handler/check_health.go +++ b/agent/pkg/handler/check_health.go @@ -44,7 +44,7 @@ func CheckHealth(w http.ResponseWriter, r *http.Request) { http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } - result, err = monitor.NewHTTPHealthChecker(types.NewURL(&url.URL{ + result, err = monitor.NewHTTPHealthMonitor(types.NewURL(&url.URL{ Scheme: scheme, Host: host, Path: path, @@ -63,7 +63,7 @@ func CheckHealth(w http.ResponseWriter, r *http.Request) { http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } - result, err = monitor.NewRawHealthChecker(types.NewURL(&url.URL{ + result, err = monitor.NewRawHealthMonitor(types.NewURL(&url.URL{ Scheme: scheme, Host: host, }), defaultHealthConfig).CheckHealth() diff --git a/internal/route/reverse_proxy.go b/internal/route/reverse_proxy.go index 5cf9c4c..d08551d 100755 --- a/internal/route/reverse_proxy.go +++ b/internal/route/reverse_proxy.go @@ -112,17 +112,7 @@ func (r *ReveseProxyRoute) Start(parent task.Parent) gperr.Error { r.handler = waker r.HealthMon = waker case r.UseHealthCheck(): - if r.IsDocker() { - client, err := docker.NewClient(r.Container.DockerHost) - if err == nil { - fallback := r.newHealthMonitor() - r.HealthMon = monitor.NewDockerHealthMonitor(client, r.Container.ContainerID, r.TargetName(), r.HealthCheck, fallback) - r.task.OnCancel("close_docker_client", client.Close) - } - } - if r.HealthMon == nil { - r.HealthMon = r.newHealthMonitor() - } + r.HealthMon = monitor.NewMonitor(r) } if r.UseAccessLog() { @@ -205,17 +195,6 @@ func (r *ReveseProxyRoute) HealthMonitor() health.HealthMonitor { return r.HealthMon } -func (r *ReveseProxyRoute) newHealthMonitor() interface { - health.HealthMonitor - health.HealthChecker -} { - if a := r.Agent(); a != nil { - target := monitor.AgentTargetFromURL(r.ProxyURL) - return monitor.NewAgentProxiedMonitor(a, r.HealthCheck, target) - } - return monitor.NewHTTPHealthMonitor(r.ProxyURL, r.HealthCheck) -} - func (r *ReveseProxyRoute) addToLoadBalancer(parent task.Parent) { var lb *loadbalancer.LoadBalancer cfg := r.LoadBalance diff --git a/internal/route/stream.go b/internal/route/stream.go index 02e7334..dd09df7 100755 --- a/internal/route/stream.go +++ b/internal/route/stream.go @@ -66,17 +66,7 @@ func (r *StreamRoute) Start(parent task.Parent) gperr.Error { r.Stream = waker r.HealthMon = waker case r.UseHealthCheck(): - if r.IsDocker() { - client, err := docker.NewClient(r.Container.DockerHost) - if err == nil { - fallback := monitor.NewRawHealthChecker(r.TargetURL(), r.HealthCheck) - r.HealthMon = monitor.NewDockerHealthMonitor(client, r.Container.ContainerID, r.TargetName(), r.HealthCheck, fallback) - r.task.OnCancel("close_docker_client", client.Close) - } - } - if r.HealthMon == nil { - r.HealthMon = monitor.NewRawHealthMonitor(r.TargetURL(), r.HealthCheck) - } + r.HealthMon = monitor.NewMonitor(r) } if err := r.Stream.Setup(); err != nil { @@ -88,7 +78,7 @@ func (r *StreamRoute) Start(parent task.Parent) gperr.Error { if r.HealthMon != nil { if err := r.HealthMon.Start(r.task); err != nil { - gperr.LogWarn("health monitor error", err, &r.l) + return err } } diff --git a/internal/watcher/health/monitor/http.go b/internal/watcher/health/monitor/http.go index cfd5645..9dec9f6 100644 --- a/internal/watcher/health/monitor/http.go +++ b/internal/watcher/health/monitor/http.go @@ -37,10 +37,6 @@ func NewHTTPHealthMonitor(url *types.URL, config *health.HealthCheckConfig) *HTT return mon } -func NewHTTPHealthChecker(url *types.URL, config *health.HealthCheckConfig) health.HealthChecker { - return NewHTTPHealthMonitor(url, config) -} - func (mon *HTTPHealthMonitor) CheckHealth() (result *health.HealthCheckResult, err error) { ctx, cancel := mon.ContextWithTimeout("ping request timed out") defer cancel() diff --git a/internal/watcher/health/monitor/monitor.go b/internal/watcher/health/monitor/monitor.go index 461f319..05197f5 100644 --- a/internal/watcher/health/monitor/monitor.go +++ b/internal/watcher/health/monitor/monitor.go @@ -6,10 +6,12 @@ import ( "fmt" "time" + "github.com/yusing/go-proxy/internal/docker" "github.com/yusing/go-proxy/internal/gperr" "github.com/yusing/go-proxy/internal/logging" "github.com/yusing/go-proxy/internal/net/types" "github.com/yusing/go-proxy/internal/notif" + route "github.com/yusing/go-proxy/internal/route/types" "github.com/yusing/go-proxy/internal/task" "github.com/yusing/go-proxy/internal/utils/atomic" "github.com/yusing/go-proxy/internal/utils/strutils" @@ -35,6 +37,32 @@ type ( var ErrNegativeInterval = errors.New("negative interval") +func NewMonitor(r route.Route) health.HealthMonCheck { + var mon health.HealthMonCheck + if r.IsAgent() { + mon = NewAgentProxiedMonitor(r.Agent(), r.HealthCheckConfig(), AgentTargetFromURL(r.TargetURL())) + } else { + switch r := r.(type) { + case route.HTTPRoute: + mon = NewHTTPHealthMonitor(r.TargetURL(), r.HealthCheckConfig()) + case route.StreamRoute: + mon = NewRawHealthMonitor(r.TargetURL(), r.HealthCheckConfig()) + default: + logging.Panic().Msgf("unexpected route type: %T", r) + } + } + if r.IsDocker() { + cont := r.DockerContainer() + client, err := docker.NewClient(cont.DockerHost) + if err != nil { + return mon + } + r.Task().OnCancel("close_docker_client", client.Close) + return NewDockerHealthMonitor(client, cont.ContainerID, r.TargetName(), r.HealthCheckConfig(), mon) + } + return mon +} + func newMonitor(url *types.URL, config *health.HealthCheckConfig, healthCheckFunc HealthCheckFunc) *monitor { mon := &monitor{ config: config, diff --git a/internal/watcher/health/monitor/raw.go b/internal/watcher/health/monitor/raw.go index 838d47a..e6358fd 100644 --- a/internal/watcher/health/monitor/raw.go +++ b/internal/watcher/health/monitor/raw.go @@ -25,10 +25,6 @@ func NewRawHealthMonitor(url *types.URL, config *health.HealthCheckConfig) *RawH return mon } -func NewRawHealthChecker(url *types.URL, config *health.HealthCheckConfig) health.HealthChecker { - return NewRawHealthMonitor(url, config) -} - func (mon *RawHealthMonitor) CheckHealth() (result *health.HealthCheckResult, err error) { ctx, cancel := mon.ContextWithTimeout("ping request timed out") defer cancel() diff --git a/internal/watcher/health/types.go b/internal/watcher/health/types.go index 4c8c0c5..de8a07f 100644 --- a/internal/watcher/health/types.go +++ b/internal/watcher/health/types.go @@ -34,4 +34,8 @@ type ( Config() *HealthCheckConfig UpdateURL(url *types.URL) } + HealthMonCheck interface { + HealthMonitor + HealthChecker + } )