fleet/server/health/health.go
Zach Wasserman db22f68c88
Separate health checks for MySQL and Redis (#6468)
This required a bit of refactoring of some mocking due to how the code
generation does not handle having the same function in different types.
2022-07-01 08:08:03 -03:00

74 lines
1.9 KiB
Go

// Package health adds methods for checking the health of service dependencies.
package health
import (
"net/http"
"github.com/go-kit/kit/log"
)
// Checker returns an error indicating if a service is in an unhealthy state.
// Checkers should be implemented by dependencies which can fail, like a DB or mail service.
type Checker interface {
HealthCheck() error
}
// Handler returns an http.Handler that checks the status of all the dependencies.
// Handler responds with either:
// 200 OK if the server can successfully communicate with it's backends or
// 500 if any of the backends are reporting an issue.
func Handler(logger log.Logger, allCheckers map[string]Checker) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
checkers := make(map[string]Checker)
checks, ok := r.URL.Query()["check"]
if ok {
if len(checks) == 0 {
http.Error(w, "checks must not be empty", http.StatusBadRequest)
return
}
for _, checkName := range checks {
check, ok := allCheckers[checkName]
if !ok {
http.Error(w, "the provided check is not valid", http.StatusBadRequest)
return
}
checkers[checkName] = check
}
} else {
checkers = allCheckers
}
healthy := CheckHealth(logger, checkers)
if !healthy {
w.WriteHeader(http.StatusInternalServerError)
return
}
}
}
// CheckHealth checks multiple checkers returning false if any of them fail.
// CheckHealth logs the reason a checker fails.
func CheckHealth(logger log.Logger, checkers map[string]Checker) bool {
healthy := true
for name, hc := range checkers {
if err := hc.HealthCheck(); err != nil {
log.With(logger, "component", "healthz").Log("err", err, "health-checker", name)
healthy = false
continue
}
}
return healthy
}
// Nop creates a noop checker. Useful in tests.
func Nop() Checker {
return nop{}
}
type nop struct{}
func (c nop) HealthCheck() error {
return nil
}