package web import ( "fmt" "net/http" "time" "github.com/go-chi/render" log "scm.yoorie.de/go-lib/gelf" ) /* healthChecker Class */ type healthChecker struct { message string healthy bool lastChecked time.Time startTime time.Time period int ticker *time.Ticker done chan bool //This is the healtchcheck you will have to provide. checkFunc func() (bool, string) } type HealthData struct { Message string `json:"message,omitempty"` LastChecked time.Time `json:"lastChecked"` } func newHealthChecker(checkFunction func() (bool, string)) *healthChecker { hc := &healthChecker{} hc.checkFunc = checkFunction hc.startTime = time.Now() return hc } func (h *healthChecker) start(checkPeriodInSeconds int) { h.period = checkPeriodInSeconds h.message = "service starting" h.healthy = false h.doCheck() h.ticker = time.NewTicker(time.Second * time.Duration(h.period)) h.done = make(chan bool) go func() { for { select { case <-h.done: return case <-h.ticker.C: h.doCheck() } } }() } func (h *healthChecker) stop() { h.ticker.Stop() h.done <- true log.Debug("Health checker stopped.") } // internal function to process the health check func (h *healthChecker) doCheck() { var msg string h.healthy, msg = h.checkFunc() if !h.healthy { h.message = msg } else { h.message = "" } h.lastChecked = time.Now() } /* GetHealthyEndpoint is this service healthy */ func (h *healthChecker) healthyEndpoint(responseWriter http.ResponseWriter, request *http.Request) { t := time.Now() status := http.StatusOK healtData := &HealthData{ Message: "service up and running", LastChecked: h.lastChecked, } if t.Sub(h.lastChecked) > (time.Second * time.Duration(2*h.period)) { h.healthy = false h.message = "Healthcheck not running" } if !h.healthy { status = http.StatusServiceUnavailable healtData.Message = fmt.Sprintf("service is unavailable: %s", h.message) } responseWriter.WriteHeader(status) render.JSON(responseWriter, request, healtData) } /* GetReadinessEndpoint is this service ready for taking requests */ func (h *healthChecker) readinessEndpoint(responseWriter http.ResponseWriter, request *http.Request) { render.JSON(responseWriter, request, &HealthData{ Message: "service is ready", LastChecked: h.startTime, }) }