Add InstallPathHandler which allows for more then one path to be associated with health checking.

Currently it is only possible to have one group of checks which must all pass for the handler to report success.
Allowing multiple paths for these checks allows use of the same machinery for other kinds of checks, i.e. readiness.
This commit is contained in:
Jacob Tanenbaum 2018-05-10 16:21:39 -04:00
parent bed4531131
commit 2082a0f428
2 changed files with 43 additions and 2 deletions

View File

@ -66,6 +66,15 @@ func NamedCheck(name string, check func(r *http.Request) error) HealthzChecker {
// exactly one call to InstallHandler. Calling InstallHandler more
// than once for the same mux will result in a panic.
func InstallHandler(mux mux, checks ...HealthzChecker) {
InstallPathHandler(mux, "/healthz", checks...)
}
// InstallPathHandler registers handlers for health checking on
// a specific path to mux. *All handlers* for the path must be
// specified in exactly one call to InstallPathHandler. Calling
// InstallPathHandler more than once for the same path and mux will
// result in a panic.
func InstallPathHandler(mux mux, path string, checks ...HealthzChecker) {
if len(checks) == 0 {
glog.V(5).Info("No default health checks specified. Installing the ping handler.")
checks = []HealthzChecker{PingHealthz}
@ -73,9 +82,9 @@ func InstallHandler(mux mux, checks ...HealthzChecker) {
glog.V(5).Info("Installing healthz checkers:", strings.Join(checkerNames(checks...), ", "))
mux.Handle("/healthz", handleRootHealthz(checks...))
mux.Handle(path, handleRootHealthz(checks...))
for _, check := range checks {
mux.Handle(fmt.Sprintf("/healthz/%v", check.Name()), adaptCheckToHandler(check.Check))
mux.Handle(fmt.Sprintf("%s/%v", path, check.Name()), adaptCheckToHandler(check.Check))
}
}

View File

@ -42,6 +42,38 @@ func TestInstallHandler(t *testing.T) {
}
}
func TestInstallPathHandler(t *testing.T) {
mux := http.NewServeMux()
InstallPathHandler(mux, "/healthz/test")
InstallPathHandler(mux, "/healthz/ready")
req, err := http.NewRequest("GET", "http://example.com/healthz/test", nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
w := httptest.NewRecorder()
mux.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Errorf("expected %v, got %v", http.StatusOK, w.Code)
}
if w.Body.String() != "ok" {
t.Errorf("expected %v, got %v", "ok", w.Body.String())
}
req, err = http.NewRequest("GET", "http://example.com/healthz/ready", nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
w = httptest.NewRecorder()
mux.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Errorf("expected %v, got %v", http.StatusOK, w.Code)
}
if w.Body.String() != "ok" {
t.Errorf("expected %v, got %v", "ok", w.Body.String())
}
}
func TestMulitipleChecks(t *testing.T) {
tests := []struct {
path string