Files
schemas/health/health.go
T

74 lines
1.7 KiB
Go
Raw Normal View History

package health
import (
"context"
"database/sql"
"encoding/json"
"log/slog"
"net/http"
"time"
)
type Checker struct {
db *sql.DB
logger *slog.Logger
}
func New(db *sql.DB, logger *slog.Logger) *Checker {
return &Checker{
db: db,
logger: logger,
}
}
type HealthStatus struct {
Status string `json:"status"`
Checks map[string]string `json:"checks,omitempty"`
}
// LivenessHandler checks if the application is running
// This is a simple check that always returns OK if the handler is reached
func (h *Checker) LivenessHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
_ = json.NewEncoder(w).Encode(HealthStatus{
Status: "UP",
})
}
// ReadinessHandler checks if the application is ready to accept traffic
// This checks database connectivity and other critical dependencies
func (h *Checker) ReadinessHandler(w http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
defer cancel()
checks := make(map[string]string)
allHealthy := true
// Check database connectivity
if err := h.db.PingContext(ctx); err != nil {
h.logger.With("error", err).Warn("database health check failed")
checks["database"] = "DOWN"
allHealthy = false
} else {
checks["database"] = "UP"
}
status := HealthStatus{
Status: "UP",
Checks: checks,
}
if !allHealthy {
status.Status = "DOWN"
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusServiceUnavailable)
_ = json.NewEncoder(w).Encode(status)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
_ = json.NewEncoder(w).Encode(status)
}