66 lines
1.4 KiB
Go
66 lines
1.4 KiB
Go
package handler
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"sort"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type HealthHandler struct {
|
|
startedAt time.Time
|
|
checks map[string]ReadinessCheck
|
|
}
|
|
|
|
type ReadinessCheck func(context.Context) error
|
|
|
|
func NewHealthHandler(checks map[string]ReadinessCheck) *HealthHandler {
|
|
return &HealthHandler{startedAt: time.Now(), checks: checks}
|
|
}
|
|
|
|
func (h *HealthHandler) Live(c *gin.Context) {
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"status": "ok",
|
|
"service": "hfb-api",
|
|
"started_at": h.startedAt.Format(time.RFC3339),
|
|
})
|
|
}
|
|
|
|
func (h *HealthHandler) Ready(c *gin.Context) {
|
|
ctx, cancel := context.WithTimeout(c.Request.Context(), 2*time.Second)
|
|
defer cancel()
|
|
|
|
names := make([]string, 0, len(h.checks))
|
|
for name := range h.checks {
|
|
names = append(names, name)
|
|
}
|
|
sort.Strings(names)
|
|
|
|
ready := true
|
|
dependencies := make(map[string]string, len(names))
|
|
for _, name := range names {
|
|
check := h.checks[name]
|
|
if check == nil || check(ctx) != nil {
|
|
dependencies[name] = "unavailable"
|
|
ready = false
|
|
continue
|
|
}
|
|
dependencies[name] = "ok"
|
|
}
|
|
|
|
statusCode := http.StatusOK
|
|
status := "ok"
|
|
if !ready {
|
|
statusCode = http.StatusServiceUnavailable
|
|
status = "unavailable"
|
|
}
|
|
c.JSON(statusCode, gin.H{
|
|
"status": status,
|
|
"service": "hfb-api",
|
|
"started_at": h.startedAt.Format(time.RFC3339),
|
|
"dependencies": dependencies,
|
|
})
|
|
}
|