reproxy/app/proxy/health.go

80 lines
1.9 KiB
Go

package proxy
import (
"fmt"
"net/http"
"strings"
log "github.com/go-pkgz/lgr"
"github.com/go-pkgz/rest"
"github.com/umputun/reproxy/app/discovery"
)
func (h *Http) healthMiddleware(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" && strings.EqualFold(r.URL.Path, "/health") {
h.healthHandler(w, r)
return
}
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
func (h *Http) healthHandler(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
mappers := h.Mappers()
total := 0
for _, m := range mappers {
if m.MatchType == discovery.MTProxy {
total++
}
}
pingErrs := h.CheckHealth()
var errs []string
for _, pingErr := range pingErrs {
if pingErr != nil {
errs = append(errs, pingErr.Error())
}
}
if len(errs) > 0 {
w.WriteHeader(http.StatusExpectationFailed)
errResp := struct {
Status string `json:"status,omitempty"`
Services int `json:"services,omitempty"`
Passed int `json:"passed,omitempty"`
Failed int `json:"failed,omitempty"`
Errors []string `json:"errors,omitempty"`
}{Status: "failed", Services: total, Passed: len(pingErrs) - len(errs), Failed: len(errs), Errors: errs}
rest.RenderJSON(w, errResp)
return
}
w.WriteHeader(http.StatusOK)
_, err := fmt.Fprintf(w, `{"status": "ok", "services": %d}`, total)
if err != nil {
log.Printf("[WARN] failed to send health, %v", err)
}
}
// pingHandler middleware response with pong to /ping. Stops chain if ping request detected
func (h *Http) pingHandler(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" && strings.EqualFold(r.URL.Path, "/ping") {
w.Header().Set("Content-Type", "text/plain")
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("pong"))
return
}
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}