blob: 862e102e37ebea6e1e92957a1e3ffbe3ffa84343 [file] [log] [blame]
// Copyright 2017 The Go Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd.
// Package health provides health check handlers.
package health
import (
"io"
"net/http"
)
// Handler is an HTTP handler that reports on the success of an
// aggregate of Checkers. The zero value is always healthy.
type Handler struct {
checkers []Checker
}
// Add adds a new check to the handler.
func (h *Handler) Add(c Checker) {
h.checkers = append(h.checkers, c)
}
// ServeHTTP returns 200 if it is healthy, 500 otherwise.
func (h *Handler) ServeHTTP(w http.ResponseWriter, _ *http.Request) {
for _, c := range h.checkers {
if err := c.CheckHealth(); err != nil {
writeUnhealthy(w)
return
}
}
writeHealthy(w)
}
func writeUnhealthy(w http.ResponseWriter) {
w.Header().Set("Content-Length", "9")
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.Header().Set("X-Content-Type-Options", "nosniff")
w.WriteHeader(http.StatusInternalServerError)
io.WriteString(w, "unhealthy")
}
// HandleLive is an http.HandleFunc that handles liveness checks by
// immediately responding with an HTTP 200 status.
func HandleLive(w http.ResponseWriter, _ *http.Request) {
writeHealthy(w)
}
func writeHealthy(w http.ResponseWriter) {
w.Header().Set("Content-Length", "2")
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.Header().Set("X-Content-Type-Options", "nosniff")
w.WriteHeader(http.StatusOK)
io.WriteString(w, "ok")
}
// Checker wraps the CheckHealth method.
//
// CheckHealth returns nil if the resource is healthy, or a non-nil
// error if the resource is not healthy. CheckHealth must be safe to
// call from multiple goroutines.
type Checker interface {
CheckHealth() error
}