51 lines
1.2 KiB
Go
51 lines
1.2 KiB
Go
package handlers
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"log/slog"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
// HealthHandler provides a health check endpoint that verifies database connectivity.
|
|
type HealthHandler struct {
|
|
dbPool *pgxpool.Pool
|
|
}
|
|
|
|
// NewHealthHandler creates a new HealthHandler with the given database pool.
|
|
func NewHealthHandler(dbPool *pgxpool.Pool) *HealthHandler {
|
|
return &HealthHandler{dbPool: dbPool}
|
|
}
|
|
|
|
// ServeHTTP handles GET /health requests.
|
|
func (h *HealthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
dbConnected := false
|
|
if h.dbPool != nil {
|
|
if err := h.dbPool.Ping(ctx); err == nil {
|
|
dbConnected = true
|
|
} else {
|
|
slog.Warn("health check db ping failed", "error", err)
|
|
}
|
|
}
|
|
|
|
resp := map[string]any{
|
|
"status": "ok",
|
|
"timestamp": time.Now().UTC().Format(time.RFC3339),
|
|
"db_connected": dbConnected,
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
if !dbConnected {
|
|
w.WriteHeader(http.StatusServiceUnavailable)
|
|
}
|
|
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
|
slog.Error("failed to encode health response", "error", err)
|
|
}
|
|
}
|