Files
coredns/middleware/health/health.go
Miek Gieben 558f4bea41 mw/health: poll other middleware (#976)
This add the infrastructure to let other middleware report their health
status back to the health middleware. A health.Healther interface is
introduced and a middleware needs to implement that. A middleware
that supports healthchecks is statically configured.

Every second each supported middleware is queried and the global health
state is updated.

Actual tests have been disabled as no other middleware implements this
at the moment.
2017-08-27 13:33:38 -07:00

70 lines
1.1 KiB
Go

// Package health implements an HTTP handler that responds to health checks.
package health
import (
"io"
"log"
"net"
"net/http"
"sync"
)
var once sync.Once
type health struct {
Addr string
ln net.Listener
mux *http.ServeMux
// A slice of Healthers that the health middleware will poll every second for their health status.
h []Healther
sync.RWMutex
ok bool // ok is the global boolean indicating an all healthy middleware stack
}
func (h *health) Startup() error {
if h.Addr == "" {
h.Addr = defAddr
}
once.Do(func() {
ln, err := net.Listen("tcp", h.Addr)
if err != nil {
log.Printf("[ERROR] Failed to start health handler: %s", err)
return
}
h.ln = ln
h.mux = http.NewServeMux()
h.mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
if h.Ok() {
w.WriteHeader(http.StatusOK)
io.WriteString(w, ok)
return
}
w.WriteHeader(http.StatusServiceUnavailable)
})
go func() {
http.Serve(h.ln, h.mux)
}()
})
return nil
}
func (h *health) Shutdown() error {
if h.ln != nil {
return h.ln.Close()
}
return nil
}
const (
ok = "OK"
defAddr = ":8080"
path = "/health"
)