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  }