80 lines
1.7 KiB
Go
80 lines
1.7 KiB
Go
package healthhttp
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"time"
|
|
|
|
"gitea.dwysokinski.me/twhelp/corev3/internal/health"
|
|
)
|
|
|
|
type handler struct {
|
|
check func(ctx context.Context) health.Result
|
|
}
|
|
|
|
var _ http.Handler = (*handler)(nil)
|
|
|
|
func LiveHandler(h *health.Health) http.Handler {
|
|
return &handler{
|
|
check: h.CheckLive,
|
|
}
|
|
}
|
|
|
|
func ReadyHandler(h *health.Health) http.Handler {
|
|
return &handler{
|
|
check: h.CheckReady,
|
|
}
|
|
}
|
|
|
|
type singleCheckResult struct {
|
|
Status string `json:"status"`
|
|
FailureReason string `json:"err,omitempty"`
|
|
Time time.Time `json:"time"`
|
|
}
|
|
|
|
type response struct {
|
|
Status string `json:"status"`
|
|
Checks map[string][]singleCheckResult `json:"checks"`
|
|
}
|
|
|
|
func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
result := h.check(r.Context())
|
|
|
|
respChecks := make(map[string][]singleCheckResult, len(result.Checks))
|
|
for name, checks := range result.Checks {
|
|
respChecks[name] = make([]singleCheckResult, 0, len(checks))
|
|
|
|
for _, ch := range checks {
|
|
failureReason := ""
|
|
if ch.Err != nil {
|
|
failureReason = ch.Err.Error()
|
|
}
|
|
|
|
respChecks[name] = append(respChecks[name], singleCheckResult{
|
|
Status: ch.Status.String(),
|
|
FailureReason: failureReason,
|
|
Time: ch.Time,
|
|
})
|
|
}
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(healthStatusToHTTPStatus(result.Status))
|
|
_ = json.NewEncoder(w).Encode(response{
|
|
Status: result.Status.String(),
|
|
Checks: respChecks,
|
|
})
|
|
}
|
|
|
|
func healthStatusToHTTPStatus(status health.Status) int {
|
|
switch status {
|
|
case health.StatusPass:
|
|
return http.StatusOK
|
|
case health.StatusFail:
|
|
return http.StatusServiceUnavailable
|
|
default:
|
|
return http.StatusInternalServerError
|
|
}
|
|
}
|