mirror of
https://github.com/yusing/godoxy.git
synced 2026-03-24 10:01:04 +01:00
85 lines
2.1 KiB
Go
85 lines
2.1 KiB
Go
package monitor
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"errors"
|
|
"net/url"
|
|
"time"
|
|
|
|
"github.com/valyala/fasthttp"
|
|
"github.com/yusing/godoxy/internal/types"
|
|
"github.com/yusing/goutils/version"
|
|
)
|
|
|
|
type HTTPHealthMonitor struct {
|
|
*monitor
|
|
method string
|
|
}
|
|
|
|
var pinger = &fasthttp.Client{
|
|
ReadTimeout: 5 * time.Second,
|
|
WriteTimeout: 3 * time.Second,
|
|
MaxConnDuration: 0,
|
|
DisableHeaderNamesNormalizing: true,
|
|
DisablePathNormalizing: true,
|
|
TLSConfig: &tls.Config{
|
|
InsecureSkipVerify: true,
|
|
},
|
|
MaxConnsPerHost: 1,
|
|
NoDefaultUserAgentHeader: true,
|
|
}
|
|
|
|
func NewHTTPHealthMonitor(url *url.URL, config *types.HealthCheckConfig) *HTTPHealthMonitor {
|
|
mon := new(HTTPHealthMonitor)
|
|
mon.monitor = newMonitor(url, config, mon.CheckHealth)
|
|
if config.UseGet {
|
|
mon.method = fasthttp.MethodGet
|
|
} else {
|
|
mon.method = fasthttp.MethodHead
|
|
}
|
|
return mon
|
|
}
|
|
|
|
func (mon *HTTPHealthMonitor) CheckHealth() (types.HealthCheckResult, error) {
|
|
req := fasthttp.AcquireRequest()
|
|
defer fasthttp.ReleaseRequest(req)
|
|
|
|
resp := fasthttp.AcquireResponse()
|
|
defer fasthttp.ReleaseResponse(resp)
|
|
|
|
req.SetRequestURI(mon.url.Load().JoinPath(mon.config.Path).String())
|
|
req.Header.SetMethod(mon.method)
|
|
req.Header.Set("User-Agent", "GoDoxy/"+version.Get().String())
|
|
req.Header.Set("Accept", "text/plain,text/html,*/*;q=0.8")
|
|
req.Header.Set("Accept-Encoding", "identity")
|
|
req.Header.Set("Cache-Control", "no-cache")
|
|
req.Header.Set("Pragma", "no-cache")
|
|
req.SetConnectionClose()
|
|
|
|
start := time.Now()
|
|
respErr := pinger.DoTimeout(req, resp, mon.config.Timeout)
|
|
lat := time.Since(start)
|
|
|
|
switch {
|
|
case respErr != nil:
|
|
// treat TLS error as healthy
|
|
var tlsErr *tls.CertificateVerificationError
|
|
if ok := errors.As(respErr, &tlsErr); !ok {
|
|
return types.HealthCheckResult{
|
|
Latency: lat,
|
|
Detail: respErr.Error(),
|
|
}, nil
|
|
}
|
|
case resp.StatusCode() == fasthttp.StatusServiceUnavailable:
|
|
return types.HealthCheckResult{
|
|
Latency: lat,
|
|
Detail: fasthttp.StatusMessage(resp.StatusCode()),
|
|
}, nil
|
|
}
|
|
|
|
return types.HealthCheckResult{
|
|
Latency: lat,
|
|
Healthy: true,
|
|
}, nil
|
|
}
|