refactor: health check logic

This commit is contained in:
yusing 2025-05-10 22:55:20 +08:00
parent a8ba42e360
commit 30c76cfc5f
4 changed files with 36 additions and 34 deletions

View file

@ -21,15 +21,16 @@ func NewFileServerHealthMonitor(config *health.HealthCheckConfig, path string) *
func (s *FileServerHealthMonitor) CheckHealth() (*health.HealthCheckResult, error) {
start := time.Now()
_, err := os.Stat(s.path)
detail := ""
if err != nil {
detail = err.Error()
if os.IsNotExist(err) {
return &health.HealthCheckResult{
Detail: err.Error(),
}, nil
}
return nil, err
}
return &health.HealthCheckResult{
Healthy: err == nil,
Healthy: true,
Latency: time.Since(start),
Detail: detail,
}, nil
}

View file

@ -37,19 +37,18 @@ func NewHTTPHealthMonitor(url *url.URL, config *health.HealthCheckConfig) *HTTPH
return mon
}
func (mon *HTTPHealthMonitor) CheckHealth() (result *health.HealthCheckResult, err error) {
func (mon *HTTPHealthMonitor) CheckHealth() (*health.HealthCheckResult, error) {
ctx, cancel := mon.ContextWithTimeout("ping request timed out")
defer cancel()
req, reqErr := http.NewRequestWithContext(
req, err := http.NewRequestWithContext(
ctx,
mon.method,
mon.url.Load().JoinPath(mon.config.Path).String(),
nil,
)
if reqErr != nil {
err = reqErr
return
if err != nil {
return nil, err
}
req.Close = true
req.Header.Set("Connection", "close")
@ -62,22 +61,26 @@ func (mon *HTTPHealthMonitor) CheckHealth() (result *health.HealthCheckResult, e
}
lat := time.Since(start)
result = &health.HealthCheckResult{}
switch {
case respErr != nil:
// treat tls error as healthy
var tlsErr *tls.CertificateVerificationError
if ok := errors.As(respErr, &tlsErr); !ok {
result.Detail = respErr.Error()
return
return &health.HealthCheckResult{
Latency: lat,
Detail: respErr.Error(),
}, nil
}
case resp.StatusCode == http.StatusServiceUnavailable:
result.Detail = resp.Status
return
return &health.HealthCheckResult{
Latency: lat,
Detail: resp.Status,
}, nil
}
result.Latency = lat
result.Healthy = true
return
return &health.HealthCheckResult{
Latency: lat,
Healthy: true,
}, nil
}

View file

@ -215,15 +215,14 @@ func (mon *monitor) checkUpdateHealth() error {
result, err := mon.checkHealth()
var lastStatus health.Status
if err != nil {
if result == nil {
result = &health.HealthCheckResult{Healthy: false, Detail: err.Error()}
}
switch {
case err != nil:
result = &health.HealthCheckResult{Healthy: false, Detail: err.Error()}
lastStatus = mon.status.Swap(health.StatusError)
} else if result.Healthy {
case result.Healthy:
lastStatus = mon.status.Swap(health.StatusHealthy)
UpdateLastSeen(mon.service)
} else {
default:
lastStatus = mon.status.Swap(health.StatusUnhealthy)
}
mon.lastResult.Store(result)

View file

@ -25,20 +25,19 @@ func NewRawHealthMonitor(url *url.URL, config *health.HealthCheckConfig) *RawHea
return mon
}
func (mon *RawHealthMonitor) CheckHealth() (result *health.HealthCheckResult, err error) {
func (mon *RawHealthMonitor) CheckHealth() (*health.HealthCheckResult, error) {
ctx, cancel := mon.ContextWithTimeout("ping request timed out")
defer cancel()
url := mon.url.Load()
start := time.Now()
conn, dialErr := mon.dialer.DialContext(ctx, url.Scheme, url.Host)
result = new(health.HealthCheckResult)
if dialErr != nil {
result.Detail = dialErr.Error()
return
conn, err := mon.dialer.DialContext(ctx, url.Scheme, url.Host)
if err != nil {
return nil, err
}
defer conn.Close()
result.Latency = time.Since(start)
result.Healthy = true
return
return &health.HealthCheckResult{
Latency: time.Since(start),
Healthy: true,
}, nil
}