github.com/thanos-io/thanos@v0.32.5/pkg/prober/http.go (about) 1 // Copyright (c) The Thanos Authors. 2 // Licensed under the Apache License 2.0. 3 4 package prober 5 6 import ( 7 "io" 8 "net/http" 9 10 "github.com/go-kit/log" 11 "github.com/go-kit/log/level" 12 "go.uber.org/atomic" 13 ) 14 15 type check func() bool 16 17 // HTTPProbe represents health and readiness status of given component, and provides HTTP integration. 18 type HTTPProbe struct { 19 ready atomic.Uint32 20 healthy atomic.Uint32 21 } 22 23 // NewHTTP returns HTTPProbe representing readiness and healthiness of given component. 24 func NewHTTP() *HTTPProbe { 25 return &HTTPProbe{} 26 } 27 28 // HealthyHandler returns a HTTP Handler which responds health checks. 29 func (p *HTTPProbe) HealthyHandler(logger log.Logger) http.HandlerFunc { 30 return p.handler(logger, p.isHealthy) 31 } 32 33 // ReadyHandler returns a HTTP Handler which responds readiness checks. 34 func (p *HTTPProbe) ReadyHandler(logger log.Logger) http.HandlerFunc { 35 return p.handler(logger, p.IsReady) 36 } 37 38 func (p *HTTPProbe) handler(logger log.Logger, c check) http.HandlerFunc { 39 return func(w http.ResponseWriter, _ *http.Request) { 40 if !c() { 41 http.Error(w, "NOT OK", http.StatusServiceUnavailable) 42 return 43 } 44 if _, err := io.WriteString(w, "OK"); err != nil { 45 level.Error(logger).Log("msg", "failed to write probe response", "err", err) 46 } 47 } 48 } 49 50 // IsReady returns true if component is ready. 51 func (p *HTTPProbe) IsReady() bool { 52 ready := p.ready.Load() 53 return ready > 0 54 } 55 56 // isHealthy returns true if component is healthy. 57 func (p *HTTPProbe) isHealthy() bool { 58 healthy := p.healthy.Load() 59 return healthy > 0 60 } 61 62 // Ready sets components status to ready. 63 func (p *HTTPProbe) Ready() { 64 p.ready.Swap(1) 65 } 66 67 // NotReady sets components status to not ready with given error as a cause. 68 func (p *HTTPProbe) NotReady(err error) { 69 p.ready.Swap(0) 70 71 } 72 73 // Healthy sets components status to healthy. 74 func (p *HTTPProbe) Healthy() { 75 p.healthy.Swap(1) 76 } 77 78 // NotHealthy sets components status to not healthy with given error as a cause. 79 func (p *HTTPProbe) NotHealthy(err error) { 80 p.healthy.Swap(0) 81 }